@softr/sdk 0.0.49-alpha.0 → 0.0.50-alpha.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/dist/auth/platform.js +1 -1
- package/dist/cli.js +31 -7
- package/dist/codegen/fetch-metadata.js +1 -1
- package/dist/codegen/write-datasource-docs.js +1 -0
- package/dist/core/workflow.js +1 -1
- package/dist/datasource/chart.js +1 -1
- package/dist/datasource/record.js +1 -1
- package/dist/default-error-overlay.js +16 -6
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +3 -3
- package/dist/package.js +1 -1
- package/package.json +33 -10
- package/skills/softr-sdk/SKILL.md +1 -1
- package/skills/softr-sdk/auth/SKILL.md +1 -1
- package/skills/softr-sdk/charts-and-metrics/SKILL.md +1 -1
- package/skills/softr-sdk/current-user/SKILL.md +2 -19
- package/skills/softr-sdk/file-uploads/SKILL.md +1 -1
- package/skills/softr-sdk/integrations/SKILL.md +4 -4
- package/skills/softr-sdk/mcp/SKILL.md +1 -1
- package/skills/softr-sdk/record-mutations/SKILL.md +1 -1
- package/skills/softr-sdk/record-queries/SKILL.md +1 -1
- package/skills/softr-sdk/region-visibility/SKILL.md +1 -1
- package/skills/softr-sdk/routes-and-visibility/SKILL.md +5 -6
- package/skills/softr-sdk/workflows/SKILL.md +1 -1
package/dist/auth/platform.js
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,26 +1,50 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { version } from "./package.js";
|
|
3
|
+
import { requireDefined } from "./assertions.js";
|
|
3
4
|
import { fetchSoftrEnvInput, metadataSourceFromEnv } from "./codegen/fetch-metadata.js";
|
|
4
5
|
import { renderSoftrEnv } from "./codegen/softr-env.js";
|
|
5
6
|
import { writeDatasourceDocs } from "./codegen/write-datasource-docs.js";
|
|
6
7
|
import { writeFileSync } from "node:fs";
|
|
7
8
|
import path from "node:path";
|
|
9
|
+
import { parseArgs } from "node:util";
|
|
8
10
|
|
|
9
11
|
//#region src/cli.ts
|
|
10
12
|
const OUTPUT = "softr-env.d.ts";
|
|
11
13
|
const DOCS_DIR = "docs/datasources";
|
|
12
|
-
async function generate() {
|
|
14
|
+
async function generate({ json }) {
|
|
15
|
+
if (json) console.info = console.error;
|
|
13
16
|
const input = await fetchSoftrEnvInput(metadataSourceFromEnv());
|
|
14
17
|
writeFileSync(path.resolve(process.cwd(), OUTPUT), renderSoftrEnv(input, version), "utf8");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
const docFiles = writeDatasourceDocs(input.datasources, path.resolve(process.cwd(), DOCS_DIR));
|
|
19
|
+
const report = {
|
|
20
|
+
types: OUTPUT,
|
|
21
|
+
docsIndex: `${DOCS_DIR}/README.md`,
|
|
22
|
+
datasources: input.datasources.map(({ id, name }) => ({
|
|
23
|
+
id,
|
|
24
|
+
name,
|
|
25
|
+
doc: `${DOCS_DIR}/${requireDefined(docFiles.get(id))}`
|
|
26
|
+
}))
|
|
27
|
+
};
|
|
28
|
+
if (json) {
|
|
29
|
+
process.stdout.write(`${JSON.stringify(report)}\n`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log(`[softr] wrote ${report.types}`);
|
|
33
|
+
console.log(`[softr] wrote ${report.docsIndex}`);
|
|
34
|
+
for (const datasource of report.datasources) console.log(`[softr] wrote ${datasource.doc} for ${datasource.name} (${datasource.id})`);
|
|
18
35
|
}
|
|
19
|
-
const
|
|
20
|
-
|
|
36
|
+
const { positionals, values } = parseArgs({
|
|
37
|
+
allowPositionals: true,
|
|
38
|
+
options: { json: {
|
|
39
|
+
type: "boolean",
|
|
40
|
+
default: false
|
|
41
|
+
} }
|
|
42
|
+
});
|
|
43
|
+
const [command] = positionals;
|
|
44
|
+
if (command === "generate") await generate({ json: values.json });
|
|
21
45
|
else {
|
|
22
46
|
console.error(command ? `softr-sdk: unknown command '${command}'` : "softr-sdk: no command given");
|
|
23
|
-
console.error("usage: softr-sdk generate");
|
|
47
|
+
console.error("usage: softr-sdk generate [--json]");
|
|
24
48
|
process.exit(1);
|
|
25
49
|
}
|
|
26
50
|
|
|
@@ -18,6 +18,7 @@ function writeDatasourceDocs(datasources, docsDir) {
|
|
|
18
18
|
mkdirSync(docsDir, { recursive: true });
|
|
19
19
|
writeFileSync(path.join(docsDir, "README.md"), renderDatasourceIndex(datasources, context), "utf8");
|
|
20
20
|
for (const datasource of datasources) writeFileSync(path.join(docsDir, requireDefined(context.fileNames.get(datasource.id))), renderDatasourceDoc(datasource, context), "utf8");
|
|
21
|
+
return context.fileNames;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
//#endregion
|
package/dist/core/workflow.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fetch } from "../fetch.js";
|
|
2
1
|
import { panic } from "../assertions.js";
|
|
2
|
+
import { fetch } from "../fetch.js";
|
|
3
3
|
import { sessionConfig } from "../auth/config.js";
|
|
4
4
|
import { readSessionToken } from "../auth/session.js";
|
|
5
5
|
import { platformApiUrl } from "../auth/platform.js";
|
package/dist/datasource/chart.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fetch } from "../fetch.js";
|
|
2
1
|
import { assert, panic } from "../assertions.js";
|
|
2
|
+
import { fetch } from "../fetch.js";
|
|
3
3
|
import { readUserTimezone } from "../cookies.js";
|
|
4
4
|
import { readSessionToken } from "../auth/session.js";
|
|
5
5
|
import { INTERNAL_KIND, buildFilterCriteria, buildOrderBy, dealiasFilterCriteria } from "./filter.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fetch } from "../fetch.js";
|
|
2
1
|
import { assert, panic } from "../assertions.js";
|
|
2
|
+
import { fetch } from "../fetch.js";
|
|
3
3
|
import { readUserTimezone } from "../cookies.js";
|
|
4
4
|
import { readSessionToken } from "../auth/session.js";
|
|
5
5
|
import { isDatasourceAction } from "../action.js";
|
|
@@ -17,6 +17,7 @@ function isAgentTurnRunning() {
|
|
|
17
17
|
function DefaultErrorOverlay({ error, reset }) {
|
|
18
18
|
if (process.env.NODE_ENV === "production") return /* @__PURE__ */ jsx("div", {
|
|
19
19
|
style: s.overlay,
|
|
20
|
+
"data-softr-error-overlay": "error",
|
|
20
21
|
children: /* @__PURE__ */ jsxs("div", {
|
|
21
22
|
style: s.card,
|
|
22
23
|
children: [
|
|
@@ -39,24 +40,32 @@ function DefaultErrorOverlay({ error, reset }) {
|
|
|
39
40
|
}
|
|
40
41
|
function DevView({ error, reset }) {
|
|
41
42
|
const running = useSyncExternalStore(subscribeToAgentTurn, isAgentTurnRunning, () => false);
|
|
42
|
-
const caughtDuringTurn =
|
|
43
|
+
const [caughtDuringTurn, setCaughtDuringTurn] = useState(running);
|
|
43
44
|
const router = useRouter();
|
|
44
45
|
useEffect(() => {
|
|
45
46
|
if (running) {
|
|
46
|
-
|
|
47
|
+
setCaughtDuringTurn(true);
|
|
47
48
|
return;
|
|
48
49
|
}
|
|
49
|
-
if (!caughtDuringTurn
|
|
50
|
-
const
|
|
50
|
+
if (!caughtDuringTurn) return;
|
|
51
|
+
const showError = () => setCaughtDuringTurn(false);
|
|
52
|
+
const timer = setTimeout(() => {
|
|
53
|
+
router.invalidate().then(() => {
|
|
54
|
+
reset?.();
|
|
55
|
+
showError();
|
|
56
|
+
}, showError);
|
|
57
|
+
}, 1e3);
|
|
51
58
|
return () => clearTimeout(timer);
|
|
52
59
|
}, [
|
|
53
60
|
running,
|
|
61
|
+
caughtDuringTurn,
|
|
54
62
|
reset,
|
|
55
63
|
router
|
|
56
64
|
]);
|
|
57
|
-
if (running) return /* @__PURE__ */ jsx(UpdatingView, {});
|
|
65
|
+
if (running || caughtDuringTurn) return /* @__PURE__ */ jsx(UpdatingView, {});
|
|
58
66
|
return /* @__PURE__ */ jsx("div", {
|
|
59
67
|
style: s.overlay,
|
|
68
|
+
"data-softr-error-overlay": "error",
|
|
60
69
|
children: /* @__PURE__ */ jsxs("div", {
|
|
61
70
|
style: s.card,
|
|
62
71
|
children: [
|
|
@@ -88,6 +97,7 @@ function DevView({ error, reset }) {
|
|
|
88
97
|
function UpdatingView() {
|
|
89
98
|
return /* @__PURE__ */ jsx("div", {
|
|
90
99
|
style: s.overlay,
|
|
100
|
+
"data-softr-error-overlay": "updating",
|
|
91
101
|
children: /* @__PURE__ */ jsxs("div", {
|
|
92
102
|
style: s.card,
|
|
93
103
|
children: [/* @__PURE__ */ jsx("div", {
|
|
@@ -339,7 +349,7 @@ const s = {
|
|
|
339
349
|
border: "1px solid var(--input, oklch(0.922 0 0))",
|
|
340
350
|
borderRadius: "var(--radius, 0.625rem)",
|
|
341
351
|
background: "var(--input-fill, oklch(1 0 0))",
|
|
342
|
-
color: "var(--
|
|
352
|
+
color: "var(--foreground, oklch(0.145 0 0))",
|
|
343
353
|
fontFamily: "inherit",
|
|
344
354
|
fontSize: "0.875rem",
|
|
345
355
|
fontWeight: 500,
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DatasourceAction } from "./action.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _tanstack_react_start2 from "@tanstack/react-start";
|
|
3
3
|
|
|
4
4
|
//#region src/mcp.d.ts
|
|
5
5
|
|
|
@@ -37,6 +37,6 @@ type SoftrMcpOptions = {
|
|
|
37
37
|
* ],
|
|
38
38
|
* }))
|
|
39
39
|
*/
|
|
40
|
-
declare function softrMcpMiddleware(options?: SoftrMcpOptions):
|
|
40
|
+
declare function softrMcpMiddleware(options?: SoftrMcpOptions): _tanstack_react_start2.RequestMiddlewareAfterServer<{}, undefined, undefined>;
|
|
41
41
|
//#endregion
|
|
42
42
|
export { softrMcpMiddleware };
|
package/dist/mcp.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fetch } from "./fetch.js";
|
|
2
1
|
import { assert } from "./assertions.js";
|
|
2
|
+
import { fetch } from "./fetch.js";
|
|
3
3
|
import { sessionConfig } from "./auth/config.js";
|
|
4
4
|
import { readSessionToken, withSessionToken } from "./auth/session.js";
|
|
5
5
|
import { makePlatform, platformApiUrl } from "./auth/platform.js";
|
|
@@ -226,10 +226,10 @@ async function platformSession(accessToken) {
|
|
|
226
226
|
ok: false,
|
|
227
227
|
refused: response.status === 401 || response.status === 403
|
|
228
228
|
};
|
|
229
|
-
const parsed = z.object({
|
|
229
|
+
const parsed = z.object({ sessionJwt: z.string() }).safeParse(await response.json().catch(() => null));
|
|
230
230
|
return parsed.success ? {
|
|
231
231
|
ok: true,
|
|
232
|
-
sessionToken: parsed.data.
|
|
232
|
+
sessionToken: parsed.data.sessionJwt
|
|
233
233
|
} : {
|
|
234
234
|
ok: false,
|
|
235
235
|
refused: false
|
package/dist/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softr/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.50-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
|
-
".": {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"./client": {
|
|
11
|
+
"types": "./dist/client.d.ts",
|
|
12
|
+
"import": "./dist/client.js"
|
|
13
|
+
},
|
|
14
|
+
"./server": {
|
|
15
|
+
"types": "./dist/server.d.ts",
|
|
16
|
+
"import": "./dist/server.js"
|
|
17
|
+
},
|
|
18
|
+
"./vite": {
|
|
19
|
+
"types": "./dist/vite.d.ts",
|
|
20
|
+
"import": "./dist/vite.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"softr-sdk": "./dist/cli.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"schema",
|
|
29
|
+
"skills",
|
|
30
|
+
"!skills/_artifacts"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
14
35
|
"scripts": {
|
|
15
36
|
"build": "tsdown",
|
|
16
37
|
"test": "node --import ./src/test-utils/setup.ts --test",
|
|
@@ -42,7 +63,9 @@
|
|
|
42
63
|
"optional": true
|
|
43
64
|
}
|
|
44
65
|
},
|
|
45
|
-
"keywords": [
|
|
66
|
+
"keywords": [
|
|
67
|
+
"tanstack-intent"
|
|
68
|
+
],
|
|
46
69
|
"intent": {
|
|
47
70
|
"version": 1,
|
|
48
71
|
"repo": "@softr/sdk",
|
|
@@ -16,7 +16,7 @@ description: >-
|
|
|
16
16
|
metadata:
|
|
17
17
|
type: sub-skill
|
|
18
18
|
library: softr-sdk
|
|
19
|
-
library_version: 0.0.
|
|
19
|
+
library_version: 0.0.50
|
|
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.
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
metadata:
|
|
13
13
|
type: sub-skill
|
|
14
14
|
library: softr-sdk
|
|
15
|
-
library_version: 0.0.
|
|
15
|
+
library_version: 0.0.50
|
|
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.
|
|
@@ -4,12 +4,11 @@ description: >-
|
|
|
4
4
|
Read the signed-in Softr visitor: useCurrentUser and the User type,
|
|
5
5
|
context.user in a route's beforeLoad, and context.user inside a server
|
|
6
6
|
function handler, where Start types it from the app's registered request
|
|
7
|
-
middleware. Covers the null guest
|
|
8
|
-
that narrows group ids to your own.
|
|
7
|
+
middleware. Covers the null guest.
|
|
9
8
|
metadata:
|
|
10
9
|
type: sub-skill
|
|
11
10
|
library: softr-sdk
|
|
12
|
-
library_version: 0.0.
|
|
11
|
+
library_version: 0.0.50
|
|
13
12
|
---
|
|
14
13
|
|
|
15
14
|
# The current user
|
|
@@ -84,22 +83,6 @@ const getMyInvoices = createServerFn().handler(async ({ context }) => {
|
|
|
84
83
|
|
|
85
84
|
`context.user` is typed. Start derives a handler's context from the app's registered request middleware as well as the server function's own, so there is nothing to import and nothing to cast.
|
|
86
85
|
|
|
87
|
-
### Narrowing group ids to your own
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// src/softr.d.ts
|
|
91
|
-
declare module '@softr/sdk' {
|
|
92
|
-
interface SoftrUserGroups {
|
|
93
|
-
ids:
|
|
94
|
-
| '00000000-0000-0000-0000-00000000000a'
|
|
95
|
-
| '00000000-0000-0000-0000-00000000000b'
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
export {}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
With this declaration, `user.userGroupIds` and every `userGroupIds` the SDK accepts narrow to those ids, and a typo stops compiling. Without it they are plain `string`.
|
|
102
|
-
|
|
103
86
|
## References
|
|
104
87
|
|
|
105
88
|
- [routes-and-visibility/SKILL.md](../routes-and-visibility/SKILL.md): `isAuthorized` narrows `context.user` while applying the route's rule
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
metadata:
|
|
11
11
|
type: sub-skill
|
|
12
12
|
library: softr-sdk
|
|
13
|
-
library_version: 0.0.
|
|
13
|
+
library_version: 0.0.50
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
**Boundary.** `upload` lives on `@softr/sdk/server` and runs inside server functions. `useFileUpload` and `FileItem` live on `@softr/sdk` and run in components. `FileAttachment` comes from `@softr/sdk` and can be imported anywhere.
|
|
@@ -4,13 +4,13 @@ description: >-
|
|
|
4
4
|
Call a third-party service connected to the app as an integration:
|
|
5
5
|
defineIntegration from @softr/sdk declares the action with its integrationId,
|
|
6
6
|
the one HTTP method and endpoint url it allows, and permissions;
|
|
7
|
-
integration.createFetcher from @softr/sdk/server binds it and returns a
|
|
8
|
-
function you call with optional params, query, headers, and body.
|
|
9
|
-
before res.json().
|
|
7
|
+
integration.createFetcher from @softr/sdk/server binds it and returns a
|
|
8
|
+
fetcher function you call with optional params, query, headers, and body.
|
|
9
|
+
Check res.ok before res.json().
|
|
10
10
|
metadata:
|
|
11
11
|
type: sub-skill
|
|
12
12
|
library: softr-sdk
|
|
13
|
-
library_version: 0.0.
|
|
13
|
+
library_version: 0.0.50
|
|
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. `defineIntegration` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
metadata:
|
|
10
10
|
type: sub-skill
|
|
11
11
|
library: softr-sdk
|
|
12
|
-
library_version: 0.0.
|
|
12
|
+
library_version: 0.0.50
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
**Boundary.** `softrMcpMiddleware` lives on `@softr/sdk` and is registered once, in `src/start.ts`. The actions you hand it are the same `defineQuery` / `defineMutation` values the app's own pages use — declared wherever they already live, not duplicated for MCP.
|
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
metadata:
|
|
12
12
|
type: sub-skill
|
|
13
13
|
library: softr-sdk
|
|
14
|
-
library_version: 0.0.
|
|
14
|
+
library_version: 0.0.50
|
|
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.
|
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
metadata:
|
|
14
14
|
type: sub-skill
|
|
15
15
|
library: softr-sdk
|
|
16
|
-
library_version: 0.0.
|
|
16
|
+
library_version: 0.0.50
|
|
17
17
|
---
|
|
18
18
|
|
|
19
19
|
**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.
|
|
@@ -5,15 +5,14 @@ description: >-
|
|
|
5
5
|
with ALL_USERS, LOGGED_IN_USERS or NON_LOGGED_IN_USERS, userGroupIds, and the
|
|
6
6
|
ways to apply a rule: guardRoute and assertRouteAccess in a route,
|
|
7
7
|
isAuthorized and checkAccess anywhere. Covers per-reason overrides, the
|
|
8
|
-
redirect and throw strategies, rendering an access error with
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
root-level one.
|
|
8
|
+
redirect and throw strategies, rendering an access error with isAccessError,
|
|
9
|
+
isUnauthenticatedError, isForbiddenError and isAlreadyAuthenticatedError,
|
|
10
|
+
guarding a layout, and the lint rule that requires a declaration alongside the
|
|
11
|
+
rules that reject a duplicate, computed or root-level one.
|
|
13
12
|
metadata:
|
|
14
13
|
type: sub-skill
|
|
15
14
|
library: softr-sdk
|
|
16
|
-
library_version: 0.0.
|
|
15
|
+
library_version: 0.0.50
|
|
17
16
|
---
|
|
18
17
|
|
|
19
18
|
**Boundary.** `defineVisibility`, the access functions and the error predicates come from `@softr/sdk` and work anywhere.
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
metadata:
|
|
10
10
|
type: sub-skill
|
|
11
11
|
library: softr-sdk
|
|
12
|
-
library_version: 0.0.
|
|
12
|
+
library_version: 0.0.50
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
**Boundary.** `workflow` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineWorkflow` and every type come from `@softr/sdk` and can be imported anywhere.
|