@softr/sdk 0.0.29 → 0.0.30

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.
@@ -1,5 +1,22 @@
1
1
  //#region src/core/integration.d.ts
2
- declare function integrationFetch(datasourceId: string, input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
2
+ interface IntegrationFetchOptions {
3
+ dataSourceId: string;
4
+ url: string;
5
+ method?: string;
6
+ headers?: Record<string, string>;
7
+ body?: string;
8
+ queryParams?: Record<string, string>;
9
+ signal?: AbortSignal;
10
+ }
11
+ declare function integrationFetch({
12
+ dataSourceId,
13
+ url: rawUrl,
14
+ method,
15
+ headers,
16
+ body,
17
+ queryParams,
18
+ signal
19
+ }: IntegrationFetchOptions): Promise<Response>;
3
20
  declare const integration: {
4
21
  fetch: typeof integrationFetch;
5
22
  };
@@ -2,28 +2,28 @@ import { readSessionToken } from "../auth/session.js";
2
2
  import { dsUrl } from "../datasource/record.js";
3
3
 
4
4
  //#region src/core/integration.ts
5
- async function integrationFetch(datasourceId, input, init) {
6
- const req = new Request(input, init);
7
- if (req.signal.aborted) throw req.signal.reason ?? new DOMException("The operation was aborted.", "AbortError");
8
- const reqHeaders = {};
9
- new Headers(req.headers).forEach((value, key) => {
10
- reqHeaders[key] = value;
11
- });
5
+ async function integrationFetch({ dataSourceId, url: rawUrl, method = "GET", headers = {}, body, queryParams, signal }) {
6
+ if (signal?.aborted) throw signal.reason ?? new DOMException("The operation was aborted.", "AbortError");
7
+ let url = rawUrl;
8
+ if (queryParams && Object.keys(queryParams).length > 0) {
9
+ const params = new URLSearchParams(queryParams);
10
+ url += (rawUrl.includes("?") ? "&" : "?") + params.toString();
11
+ }
12
+ const upperMethod = method.toUpperCase();
12
13
  const payload = {
13
- method: req.method,
14
- url: req.url,
15
- headers: reqHeaders
14
+ method: upperMethod,
15
+ url,
16
+ headers
16
17
  };
17
- const method = req.method.toUpperCase();
18
- if (method !== "GET" && method !== "HEAD" && req.body !== null) payload.body = await req.clone().text();
19
- return fetch(`${dsUrl(datasourceId)}/proxy`, {
18
+ if (upperMethod !== "GET" && upperMethod !== "HEAD" && body !== void 0) payload.body = body;
19
+ return fetch(`${dsUrl(dataSourceId)}/proxy`, {
20
20
  method: "POST",
21
21
  headers: {
22
22
  "Content-Type": "application/json",
23
23
  "Authorization": `Bearer ${readSessionToken()}`
24
24
  },
25
25
  body: JSON.stringify(payload),
26
- signal: req.signal
26
+ signal
27
27
  });
28
28
  }
29
29
  const integration = { fetch: integrationFetch };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.0.29";
2
+ var version = "0.0.30";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softr/sdk",
3
- "version": "0.0.29",
3
+ "version": "0.0.30",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
@@ -11,7 +11,7 @@ description: >-
11
11
  metadata:
12
12
  type: core
13
13
  library: softr-sdk
14
- library_version: 0.0.29
14
+ library_version: 0.0.30
15
15
  ---
16
16
 
17
17
  # Softr SDK core
@@ -16,7 +16,7 @@ description: >-
16
16
  metadata:
17
17
  type: sub-skill
18
18
  library: softr-sdk
19
- library_version: 0.0.29
19
+ library_version: 0.0.30
20
20
  ---
21
21
 
22
22
  **Boundary.** `auth` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineVisibility`, the hooks and every type come from `@softr/sdk`. The app is already wired (`src/start.ts`, `src/router.tsx`, `src/routes/__root.tsx`); never add a second registration. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.
@@ -12,7 +12,7 @@ description: >-
12
12
  metadata:
13
13
  type: sub-skill
14
14
  library: softr-sdk
15
- library_version: 0.0.29
15
+ library_version: 0.0.30
16
16
  ---
17
17
 
18
18
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere. The app is already wired (`src/start.ts`, `src/router.tsx`, `src/routes/__root.tsx`); never add a second registration. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.
@@ -10,7 +10,7 @@ description: >-
10
10
  metadata:
11
11
  type: sub-skill
12
12
  library: softr-sdk
13
- library_version: 0.0.29
13
+ library_version: 0.0.30
14
14
  ---
15
15
 
16
16
  **Boundary.** `useCurrentUser`, `usePermissions` and every type come from `@softr/sdk` and work anywhere; `ds` and `auth` live on `@softr/sdk/server` and run only inside a `createServerFn` handler. The app is already wired — `src/start.ts` registers `softrAuthMiddleware`, `src/routes/__root.tsx` publishes the visitor as route context — never add a second registration. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.
@@ -2,15 +2,15 @@
2
2
  name: integrations
3
3
  description: >-
4
4
  Call a third-party service connected to the app as an integration:
5
- integration.fetch from @softr/sdk/server, reading the datasource id and
6
- integration type from the "Attached data sources" prompt section, looking up
7
- the base URL from the reference table by integrationType, and constructing the
8
- full API URL from base URL plus the path and query params the model knows from
9
- training. Check res.ok before res.json().
5
+ integration.fetch({ dataSourceId, url, method, queryParams, body }) from
6
+ @softr/sdk/server, reading the datasource id and integration type from the
7
+ "Attached data sources" prompt section, looking up the base URL from the
8
+ reference table by integrationType, constructing the URL path, and passing
9
+ query params as an object. Check res.ok before res.json().
10
10
  metadata:
11
11
  type: sub-skill
12
12
  library: softr-sdk
13
- library_version: 0.0.29
13
+ library_version: 0.0.30
14
14
  ---
15
15
 
16
16
  **Boundary.** `integration` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.
@@ -34,23 +34,28 @@ When the user attaches integrations to the chat, they appear in the `## Attached
34
34
  - "Gmail" — database `<databaseId>`, integration `<integrationId>`, type `GMAIL`
35
35
  ```
36
36
 
37
- Use `databaseId` as the first argument to `integration.fetch` — that is the `database` coordinate, not the `integration` one. The `integration` value is the OAuth connection identifier; do not pass it to `integration.fetch`. Use `integrationType` (e.g. `GMAIL`) to look up the base URL from the reference table below — then construct the full URL by appending the path and query parameters your training knows for that API.
37
+ Use `databaseId` as `dataSourceId` in the options object passed to `integration.fetch` — that is the `database` coordinate, not the `integration` one. The `integration` value is the OAuth connection identifier; do not pass it to `integration.fetch`. Use `integrationType` (e.g. `GMAIL`) to look up the base URL from the reference table below — then construct the full URL path and pass query parameters as the `queryParams` object.
38
38
 
39
39
  ## Core pattern
40
40
 
41
41
  ```ts
42
42
  const getCalendarEvents = createServerFn().handler(async () => {
43
- const now = new Date().toISOString()
44
- const res = await integration.fetch(
45
- '25d60213-ef4f-4fa0-b094-a46931b2d120',
46
- `https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=${encodeURIComponent(now)}&singleEvents=true&orderBy=startTime&maxResults=10`,
47
- )
43
+ const res = await integration.fetch({
44
+ dataSourceId: '25d60213-ef4f-4fa0-b094-a46931b2d120',
45
+ url: 'https://www.googleapis.com/calendar/v3/calendars/primary/events',
46
+ queryParams: {
47
+ timeMin: new Date().toISOString(),
48
+ singleEvents: 'true',
49
+ orderBy: 'startTime',
50
+ maxResults: '10',
51
+ },
52
+ })
48
53
  if (!res.ok) throw new Error(`Integration request failed: ${res.status} ${await res.text()}`)
49
54
  return res.json()
50
55
  })
51
56
  ```
52
57
 
53
- The id (`25d60213-…`) is the `databaseId` from the attached data sources section — the `database` coordinate, not the `integration` one. The base URL (`https://www.googleapis.com`) is looked up from the reference table below by matching `integrationType` (`GOOGLE_CALENDAR`). The path and query params come from your knowledge of the Google Calendar REST API.
58
+ `dataSourceId` is the `databaseId` from the attached data sources section — the `database` coordinate, not the `integration` one. The base URL (`https://www.googleapis.com`) is looked up from the reference table below by matching `integrationType` (`GOOGLE_CALENDAR`). The path and query params come from your knowledge of the Google Calendar REST API.
54
59
 
55
60
  ## POST request
56
61
 
@@ -58,21 +63,19 @@ The id (`25d60213-…`) is the `databaseId` from the attached data sources secti
58
63
  const sendSlackMessage = createServerFn({ method: 'POST' })
59
64
  .validator((data: { channel: string; text: string }) => data)
60
65
  .handler(async ({ data }) => {
61
- const res = await integration.fetch(
62
- 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
63
- 'https://slack.com/api/chat.postMessage',
64
- {
65
- method: 'POST',
66
- headers: { 'Content-Type': 'application/json' },
67
- body: JSON.stringify({ channel: data.channel, text: data.text }),
68
- },
69
- )
66
+ const res = await integration.fetch({
67
+ dataSourceId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
68
+ url: 'https://slack.com/api/chat.postMessage',
69
+ method: 'POST',
70
+ headers: { 'Content-Type': 'application/json' },
71
+ body: JSON.stringify({ channel: data.channel, text: data.text }),
72
+ })
70
73
  if (!res.ok) throw new Error(`Slack error: ${res.status} ${await res.text()}`)
71
74
  return res.json()
72
75
  })
73
76
  ```
74
77
 
75
- `integration.fetch` accepts the same `RequestInit` options as the native `fetch`. Do not pass `Authorization` headers — Softr injects the integration's credentials automatically.
78
+ Do not add an `Authorization` key to `headers` — Softr injects the integration's credentials automatically.
76
79
 
77
80
  ## Base URLs by integration type
78
81
 
@@ -11,7 +11,7 @@ description: >-
11
11
  metadata:
12
12
  type: sub-skill
13
13
  library: softr-sdk
14
- library_version: 0.0.29
14
+ library_version: 0.0.30
15
15
  ---
16
16
 
17
17
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineMutation` and every type come from `@softr/sdk` and can be imported anywhere. The app is already wired (`src/start.ts`, `src/router.tsx`, `src/routes/__root.tsx`); never add a second registration. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.
@@ -12,7 +12,7 @@ description: >-
12
12
  metadata:
13
13
  type: sub-skill
14
14
  library: softr-sdk
15
- library_version: 0.0.29
15
+ library_version: 0.0.30
16
16
  ---
17
17
 
18
18
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere. The app is already wired (`src/start.ts`, `src/router.tsx`, `src/routes/__root.tsx`); never add a second registration. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.
@@ -12,7 +12,7 @@ description: >-
12
12
  metadata:
13
13
  type: sub-skill
14
14
  library: softr-sdk
15
- library_version: 0.0.29
15
+ library_version: 0.0.30
16
16
  ---
17
17
 
18
18
  **Boundary.** `defineVisibility`, the error predicates and every type come from `@softr/sdk` and work anywhere; `ds` and `auth` live on `@softr/sdk/server` and run only inside a `createServerFn` handler. The app is already wired — `src/start.ts` registers `softrAuthMiddleware`, `src/routes/__root.tsx` publishes the visitor as route context — never add a second registration. Load the core `softr-sdk` skill only if you are unsure this is the right sub-skill.