@voyantjs/cloud-sdk 0.4.0 → 0.6.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/README.md +91 -1
- package/dist/env.d.ts +41 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +55 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/search.d.ts +66 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +72 -0
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ Public TypeScript client for Voyant Cloud APIs.
|
|
|
14
14
|
long-running crawls and keep-alive Puppeteer sessions)
|
|
15
15
|
- video (manage uploads, playback, captions, watermarks, signed playback
|
|
16
16
|
tokens; create videos from a public URL)
|
|
17
|
+
- search (`createSearchClientConfig` returns a Typesense client config pointed
|
|
18
|
+
at the Voyant search proxy)
|
|
17
19
|
|
|
18
20
|
## Install
|
|
19
21
|
|
|
@@ -34,6 +36,49 @@ const vaults = await client.vault.listVaults();
|
|
|
34
36
|
const phoneNumbers = await client.sms.listPhoneNumbers();
|
|
35
37
|
```
|
|
36
38
|
|
|
39
|
+
### From env / worker bindings
|
|
40
|
+
|
|
41
|
+
`getVoyantCloudClient` reads `VOYANT_CLOUD_API_KEY` (and optionally
|
|
42
|
+
`VOYANT_CLOUD_API_URL`, `VOYANT_CLOUD_USER_AGENT`) from a bindings/env
|
|
43
|
+
object and constructs a client. It throws a typed `VoyantCloudConfigError`
|
|
44
|
+
when the key is missing.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { getVoyantCloudClient, type VoyantCloudEnv } from "@voyantjs/cloud-sdk";
|
|
48
|
+
|
|
49
|
+
// Cloudflare Worker
|
|
50
|
+
export default {
|
|
51
|
+
async fetch(_req: Request, env: VoyantCloudEnv) {
|
|
52
|
+
const cloud = getVoyantCloudClient(env);
|
|
53
|
+
return Response.json(await cloud.vault.listVaults());
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { getVoyantCloudClient } from "@voyantjs/cloud-sdk";
|
|
60
|
+
|
|
61
|
+
// Node
|
|
62
|
+
const cloud = getVoyantCloudClient(process.env);
|
|
63
|
+
const vaults = await cloud.vault.listVaults();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`overrides` win over env values, except an empty-string override is
|
|
67
|
+
treated as missing so it can't silently clobber a valid env value:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { getVoyantCloudClient, type VoyantCloudEnv } from "@voyantjs/cloud-sdk";
|
|
71
|
+
|
|
72
|
+
declare const env: VoyantCloudEnv;
|
|
73
|
+
declare const tenantKey: string;
|
|
74
|
+
|
|
75
|
+
const cloud = getVoyantCloudClient(env, { apiKey: tenantKey });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For paths that legitimately operate without cloud (local dev tooling that
|
|
79
|
+
doesn't send mail, etc.), use `tryGetVoyantCloudClient` — it returns
|
|
80
|
+
`null` instead of throwing when the key is unset.
|
|
81
|
+
|
|
37
82
|
## Shape
|
|
38
83
|
|
|
39
84
|
Root groups:
|
|
@@ -44,6 +89,7 @@ Root groups:
|
|
|
44
89
|
- `email`
|
|
45
90
|
- `browser`
|
|
46
91
|
- `video`
|
|
92
|
+
- `search` (standalone `createSearchClientConfig` export, not on the client)
|
|
47
93
|
|
|
48
94
|
The `vault` group covers list-vaults, list-secrets, and get-secret routes.
|
|
49
95
|
|
|
@@ -83,6 +129,49 @@ await client.browser.sessions.runCommands(session.id, {
|
|
|
83
129
|
await client.browser.sessions.close(session.id);
|
|
84
130
|
```
|
|
85
131
|
|
|
132
|
+
The `search` surface is a config helper, not a wrapped client. Voyant's
|
|
133
|
+
search proxy speaks the Typesense HTTP protocol, so `createSearchClientConfig`
|
|
134
|
+
hands back a config you pass straight to the official `typesense` package:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { Client } from "typesense";
|
|
138
|
+
import { createSearchClientConfig } from "@voyantjs/cloud-sdk";
|
|
139
|
+
|
|
140
|
+
const search = new Client(
|
|
141
|
+
createSearchClientConfig({
|
|
142
|
+
apiKey: process.env.VOYANT_API_KEY!,
|
|
143
|
+
organizationSlug: "acme",
|
|
144
|
+
projectName: "catalog",
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
await search.collections().create({
|
|
149
|
+
name: "products",
|
|
150
|
+
fields: [
|
|
151
|
+
{ name: "name", type: "string" },
|
|
152
|
+
{ name: "tags", type: "string[]", facet: true },
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await search
|
|
157
|
+
.collections("products")
|
|
158
|
+
.documents()
|
|
159
|
+
.import([{ id: "1", name: "Sneakers", tags: ["shoes"] }], {
|
|
160
|
+
action: "upsert",
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const hits = await search
|
|
164
|
+
.collections("products")
|
|
165
|
+
.documents()
|
|
166
|
+
.search({ q: "sneak", query_by: "name,tags" });
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`apiKey` is your Voyant API token (`search:read` for queries,
|
|
170
|
+
`search:write` for writes). The proxy auths with `Authorization: Bearer ...`,
|
|
171
|
+
substitutes the project's scoped Typesense key downstream, and rewrites
|
|
172
|
+
collection names so isolation prefixes never leak into your code. `typesense`
|
|
173
|
+
is a peer requirement — install it alongside the SDK if you use search.
|
|
174
|
+
|
|
86
175
|
The `video` group covers the Voyant video service: `videos.{list, get,
|
|
87
176
|
createUpload, createFromUrl, update, delete, enableDownload, mintToken}`,
|
|
88
177
|
captions under `videos.captions.{list, upload, generate, delete}`, and
|
|
@@ -127,6 +216,7 @@ Useful exported types include:
|
|
|
127
216
|
`GenerateVideoCaptionInput`, `CreateVideoWatermarkInput`,
|
|
128
217
|
`VideoStatus`, `VideoCaptionStatus`, `VideoDownloadStatus`,
|
|
129
218
|
`VideoWatermarkPosition`
|
|
219
|
+
- `SearchClientConfig`, `SearchClientConfigOptions`
|
|
130
220
|
- `PhoneNumberStatus`, `SmsMessageStatus`, `VerificationChannel`,
|
|
131
221
|
`VerificationAttemptStatus`, `EmailMessageStatus`,
|
|
132
222
|
`BrowserSessionStatus`, `BrowserJobStatus`
|
|
@@ -141,7 +231,7 @@ Useful exported types include:
|
|
|
141
231
|
`verification:read`, `emails:read`, `emails:send`, `browser:render`,
|
|
142
232
|
`browser:scrape`, `browser:extract`, `browser:crawl`, `browser:sessions`,
|
|
143
233
|
`video:read`, `video:upload`, `video:delete`, `video:captions:write`,
|
|
144
|
-
`video:watermarks:write`);
|
|
234
|
+
`video:watermarks:write`, `search:read`, `search:write`);
|
|
145
235
|
requests fail with `403` if the token does not include the required scope
|
|
146
236
|
|
|
147
237
|
For repo-level context, see [../../docs/cloud.md](../../docs/cloud.md).
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { VoyantCloudClient } from "./client.js";
|
|
2
|
+
import type { VoyantCloudClientOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Bindings/env shape recognized by {@link getVoyantCloudClient} and
|
|
5
|
+
* {@link tryGetVoyantCloudClient}.
|
|
6
|
+
*
|
|
7
|
+
* Designed to accept a Cloudflare Worker `env` object, Node `process.env`,
|
|
8
|
+
* or any other key/value bag of strings. Empty-string values are treated
|
|
9
|
+
* the same as `undefined` — common when `.env` files leave a key blank.
|
|
10
|
+
*/
|
|
11
|
+
export interface VoyantCloudEnv {
|
|
12
|
+
VOYANT_CLOUD_API_KEY?: string;
|
|
13
|
+
VOYANT_CLOUD_API_URL?: string;
|
|
14
|
+
VOYANT_CLOUD_USER_AGENT?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Thrown when {@link getVoyantCloudClient} cannot construct a client because
|
|
18
|
+
* `VOYANT_CLOUD_API_KEY` is missing and no override was supplied.
|
|
19
|
+
*/
|
|
20
|
+
export declare class VoyantCloudConfigError extends Error {
|
|
21
|
+
constructor(message: string);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Construct a {@link VoyantCloudClient} from a runtime bindings object
|
|
25
|
+
* (Cloudflare Worker `env`, Node `process.env`, etc.).
|
|
26
|
+
*
|
|
27
|
+
* `overrides` take precedence over env values, except an empty-string
|
|
28
|
+
* override is treated as missing so it can't silently clobber a valid env
|
|
29
|
+
* value.
|
|
30
|
+
*
|
|
31
|
+
* Throws {@link VoyantCloudConfigError} when no API key can be resolved
|
|
32
|
+
* from either source.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getVoyantCloudClient(env: VoyantCloudEnv, overrides?: Partial<VoyantCloudClientOptions>): VoyantCloudClient;
|
|
35
|
+
/**
|
|
36
|
+
* Like {@link getVoyantCloudClient}, but returns `null` when the API key
|
|
37
|
+
* is unset instead of throwing. Use from edges that legitimately operate
|
|
38
|
+
* without cloud (e.g. local dev tooling that doesn't send mail).
|
|
39
|
+
*/
|
|
40
|
+
export declare function tryGetVoyantCloudClient(env: VoyantCloudEnv, overrides?: Partial<VoyantCloudClientOptions>): VoyantCloudClient | null;
|
|
41
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EACnB,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAChD,iBAAiB,CAmBnB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,cAAc,EACnB,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAChD,iBAAiB,GAAG,IAAI,CAS1B"}
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createVoyantCloudClient } from "./client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when {@link getVoyantCloudClient} cannot construct a client because
|
|
4
|
+
* `VOYANT_CLOUD_API_KEY` is missing and no override was supplied.
|
|
5
|
+
*/
|
|
6
|
+
export class VoyantCloudConfigError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "VoyantCloudConfigError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Construct a {@link VoyantCloudClient} from a runtime bindings object
|
|
14
|
+
* (Cloudflare Worker `env`, Node `process.env`, etc.).
|
|
15
|
+
*
|
|
16
|
+
* `overrides` take precedence over env values, except an empty-string
|
|
17
|
+
* override is treated as missing so it can't silently clobber a valid env
|
|
18
|
+
* value.
|
|
19
|
+
*
|
|
20
|
+
* Throws {@link VoyantCloudConfigError} when no API key can be resolved
|
|
21
|
+
* from either source.
|
|
22
|
+
*/
|
|
23
|
+
export function getVoyantCloudClient(env, overrides = {}) {
|
|
24
|
+
const apiKey = nonEmpty(overrides.apiKey) ?? nonEmpty(env.VOYANT_CLOUD_API_KEY);
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
throw new VoyantCloudConfigError("VOYANT_CLOUD_API_KEY is not set. Set the env variable or pass `apiKey` in overrides.");
|
|
27
|
+
}
|
|
28
|
+
const baseUrl = nonEmpty(env.VOYANT_CLOUD_API_URL);
|
|
29
|
+
const userAgent = nonEmpty(env.VOYANT_CLOUD_USER_AGENT);
|
|
30
|
+
return createVoyantCloudClient({
|
|
31
|
+
...(baseUrl ? { baseUrl } : {}),
|
|
32
|
+
...(userAgent ? { userAgent } : {}),
|
|
33
|
+
...overrides,
|
|
34
|
+
apiKey,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Like {@link getVoyantCloudClient}, but returns `null` when the API key
|
|
39
|
+
* is unset instead of throwing. Use from edges that legitimately operate
|
|
40
|
+
* without cloud (e.g. local dev tooling that doesn't send mail).
|
|
41
|
+
*/
|
|
42
|
+
export function tryGetVoyantCloudClient(env, overrides = {}) {
|
|
43
|
+
try {
|
|
44
|
+
return getVoyantCloudClient(env, overrides);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error instanceof VoyantCloudConfigError) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function nonEmpty(value) {
|
|
54
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
55
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export { createVoyantCloudClient, VoyantCloudClient } from "./client.js";
|
|
2
|
+
export { getVoyantCloudClient, tryGetVoyantCloudClient, VoyantCloudConfigError, } from "./env.js";
|
|
3
|
+
export type { VoyantCloudEnv } from "./env.js";
|
|
4
|
+
export { createSearchClientConfig } from "./search.js";
|
|
5
|
+
export type { SearchClientConfig, SearchClientConfigOptions, } from "./search.js";
|
|
2
6
|
export type { BrowserCommand, BrowserCommandResult, BrowserCookie, BrowserCrawlSummary, BrowserGoToOptions, BrowserJobKind, BrowserJobStatus, BrowserJsonInput, BrowserLink, BrowserPdfInput, BrowserPdfOptions, BrowserRenderInput, BrowserSameSite, BrowserScrapeElement, BrowserScrapeInput, BrowserScrapeResult, BrowserScreenshotInput, BrowserScreenshotOptions, BrowserSessionStatus, BrowserSessionSummary, BrowserSnapshotResult, BrowserViewport, BrowserWaitForSelector, BrowserWaitUntil, CheckVerificationInput, CreateVideoFromUrlInput, CreateVideoUploadInput, CreateVideoWatermarkInput, EmailMessageStatus, EmailMessageSummary, GenerateVideoCaptionInput, MintVideoSignedTokenInput, OpenBrowserSessionInput, PhoneNumberCapabilities, PhoneNumberStatus, PhoneNumberSummary, RunBrowserCommandsInput, RunBrowserCommandsResult, SendEmailAttachment, SendEmailInput, SendSmsInput, SmsMessageStatus, SmsMessageSummary, StartBrowserCrawlInput, StartBrowserCrawlResult, StartVerificationInput, UpdateVideoInput, UploadVideoCaptionInput, VaultSecretSummary, VaultSecretValue, VaultSummary, VerificationAttemptStatus, VerificationAttemptSummary, VerificationChannel, VerificationCheckResult, VideoCaptionStatus, VideoCaptionSummary, VideoDownloadStatus, VideoSignedToken, VideoStatus, VideoSummary, VideoUploadTicket, VideoWatermarkPosition, VideoWatermarkProfileSummary, VoyantCloudClientOptions, } from "./types.js";
|
|
3
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzE,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EACV,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration helper for the Voyant search surface.
|
|
3
|
+
*
|
|
4
|
+
* Voyant's search-api is a thin proxy in front of Typesense. It auths
|
|
5
|
+
* incoming requests against a Voyant API token, picks the right scoped
|
|
6
|
+
* Typesense key (read or write) server-side, and rewrites collection
|
|
7
|
+
* names so customers never see our internal isolation prefix.
|
|
8
|
+
*
|
|
9
|
+
* The wire protocol is pure Typesense, so we don't ship a hand-rolled
|
|
10
|
+
* SDK surface for it. Instead, this helper produces a config object
|
|
11
|
+
* that you pass directly to the official `typesense` client:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { Client } from "typesense";
|
|
15
|
+
* import { createSearchClientConfig } from "@voyantjs/cloud-sdk";
|
|
16
|
+
*
|
|
17
|
+
* const search = new Client(createSearchClientConfig({
|
|
18
|
+
* apiKey: process.env.VOYANT_API_TOKEN!,
|
|
19
|
+
* organizationSlug: "acme",
|
|
20
|
+
* projectName: "catalog",
|
|
21
|
+
* }));
|
|
22
|
+
*
|
|
23
|
+
* await search.collections().create({
|
|
24
|
+
* name: "products",
|
|
25
|
+
* fields: [{ name: "name", type: "string" }],
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* `apiKey` here is your Voyant API token — it is sent as
|
|
30
|
+
* `Authorization: Bearer ...`. The proxy strips Typesense's own
|
|
31
|
+
* `X-TYPESENSE-API-KEY` header from inbound requests and injects the
|
|
32
|
+
* project's scoped key downstream.
|
|
33
|
+
*/
|
|
34
|
+
export interface SearchClientConfigOptions {
|
|
35
|
+
/** Voyant API token with `search:read` (queries) or `search:write` (writes) scope. */
|
|
36
|
+
apiKey: string;
|
|
37
|
+
/** Organization slug — the first path segment in the search URL. */
|
|
38
|
+
organizationSlug: string;
|
|
39
|
+
/** Search project name — the second path segment in the search URL. */
|
|
40
|
+
projectName: string;
|
|
41
|
+
/** Override the default `search.voyantjs.com` host (e.g. for local dev). */
|
|
42
|
+
host?: string;
|
|
43
|
+
/** Override the default port. */
|
|
44
|
+
port?: number;
|
|
45
|
+
/** Override the default `https` protocol. */
|
|
46
|
+
protocol?: string;
|
|
47
|
+
/** Additional headers to merge with `Authorization`. */
|
|
48
|
+
additionalHeaders?: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
export interface SearchClientConfig {
|
|
51
|
+
apiKey: string;
|
|
52
|
+
nodes: Array<{
|
|
53
|
+
host: string;
|
|
54
|
+
port: number;
|
|
55
|
+
protocol: string;
|
|
56
|
+
path: string;
|
|
57
|
+
}>;
|
|
58
|
+
additionalHeaders: Record<string, string>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build a Typesense client configuration that targets the Voyant
|
|
62
|
+
* search proxy. Pass the returned object straight to
|
|
63
|
+
* `new Typesense.Client(...)`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function createSearchClientConfig(options: SearchClientConfigOptions): SearchClientConfig;
|
|
66
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAMH,MAAM,WAAW,yBAAyB;IACxC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CA0CpB"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration helper for the Voyant search surface.
|
|
3
|
+
*
|
|
4
|
+
* Voyant's search-api is a thin proxy in front of Typesense. It auths
|
|
5
|
+
* incoming requests against a Voyant API token, picks the right scoped
|
|
6
|
+
* Typesense key (read or write) server-side, and rewrites collection
|
|
7
|
+
* names so customers never see our internal isolation prefix.
|
|
8
|
+
*
|
|
9
|
+
* The wire protocol is pure Typesense, so we don't ship a hand-rolled
|
|
10
|
+
* SDK surface for it. Instead, this helper produces a config object
|
|
11
|
+
* that you pass directly to the official `typesense` client:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { Client } from "typesense";
|
|
15
|
+
* import { createSearchClientConfig } from "@voyantjs/cloud-sdk";
|
|
16
|
+
*
|
|
17
|
+
* const search = new Client(createSearchClientConfig({
|
|
18
|
+
* apiKey: process.env.VOYANT_API_TOKEN!,
|
|
19
|
+
* organizationSlug: "acme",
|
|
20
|
+
* projectName: "catalog",
|
|
21
|
+
* }));
|
|
22
|
+
*
|
|
23
|
+
* await search.collections().create({
|
|
24
|
+
* name: "products",
|
|
25
|
+
* fields: [{ name: "name", type: "string" }],
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* `apiKey` here is your Voyant API token — it is sent as
|
|
30
|
+
* `Authorization: Bearer ...`. The proxy strips Typesense's own
|
|
31
|
+
* `X-TYPESENSE-API-KEY` header from inbound requests and injects the
|
|
32
|
+
* project's scoped key downstream.
|
|
33
|
+
*/
|
|
34
|
+
const DEFAULT_SEARCH_HOST = "search.voyantjs.com";
|
|
35
|
+
const DEFAULT_SEARCH_PORT = 443;
|
|
36
|
+
const DEFAULT_SEARCH_PROTOCOL = "https";
|
|
37
|
+
/**
|
|
38
|
+
* Build a Typesense client configuration that targets the Voyant
|
|
39
|
+
* search proxy. Pass the returned object straight to
|
|
40
|
+
* `new Typesense.Client(...)`.
|
|
41
|
+
*/
|
|
42
|
+
export function createSearchClientConfig(options) {
|
|
43
|
+
const { apiKey, organizationSlug, projectName, host = DEFAULT_SEARCH_HOST, port = DEFAULT_SEARCH_PORT, protocol = DEFAULT_SEARCH_PROTOCOL, additionalHeaders, } = options;
|
|
44
|
+
if (!apiKey) {
|
|
45
|
+
throw new Error("createSearchClientConfig: `apiKey` is required.");
|
|
46
|
+
}
|
|
47
|
+
if (!organizationSlug) {
|
|
48
|
+
throw new Error("createSearchClientConfig: `organizationSlug` is required.");
|
|
49
|
+
}
|
|
50
|
+
if (!projectName) {
|
|
51
|
+
throw new Error("createSearchClientConfig: `projectName` is required.");
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
// typesense-js requires `apiKey`. The proxy strips the
|
|
55
|
+
// X-TYPESENSE-API-KEY header it adds and uses our bearer token
|
|
56
|
+
// instead, so this value is ignored downstream — but it must be
|
|
57
|
+
// a non-empty string for the client to construct.
|
|
58
|
+
apiKey: "voyant-bearer",
|
|
59
|
+
nodes: [
|
|
60
|
+
{
|
|
61
|
+
host,
|
|
62
|
+
port,
|
|
63
|
+
protocol,
|
|
64
|
+
path: `/${organizationSlug}/${projectName}`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
additionalHeaders: {
|
|
68
|
+
...additionalHeaders,
|
|
69
|
+
Authorization: `Bearer ${apiKey}`,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/cloud-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Public TypeScript SDK for Voyant Cloud APIs.",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -37,9 +37,18 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@voyant-sdk/sdk-core": "0.2.0"
|
|
39
39
|
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"typesense": "^2.0.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"typesense": {
|
|
45
|
+
"optional": true
|
|
46
|
+
}
|
|
47
|
+
},
|
|
40
48
|
"devDependencies": {
|
|
41
49
|
"eslint": "^9.39.1",
|
|
42
50
|
"typescript": "5.9.2",
|
|
51
|
+
"typesense": "^2.0.0",
|
|
43
52
|
"@voyant-sdk/eslint-config": "0.0.0",
|
|
44
53
|
"@voyant-sdk/typescript-config": "0.0.0"
|
|
45
54
|
},
|