@possibl/rcrt-sdk 0.1.2 → 0.5.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/CHANGELOG.md +99 -62
- package/LICENSE +21 -0
- package/README.md +35 -21
- package/dist/auth.d.ts +45 -0
- package/dist/auth.d.ts.map +1 -0
- package/{src/auth.ts → dist/auth.js} +9 -24
- package/dist/auth.js.map +1 -0
- package/dist/authn.d.ts +114 -0
- package/dist/authn.d.ts.map +1 -0
- package/dist/authn.js +107 -0
- package/dist/authn.js.map +1 -0
- package/dist/breadcrumbs.d.ts +43 -0
- package/dist/breadcrumbs.d.ts.map +1 -0
- package/dist/breadcrumbs.js +122 -0
- package/dist/breadcrumbs.js.map +1 -0
- package/dist/cards.d.ts +28 -0
- package/dist/cards.d.ts.map +1 -0
- package/dist/cards.js +105 -0
- package/dist/cards.js.map +1 -0
- package/dist/chat.d.ts +103 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +105 -0
- package/dist/chat.js.map +1 -0
- package/dist/client.d.ts +85 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +133 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +76 -0
- package/dist/errors.js.map +1 -0
- package/dist/files.d.ts +41 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +64 -0
- package/dist/files.js.map +1 -0
- package/dist/generated/conformance.d.ts +48 -0
- package/dist/generated/conformance.d.ts.map +1 -0
- package/dist/generated/conformance.js +24 -0
- package/dist/generated/conformance.js.map +1 -0
- package/dist/generated/index.d.ts +34 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/index.js +34 -0
- package/dist/generated/index.js.map +1 -0
- package/dist/generated/openapi.d.ts +3900 -0
- package/dist/generated/openapi.d.ts.map +1 -0
- package/dist/generated/openapi.js +6 -0
- package/dist/generated/openapi.js.map +1 -0
- package/dist/grants.d.ts +41 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +50 -0
- package/dist/grants.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/fetch.d.ts +47 -0
- package/dist/internal/fetch.d.ts.map +1 -0
- package/dist/internal/fetch.js +108 -0
- package/dist/internal/fetch.js.map +1 -0
- package/dist/internal/sse.d.ts +82 -0
- package/dist/internal/sse.d.ts.map +1 -0
- package/dist/internal/sse.js +161 -0
- package/dist/internal/sse.js.map +1 -0
- package/dist/marketplace.d.ts +98 -0
- package/dist/marketplace.d.ts.map +1 -0
- package/dist/marketplace.js +74 -0
- package/dist/marketplace.js.map +1 -0
- package/dist/members.d.ts +60 -0
- package/dist/members.d.ts.map +1 -0
- package/dist/members.js +74 -0
- package/dist/members.js.map +1 -0
- package/dist/org.d.ts +85 -0
- package/dist/org.d.ts.map +1 -0
- package/dist/org.js +70 -0
- package/dist/org.js.map +1 -0
- package/dist/types/breadcrumb.d.ts +70 -0
- package/dist/types/breadcrumb.d.ts.map +1 -0
- package/dist/types/breadcrumb.js +8 -0
- package/dist/types/breadcrumb.js.map +1 -0
- package/dist/types/card.d.ts +251 -0
- package/dist/types/card.d.ts.map +1 -0
- package/dist/types/card.js +10 -0
- package/dist/types/card.js.map +1 -0
- package/dist/types/engine.d.ts +69 -0
- package/dist/types/engine.d.ts.map +1 -0
- package/dist/types/engine.js +53 -0
- package/dist/types/engine.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +35 -6
- package/src/authn.ts +0 -159
- package/src/breadcrumbs.ts +0 -111
- package/src/capabilities.ts +0 -93
- package/src/cards.ts +0 -109
- package/src/chat.ts +0 -83
- package/src/client.ts +0 -97
- package/src/errors.ts +0 -101
- package/src/files.ts +0 -135
- package/src/grants.ts +0 -99
- package/src/index.ts +0 -103
- package/src/internal/fetch.ts +0 -133
- package/src/internal/sse.ts +0 -236
- package/src/sessions.ts +0 -110
- package/src/types/breadcrumb.ts +0 -77
- package/src/types/card.ts +0 -298
- package/src/types/index.ts +0 -2
package/dist/client.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RcrtClient — the single entry-point to the SDK.
|
|
3
|
+
*
|
|
4
|
+
* import { RcrtClient, staticTokenProvider } from '@possibl/rcrt-sdk';
|
|
5
|
+
*
|
|
6
|
+
* const rcrt = new RcrtClient({
|
|
7
|
+
* apiUrl: 'https://rcrt-api-gateway-<hash>.run.app',
|
|
8
|
+
* tokenProvider: firebaseTokenProvider(auth),
|
|
9
|
+
* });
|
|
10
|
+
*
|
|
11
|
+
* rcrt.setTenantId(workspaceId);
|
|
12
|
+
* const me = await rcrt.auth.me();
|
|
13
|
+
* const stream = rcrt.chat.sessionStream(sessionId, { ...handlers });
|
|
14
|
+
*
|
|
15
|
+
* Every module on the client shares the same fetch context — one
|
|
16
|
+
* bearer refresh path, one tenant header, one error envelope.
|
|
17
|
+
*
|
|
18
|
+
* For fleet fan-out across workspaces, prefer `forTenant()` over
|
|
19
|
+
* mutating one client with `setTenantId()`:
|
|
20
|
+
*
|
|
21
|
+
* await Promise.all(workspaces.map((ws) =>
|
|
22
|
+
* rcrt.forTenant(ws.id).breadcrumbs.queryByTags(['interpret:alert']),
|
|
23
|
+
* ));
|
|
24
|
+
*/
|
|
25
|
+
import { request } from './internal/fetch.js';
|
|
26
|
+
import { BreadcrumbsModule } from './breadcrumbs.js';
|
|
27
|
+
import { ChatModule } from './chat.js';
|
|
28
|
+
import { CardsModule } from './cards.js';
|
|
29
|
+
import { GrantsModule } from './grants.js';
|
|
30
|
+
import { IdentityModule } from './authn.js';
|
|
31
|
+
import { MarketplaceModule } from './marketplace.js';
|
|
32
|
+
import { OrgModule } from './org.js';
|
|
33
|
+
import { FilesModule } from './files.js';
|
|
34
|
+
import { MembersModule } from './members.js';
|
|
35
|
+
import { SdkError } from './errors.js';
|
|
36
|
+
export class RcrtClient {
|
|
37
|
+
ctx;
|
|
38
|
+
config;
|
|
39
|
+
tenantClients = new Map();
|
|
40
|
+
auth;
|
|
41
|
+
breadcrumbs;
|
|
42
|
+
chat;
|
|
43
|
+
cards;
|
|
44
|
+
grants;
|
|
45
|
+
marketplace;
|
|
46
|
+
org;
|
|
47
|
+
files;
|
|
48
|
+
members;
|
|
49
|
+
constructor(config) {
|
|
50
|
+
if (!config.apiUrl) {
|
|
51
|
+
throw new SdkError('MISSING_API_URL', 'RcrtClient requires `apiUrl`');
|
|
52
|
+
}
|
|
53
|
+
if (!config.tokenProvider) {
|
|
54
|
+
throw new SdkError('MISSING_TOKEN_PROVIDER', 'RcrtClient requires a `tokenProvider`');
|
|
55
|
+
}
|
|
56
|
+
this.config = config;
|
|
57
|
+
const ctxInternal = {
|
|
58
|
+
apiUrl: config.apiUrl,
|
|
59
|
+
tenantId: config.tenantId ?? null,
|
|
60
|
+
tokenProvider: config.tokenProvider,
|
|
61
|
+
fetchImpl: config.fetchImpl ?? undefined,
|
|
62
|
+
};
|
|
63
|
+
// Use a Proxy so module instances can read the current `tenantId`
|
|
64
|
+
// at request time without us having to rebuild them on every
|
|
65
|
+
// `setTenantId` call.
|
|
66
|
+
this.ctx = new Proxy({}, {
|
|
67
|
+
get: (_target, prop) => ctxInternal[prop],
|
|
68
|
+
set: (_target, prop, value) => {
|
|
69
|
+
ctxInternal[prop] = value;
|
|
70
|
+
return true;
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
this.auth = new IdentityModule(this.ctx);
|
|
74
|
+
this.breadcrumbs = new BreadcrumbsModule(this.ctx);
|
|
75
|
+
this.chat = new ChatModule(this.ctx);
|
|
76
|
+
this.cards = new CardsModule(this.ctx);
|
|
77
|
+
this.grants = new GrantsModule(this.ctx);
|
|
78
|
+
this.marketplace = new MarketplaceModule(this.ctx);
|
|
79
|
+
this.org = new OrgModule(this.ctx);
|
|
80
|
+
this.files = new FilesModule(this.ctx);
|
|
81
|
+
this.members = new MembersModule(this.ctx);
|
|
82
|
+
}
|
|
83
|
+
/** Switch workspaces. Subsequent requests carry the new `X-Tenant-ID`. */
|
|
84
|
+
setTenantId(tenantId) {
|
|
85
|
+
this.ctx.tenantId = tenantId;
|
|
86
|
+
}
|
|
87
|
+
/** Read the workspace id this client is currently scoped to. */
|
|
88
|
+
getTenantId() {
|
|
89
|
+
return this.ctx.tenantId;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A client permanently bound to `tenantId` — same apiUrl, token
|
|
93
|
+
* provider and fetch impl, its own tenant header. Instances are
|
|
94
|
+
* cached per tenant and are just thin header wrappers, so parallel
|
|
95
|
+
* fleet fan-out is safe and cheap (no shared-client races, no
|
|
96
|
+
* serialisation through `setTenantId`).
|
|
97
|
+
*/
|
|
98
|
+
forTenant(tenantId) {
|
|
99
|
+
if (!tenantId) {
|
|
100
|
+
throw new SdkError('MISSING_TENANT_ID', 'forTenant requires a tenant id');
|
|
101
|
+
}
|
|
102
|
+
let c = this.tenantClients.get(tenantId);
|
|
103
|
+
if (!c) {
|
|
104
|
+
const cfg = {
|
|
105
|
+
apiUrl: this.config.apiUrl,
|
|
106
|
+
tokenProvider: this.config.tokenProvider,
|
|
107
|
+
tenantId,
|
|
108
|
+
};
|
|
109
|
+
if (this.config.fetchImpl)
|
|
110
|
+
cfg.fetchImpl = this.config.fetchImpl;
|
|
111
|
+
c = new RcrtClient(cfg);
|
|
112
|
+
this.tenantClients.set(tenantId, c);
|
|
113
|
+
}
|
|
114
|
+
return c;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Typed escape hatch — call any gateway endpoint with the client's
|
|
118
|
+
* auth + tenant + retry handling. Apps are never blocked on an SDK
|
|
119
|
+
* release for a new endpoint:
|
|
120
|
+
*
|
|
121
|
+
* const res = await rcrt.request<{ items: Item[] }>('/v1/some/new/endpoint', {
|
|
122
|
+
* method: 'POST',
|
|
123
|
+
* body: { hello: 'world' }, // plain object — the SDK serialises
|
|
124
|
+
* });
|
|
125
|
+
*
|
|
126
|
+
* `options.body` is JSON-serialised; use `options.rawBody` for
|
|
127
|
+
* FormData / binary payloads; `options.query` appends search params.
|
|
128
|
+
*/
|
|
129
|
+
async request(path, options = {}) {
|
|
130
|
+
return request(this.ctx, path, options);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error taxonomy.
|
|
3
|
+
*
|
|
4
|
+
* The RCRT backend is mid-migration from a flat `{"error": "string"}`
|
|
5
|
+
* envelope to a typed `{"error": {"code", "message", "details"}}`
|
|
6
|
+
* shape. This module normalises both into one `ApiError` that app
|
|
7
|
+
* code can switch on.
|
|
8
|
+
*
|
|
9
|
+
* See `packages/docs/guides/07-error-handling.md`.
|
|
10
|
+
*/
|
|
11
|
+
/** Stable machine-readable error codes recognised by the SDK. */
|
|
12
|
+
export type KnownErrorCode = 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'CONFLICT' | 'INVALID_REQUEST' | 'TOO_MANY_REQUESTS' | 'INTERNAL' | 'SERVICE_UNAVAILABLE' | 'UNKNOWN';
|
|
13
|
+
export interface ApiErrorDetail {
|
|
14
|
+
/** Machine-readable code if the server sent one. Otherwise derived from status. */
|
|
15
|
+
code: KnownErrorCode | string;
|
|
16
|
+
message: string;
|
|
17
|
+
details?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export declare class ApiError extends Error {
|
|
20
|
+
readonly status: number;
|
|
21
|
+
readonly detail: ApiErrorDetail;
|
|
22
|
+
readonly rawBody: string | undefined;
|
|
23
|
+
constructor(status: number, detail: ApiErrorDetail, rawBody?: string);
|
|
24
|
+
static fromResponse(status: number, rawBody: string): ApiError;
|
|
25
|
+
}
|
|
26
|
+
/** Errors thrown by the SDK before we even reach the server. */
|
|
27
|
+
export declare class SdkError extends Error {
|
|
28
|
+
readonly code: string;
|
|
29
|
+
constructor(code: string, message: string);
|
|
30
|
+
}
|
|
31
|
+
export declare function parseErrorBody(status: number, rawBody: string): ApiErrorDetail;
|
|
32
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,iEAAiE;AACjE,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,WAAW,GACX,WAAW,GACX,UAAU,GACV,iBAAiB,GACjB,mBAAmB,GACnB,UAAU,GACV,qBAAqB,GACrB,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,mFAAmF;IACnF,IAAI,EAAE,cAAc,GAAG,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,MAAM,EAAE,cAAc,CAAC;IACvC,SAAgB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEhC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM;IAQpE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ;CAG/D;AAED,gEAAgE;AAChE,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAeD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CA4B9E"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error taxonomy.
|
|
3
|
+
*
|
|
4
|
+
* The RCRT backend is mid-migration from a flat `{"error": "string"}`
|
|
5
|
+
* envelope to a typed `{"error": {"code", "message", "details"}}`
|
|
6
|
+
* shape. This module normalises both into one `ApiError` that app
|
|
7
|
+
* code can switch on.
|
|
8
|
+
*
|
|
9
|
+
* See `packages/docs/guides/07-error-handling.md`.
|
|
10
|
+
*/
|
|
11
|
+
export class ApiError extends Error {
|
|
12
|
+
status;
|
|
13
|
+
detail;
|
|
14
|
+
rawBody;
|
|
15
|
+
constructor(status, detail, rawBody) {
|
|
16
|
+
super(detail.message);
|
|
17
|
+
this.name = 'ApiError';
|
|
18
|
+
this.status = status;
|
|
19
|
+
this.detail = detail;
|
|
20
|
+
this.rawBody = rawBody;
|
|
21
|
+
}
|
|
22
|
+
static fromResponse(status, rawBody) {
|
|
23
|
+
return new ApiError(status, parseErrorBody(status, rawBody), rawBody);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Errors thrown by the SDK before we even reach the server. */
|
|
27
|
+
export class SdkError extends Error {
|
|
28
|
+
code;
|
|
29
|
+
constructor(code, message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = 'SdkError';
|
|
32
|
+
this.code = code;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// ── Internal helpers ─────────────────────────────────────────────
|
|
36
|
+
const STATUS_TO_CODE = {
|
|
37
|
+
400: 'INVALID_REQUEST',
|
|
38
|
+
401: 'UNAUTHORIZED',
|
|
39
|
+
403: 'FORBIDDEN',
|
|
40
|
+
404: 'NOT_FOUND',
|
|
41
|
+
409: 'CONFLICT',
|
|
42
|
+
429: 'TOO_MANY_REQUESTS',
|
|
43
|
+
500: 'INTERNAL',
|
|
44
|
+
503: 'SERVICE_UNAVAILABLE',
|
|
45
|
+
};
|
|
46
|
+
export function parseErrorBody(status, rawBody) {
|
|
47
|
+
const fallbackCode = STATUS_TO_CODE[status] ?? 'UNKNOWN';
|
|
48
|
+
if (!rawBody.trim()) {
|
|
49
|
+
return { code: fallbackCode, message: `HTTP ${status}` };
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(rawBody);
|
|
53
|
+
if (parsed && typeof parsed === 'object' && 'error' in parsed) {
|
|
54
|
+
const err = parsed.error;
|
|
55
|
+
if (typeof err === 'string') {
|
|
56
|
+
return { code: fallbackCode, message: err };
|
|
57
|
+
}
|
|
58
|
+
if (err && typeof err === 'object') {
|
|
59
|
+
const e = err;
|
|
60
|
+
const detail = {
|
|
61
|
+
code: typeof e.code === 'string' ? e.code : fallbackCode,
|
|
62
|
+
message: typeof e.message === 'string' ? e.message : `HTTP ${status}`,
|
|
63
|
+
};
|
|
64
|
+
if (typeof e.details === 'object' && e.details !== null) {
|
|
65
|
+
detail.details = e.details;
|
|
66
|
+
}
|
|
67
|
+
return detail;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { code: fallbackCode, message: rawBody.slice(0, 200) };
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return { code: fallbackCode, message: rawBody.slice(0, 200) };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files module — `/v1/files` upload + retrieval.
|
|
3
|
+
*
|
|
4
|
+
* Uploads use multipart `FormData`, which is global in browsers,
|
|
5
|
+
* Node 18+ and React Native — no extra dependency needed. Every file
|
|
6
|
+
* lands as a breadcrumb, so downstream reads are normal breadcrumb
|
|
7
|
+
* reads too.
|
|
8
|
+
*/
|
|
9
|
+
import type { FetchContext } from './internal/fetch.js';
|
|
10
|
+
import type { Breadcrumb } from './types/breadcrumb.js';
|
|
11
|
+
export type FileScope = 'tenant' | 'org' | 'user';
|
|
12
|
+
export interface UploadFileOptions {
|
|
13
|
+
/** Who can see the file. Default `'tenant'`. */
|
|
14
|
+
scope?: FileScope;
|
|
15
|
+
/** Override the filename recorded server-side (useful for raw Blobs). */
|
|
16
|
+
filename?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class FilesModule {
|
|
19
|
+
private readonly ctx;
|
|
20
|
+
constructor(ctx: FetchContext);
|
|
21
|
+
/**
|
|
22
|
+
* `POST /v1/files` — multipart upload. Returns the file's breadcrumb.
|
|
23
|
+
*
|
|
24
|
+
* Accepts a `File` (browser), `Blob`, or anything FormData takes.
|
|
25
|
+
*/
|
|
26
|
+
upload(file: Blob, opts?: UploadFileOptions): Promise<Breadcrumb>;
|
|
27
|
+
/** `GET /v1/files` — file breadcrumbs visible at the given scope. */
|
|
28
|
+
list(opts?: {
|
|
29
|
+
scope?: FileScope;
|
|
30
|
+
limit?: number;
|
|
31
|
+
}): Promise<Breadcrumb[]>;
|
|
32
|
+
/** `GET /v1/files/{id}` */
|
|
33
|
+
get(fileId: string): Promise<Breadcrumb>;
|
|
34
|
+
/** `GET /v1/files/{id}/content` — short-lived signed download URL. */
|
|
35
|
+
downloadUrl(fileId: string, expiry?: string): Promise<string>;
|
|
36
|
+
/** `GET /v1/files/{id}/text` — extracted text content (PDFs, docs, …). */
|
|
37
|
+
getText(fileId: string): Promise<string>;
|
|
38
|
+
/** `DELETE /v1/files/{id}` */
|
|
39
|
+
delete(fileId: string): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,YAAY;IAE9C;;;;OAIG;IACG,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAe3E,qEAAqE;IAC/D,IAAI,CAAC,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAOnF,2BAA2B;IACrB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAK9C,sEAAsE;IAChE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAOjE,0EAA0E;IACpE,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C,8BAA8B;IACxB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG5C"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files module — `/v1/files` upload + retrieval.
|
|
3
|
+
*
|
|
4
|
+
* Uploads use multipart `FormData`, which is global in browsers,
|
|
5
|
+
* Node 18+ and React Native — no extra dependency needed. Every file
|
|
6
|
+
* lands as a breadcrumb, so downstream reads are normal breadcrumb
|
|
7
|
+
* reads too.
|
|
8
|
+
*/
|
|
9
|
+
import { request } from './internal/fetch.js';
|
|
10
|
+
export class FilesModule {
|
|
11
|
+
ctx;
|
|
12
|
+
constructor(ctx) {
|
|
13
|
+
this.ctx = ctx;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* `POST /v1/files` — multipart upload. Returns the file's breadcrumb.
|
|
17
|
+
*
|
|
18
|
+
* Accepts a `File` (browser), `Blob`, or anything FormData takes.
|
|
19
|
+
*/
|
|
20
|
+
async upload(file, opts = {}) {
|
|
21
|
+
const form = new FormData();
|
|
22
|
+
if (opts.filename)
|
|
23
|
+
form.append('file', file, opts.filename);
|
|
24
|
+
else
|
|
25
|
+
form.append('file', file);
|
|
26
|
+
form.append('scope', opts.scope ?? 'tenant');
|
|
27
|
+
const res = await request(this.ctx, '/v1/files', {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
rawBody: form,
|
|
30
|
+
});
|
|
31
|
+
return 'breadcrumb' in res && res.breadcrumb
|
|
32
|
+
? res.breadcrumb
|
|
33
|
+
: res;
|
|
34
|
+
}
|
|
35
|
+
/** `GET /v1/files` — file breadcrumbs visible at the given scope. */
|
|
36
|
+
async list(opts = {}) {
|
|
37
|
+
const res = await request(this.ctx, '/v1/files', {
|
|
38
|
+
query: { scope: opts.scope, limit: opts.limit ?? 50 },
|
|
39
|
+
});
|
|
40
|
+
return Array.isArray(res) ? res : (res?.files ?? []);
|
|
41
|
+
}
|
|
42
|
+
/** `GET /v1/files/{id}` */
|
|
43
|
+
async get(fileId) {
|
|
44
|
+
const res = await request(this.ctx, `/v1/files/${fileId}`);
|
|
45
|
+
return res.file ?? res;
|
|
46
|
+
}
|
|
47
|
+
/** `GET /v1/files/{id}/content` — short-lived signed download URL. */
|
|
48
|
+
async downloadUrl(fileId, expiry = '1h') {
|
|
49
|
+
const res = await request(this.ctx, `/v1/files/${fileId}/content`, {
|
|
50
|
+
query: { expiry },
|
|
51
|
+
});
|
|
52
|
+
return res.download_url;
|
|
53
|
+
}
|
|
54
|
+
/** `GET /v1/files/{id}/text` — extracted text content (PDFs, docs, …). */
|
|
55
|
+
async getText(fileId) {
|
|
56
|
+
const res = await request(this.ctx, `/v1/files/${fileId}/text`);
|
|
57
|
+
return res.text;
|
|
58
|
+
}
|
|
59
|
+
/** `DELETE /v1/files/{id}` */
|
|
60
|
+
async delete(fileId) {
|
|
61
|
+
await request(this.ctx, `/v1/files/${fileId}`, { method: 'DELETE' });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAY9C,MAAM,OAAO,WAAW;IACO;IAA7B,YAA6B,GAAiB;QAAjB,QAAG,GAAH,GAAG,CAAc;IAAG,CAAC;IAElD;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,IAAU,EAAE,OAA0B,EAAE;QACnD,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;;YACvD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;QAE7C,MAAM,GAAG,GAAG,MAAM,OAAO,CAA2C,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE;YACzF,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,OAAO,YAAY,IAAK,GAAmC,IAAK,GAAmC,CAAC,UAAU;YAC5G,CAAC,CAAE,GAAkC,CAAC,UAAU;YAChD,CAAC,CAAE,GAAkB,CAAC;IAC1B,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,IAAI,CAAC,OAA8C,EAAE;QACzD,MAAM,GAAG,GAAG,MAAM,OAAO,CAA0C,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE;YACxF,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE;SACtD,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,GAAG,CAAC,MAAc;QACtB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAqC,IAAI,CAAC,GAAG,EAAE,aAAa,MAAM,EAAE,CAAC,CAAC;QAC/F,OAAQ,GAA6B,CAAC,IAAI,IAAK,GAAkB,CAAC;IACpE,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAM,GAAG,IAAI;QAC7C,MAAM,GAAG,GAAG,MAAM,OAAO,CAA2B,IAAI,CAAC,GAAG,EAAE,aAAa,MAAM,UAAU,EAAE;YAC3F,KAAK,EAAE,EAAE,MAAM,EAAE;SAClB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,YAAY,CAAC;IAC1B,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAmB,IAAI,CAAC,GAAG,EAAE,aAAa,MAAM,OAAO,CAAC,CAAC;QAClF,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,8BAA8B;IAC9B,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,MAAM,OAAO,CAAO,IAAI,CAAC,GAAG,EAAE,aAAa,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7E,CAAC;CACF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract conformance guardrail.
|
|
3
|
+
*
|
|
4
|
+
* Asserts at compile time that the hand-written domain types in
|
|
5
|
+
* `@possibl/rcrt-sdk/types` are structurally compatible with the
|
|
6
|
+
* OpenAPI spec. If the spec drifts (new required field, renamed prop,
|
|
7
|
+
* changed enum) without a matching hand-written update, `tsc` fails
|
|
8
|
+
* here and the PR is blocked until the two are re-aligned.
|
|
9
|
+
*
|
|
10
|
+
* The asserts are one-directional. They check that our domain shape
|
|
11
|
+
* ⊇ the wire shape (we accept everything the server sends). We do
|
|
12
|
+
* NOT check the reverse — by design, hand-written types can be richer
|
|
13
|
+
* (flexible rows, normalised error envelope, etc.).
|
|
14
|
+
*
|
|
15
|
+
* If this file fails to compile:
|
|
16
|
+
* - Read the error message carefully — it points at the specific
|
|
17
|
+
* property that diverged.
|
|
18
|
+
* - Either update the hand-written type to accept the new shape, or
|
|
19
|
+
* update the OpenAPI spec if the code changed first (more common).
|
|
20
|
+
* - Re-run `pnpm run codegen` and commit the regenerated
|
|
21
|
+
* `src/generated/openapi.ts` in the same PR.
|
|
22
|
+
*/
|
|
23
|
+
import type { components } from './openapi.js';
|
|
24
|
+
import type { Card, Breadcrumb } from '../types/index.js';
|
|
25
|
+
/**
|
|
26
|
+
* Compile-time assertion that `Got` extends `Expected`.
|
|
27
|
+
* Produces a type error at the `_check_*` declaration if not.
|
|
28
|
+
*/
|
|
29
|
+
type AssertExtends<Got, Expected> = Got extends Expected ? true : never;
|
|
30
|
+
/**
|
|
31
|
+
* Our hand-written `Card` must accept every property required by the
|
|
32
|
+
* spec's `components.schemas.Card`. If you see an error here, the spec
|
|
33
|
+
* gained a required field that our type doesn't model. Update the type
|
|
34
|
+
* (preferred) or relax the spec.
|
|
35
|
+
*
|
|
36
|
+
* We use Pick<…, X> so the assertion only covers the fields we've
|
|
37
|
+
* explicitly opted into. Ignoring fields we don't surface (e.g. legacy
|
|
38
|
+
* spec-level extras) is intentional.
|
|
39
|
+
*/
|
|
40
|
+
type _check_card_layout = AssertExtends<Pick<Card, 'layout' | 'header'>, Pick<components['schemas']['Card'], 'layout' | 'header'>>;
|
|
41
|
+
/**
|
|
42
|
+
* Breadcrumb.content is an open `Record<string, unknown>` — intentional.
|
|
43
|
+
* Only check the metadata fields that are load-bearing for the SDK.
|
|
44
|
+
*/
|
|
45
|
+
type _check_breadcrumb_core = AssertExtends<Pick<Breadcrumb, 'id' | 'tags' | 'content'>, Pick<components['schemas']['Breadcrumb'], 'id' | 'tags' | 'content'>>;
|
|
46
|
+
export type __conformanceGuards = [_check_card_layout, _check_breadcrumb_core];
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../../src/generated/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI1D;;;GAGG;AACH,KAAK,aAAa,CAAC,GAAG,EAAE,QAAQ,IAAI,GAAG,SAAS,QAAQ,GAAG,IAAI,GAAG,KAAK,CAAC;AAIxE;;;;;;;;;GASG;AACH,KAAK,kBAAkB,GAAG,aAAa,CACrC,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC,EAC/B,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC,CACzD,CAAC;AAEF;;;GAGG;AACH,KAAK,sBAAsB,GAAG,aAAa,CACzC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,EAC3C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,CACrE,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract conformance guardrail.
|
|
3
|
+
*
|
|
4
|
+
* Asserts at compile time that the hand-written domain types in
|
|
5
|
+
* `@possibl/rcrt-sdk/types` are structurally compatible with the
|
|
6
|
+
* OpenAPI spec. If the spec drifts (new required field, renamed prop,
|
|
7
|
+
* changed enum) without a matching hand-written update, `tsc` fails
|
|
8
|
+
* here and the PR is blocked until the two are re-aligned.
|
|
9
|
+
*
|
|
10
|
+
* The asserts are one-directional. They check that our domain shape
|
|
11
|
+
* ⊇ the wire shape (we accept everything the server sends). We do
|
|
12
|
+
* NOT check the reverse — by design, hand-written types can be richer
|
|
13
|
+
* (flexible rows, normalised error envelope, etc.).
|
|
14
|
+
*
|
|
15
|
+
* If this file fails to compile:
|
|
16
|
+
* - Read the error message carefully — it points at the specific
|
|
17
|
+
* property that diverged.
|
|
18
|
+
* - Either update the hand-written type to accept the new shape, or
|
|
19
|
+
* update the OpenAPI spec if the code changed first (more common).
|
|
20
|
+
* - Re-run `pnpm run codegen` and commit the regenerated
|
|
21
|
+
* `src/generated/openapi.ts` in the same PR.
|
|
22
|
+
*/
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=conformance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../../src/generated/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated OpenAPI types.
|
|
3
|
+
*
|
|
4
|
+
* This module is produced by `pnpm run codegen` against
|
|
5
|
+
* `packages/docs/openapi/v1.yaml` — the hand-maintained API contract.
|
|
6
|
+
* Do NOT edit the generated file by hand. Edit the spec, then regenerate.
|
|
7
|
+
*
|
|
8
|
+
* ## When to use these types
|
|
9
|
+
*
|
|
10
|
+
* - **Raw fetch-level type safety** — e.g. you're bypassing the `RcrtClient`
|
|
11
|
+
* and calling the HTTP endpoints directly. Use `paths`, `operations`, or
|
|
12
|
+
* `components` to type request bodies + response shapes.
|
|
13
|
+
* - **Contract conformance checks** — asserting at compile time that a
|
|
14
|
+
* hand-written type is a structural subset of the wire shape.
|
|
15
|
+
*
|
|
16
|
+
* ## When NOT to use these types
|
|
17
|
+
*
|
|
18
|
+
* - **Domain modelling in app code.** Prefer the hand-written types in
|
|
19
|
+
* `@possibl/rcrt-sdk/types` (`Card`, `Breadcrumb`, `Row`, `ChartSpec`).
|
|
20
|
+
* They are richer: documented flexibly (e.g. `FlexibleTextRow`),
|
|
21
|
+
* discriminated-union-friendly, and wear the `ApiErrorDetail` shape
|
|
22
|
+
* normalised across both the canonical and legacy error envelopes.
|
|
23
|
+
*
|
|
24
|
+
* ## Usage
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* import type { components, operations } from '@possibl/rcrt-sdk/generated';
|
|
28
|
+
*
|
|
29
|
+
* type RawCard = components['schemas']['Card'];
|
|
30
|
+
* type ChatRequest = operations['post_v1_chat']['requestBody']['content']['application/json'];
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export type { paths, components, operations, webhooks } from './openapi.js';
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated OpenAPI types.
|
|
3
|
+
*
|
|
4
|
+
* This module is produced by `pnpm run codegen` against
|
|
5
|
+
* `packages/docs/openapi/v1.yaml` — the hand-maintained API contract.
|
|
6
|
+
* Do NOT edit the generated file by hand. Edit the spec, then regenerate.
|
|
7
|
+
*
|
|
8
|
+
* ## When to use these types
|
|
9
|
+
*
|
|
10
|
+
* - **Raw fetch-level type safety** — e.g. you're bypassing the `RcrtClient`
|
|
11
|
+
* and calling the HTTP endpoints directly. Use `paths`, `operations`, or
|
|
12
|
+
* `components` to type request bodies + response shapes.
|
|
13
|
+
* - **Contract conformance checks** — asserting at compile time that a
|
|
14
|
+
* hand-written type is a structural subset of the wire shape.
|
|
15
|
+
*
|
|
16
|
+
* ## When NOT to use these types
|
|
17
|
+
*
|
|
18
|
+
* - **Domain modelling in app code.** Prefer the hand-written types in
|
|
19
|
+
* `@possibl/rcrt-sdk/types` (`Card`, `Breadcrumb`, `Row`, `ChartSpec`).
|
|
20
|
+
* They are richer: documented flexibly (e.g. `FlexibleTextRow`),
|
|
21
|
+
* discriminated-union-friendly, and wear the `ApiErrorDetail` shape
|
|
22
|
+
* normalised across both the canonical and legacy error envelopes.
|
|
23
|
+
*
|
|
24
|
+
* ## Usage
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* import type { components, operations } from '@possibl/rcrt-sdk/generated';
|
|
28
|
+
*
|
|
29
|
+
* type RawCard = components['schemas']['Card'];
|
|
30
|
+
* type ChatRequest = operations['post_v1_chat']['requestBody']['content']['application/json'];
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG"}
|