@softr/sdk 0.0.24 → 0.0.26-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.
Files changed (62) hide show
  1. package/dist/action.d.ts +195 -0
  2. package/dist/action.js +21 -0
  3. package/dist/assertions.js +1 -7
  4. package/dist/auth/isomorphic.d.ts +1 -2
  5. package/dist/auth/methods/authenticator.d.ts +80 -0
  6. package/dist/auth/methods/authenticator.js +175 -0
  7. package/dist/auth/methods/code.d.ts +40 -0
  8. package/dist/auth/methods/code.js +74 -0
  9. package/dist/auth/methods/magicLink.d.ts +24 -0
  10. package/dist/auth/methods/magicLink.js +53 -0
  11. package/dist/auth/methods/password.d.ts +19 -5
  12. package/dist/auth/methods/password.js +36 -15
  13. package/dist/auth/methods/signup.d.ts +22 -14
  14. package/dist/auth/methods/signup.js +48 -54
  15. package/dist/auth/methods/social.d.ts +35 -0
  16. package/dist/auth/methods/social.js +58 -0
  17. package/dist/auth/methods/utils.d.ts +1 -1
  18. package/dist/auth/permissions.d.ts +7 -2
  19. package/dist/auth/platform.js +185 -7
  20. package/dist/auth/server.d.ts +15 -0
  21. package/dist/auth/server.js +16 -1
  22. package/dist/auth/session.js +35 -2
  23. package/dist/cli.d.ts +1 -0
  24. package/dist/cli.js +23 -0
  25. package/dist/codegen/datasource-types.js +471 -0
  26. package/dist/codegen/fetch-metadata.js +46 -0
  27. package/dist/codegen/softr-env.js +102 -0
  28. package/dist/codegen/user-groups.js +11 -0
  29. package/dist/core/integration.js +1 -1
  30. package/dist/datasource/chart.d.ts +196 -0
  31. package/dist/datasource/chart.js +289 -0
  32. package/dist/datasource/datasource.d.ts +16 -0
  33. package/dist/datasource/datasource.js +17 -0
  34. package/dist/datasource/fields.d.ts +122 -0
  35. package/dist/datasource/fields.js +82 -0
  36. package/dist/datasource/filter.d.ts +30 -0
  37. package/dist/datasource/filter.js +146 -0
  38. package/dist/datasource/record.d.ts +138 -0
  39. package/dist/datasource/record.js +258 -0
  40. package/dist/index.d.ts +3 -5
  41. package/dist/index.js +2 -2
  42. package/dist/package.js +5 -0
  43. package/dist/routes/visibility.d.ts +1 -1
  44. package/dist/server.d.ts +1 -1
  45. package/dist/server.js +1 -1
  46. package/package.json +31 -8
  47. package/skills/softr-sdk/SKILL.md +11 -7
  48. package/skills/softr-sdk/auth/SKILL.md +222 -36
  49. package/skills/softr-sdk/charts-and-metrics/SKILL.md +178 -0
  50. package/skills/softr-sdk/charts-and-metrics/references/aggregations.md +76 -0
  51. package/skills/softr-sdk/current-user/SKILL.md +1 -1
  52. package/skills/softr-sdk/data-mutations/SKILL.md +76 -56
  53. package/skills/softr-sdk/reading-records/SKILL.md +77 -93
  54. package/skills/softr-sdk/reading-records/references/field-types.md +41 -48
  55. package/skills/softr-sdk/reading-records/references/query-builder.md +66 -70
  56. package/skills/softr-sdk/routes-and-visibility/SKILL.md +1 -1
  57. package/dist/core/datasource.d.ts +0 -31
  58. package/dist/core/datasource.js +0 -226
  59. package/dist/core/query.d.ts +0 -354
  60. package/dist/core/query.js +0 -528
  61. package/dist/core/utils.js +0 -14
  62. package/dist/types.d.ts +0 -128
@@ -22,18 +22,196 @@ function makePlatform(applicationId) {
22
22
  method: "POST",
23
23
  json: credentials
24
24
  }, z.object({
25
- jwt: z.string(),
26
- user: userSchema,
27
- permissions: permissionsSchema
25
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
26
+ session: z.object({
27
+ jwt: z.string(),
28
+ user: userSchema,
29
+ permissions: permissionsSchema
30
+ }).nullish(),
31
+ mfa: z.object({
32
+ action: z.enum([
33
+ "VERIFICATION_REQUIRED",
34
+ "SETUP_REQUIRED",
35
+ "SETUP_OPTIONAL"
36
+ ]),
37
+ challengeToken: z.string()
38
+ }).nullish()
39
+ })),
40
+ sendSignInCode: (email) => request(`/v1/vibe/applications/${applicationId}/users/tokens/send-code`, {
41
+ method: "POST",
42
+ json: { email }
43
+ }, z.null()),
44
+ signInWithCode: (credentials) => request(`/v1/vibe/applications/${applicationId}/users/tokens/with-code`, {
45
+ method: "POST",
46
+ json: credentials
47
+ }, z.object({
48
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
49
+ session: z.object({
50
+ jwt: z.string(),
51
+ user: userSchema,
52
+ permissions: permissionsSchema
53
+ }).nullish(),
54
+ mfa: z.object({
55
+ action: z.enum([
56
+ "VERIFICATION_REQUIRED",
57
+ "SETUP_REQUIRED",
58
+ "SETUP_OPTIONAL"
59
+ ]),
60
+ challengeToken: z.string()
61
+ }).nullish()
62
+ })),
63
+ signInWithGoogle: (body) => request(`/v1/vibe/applications/${applicationId}/users/tokens/with-google`, {
64
+ method: "POST",
65
+ json: body
66
+ }, z.object({
67
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
68
+ session: z.object({
69
+ jwt: z.string(),
70
+ user: userSchema,
71
+ permissions: permissionsSchema
72
+ }).nullish(),
73
+ mfa: z.object({
74
+ action: z.enum([
75
+ "VERIFICATION_REQUIRED",
76
+ "SETUP_REQUIRED",
77
+ "SETUP_OPTIONAL"
78
+ ]),
79
+ challengeToken: z.string()
80
+ }).nullish()
28
81
  })),
29
- signUp: (body) => request(`/v1/applications/${applicationId}/users/sign-up`, {
82
+ signInWithMagicLink: (body) => request(`/v1/vibe/applications/${applicationId}/users/tokens/with-magic-link`, {
30
83
  method: "POST",
31
84
  json: body
32
- }, z.object({ jwt: z.string().nullish() }).nullable()),
33
- new: (body) => request(`/v1/applications/${applicationId}/users/new`, {
85
+ }, z.object({
86
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
87
+ session: z.object({
88
+ jwt: z.string(),
89
+ user: userSchema,
90
+ permissions: permissionsSchema
91
+ }).nullish(),
92
+ mfa: z.object({
93
+ action: z.enum([
94
+ "VERIFICATION_REQUIRED",
95
+ "SETUP_REQUIRED",
96
+ "SETUP_OPTIONAL"
97
+ ]),
98
+ challengeToken: z.string()
99
+ }).nullish()
100
+ })),
101
+ sendSignUpCode: (body) => request(`/v1/vibe/applications/${applicationId}/users/sign-up/send-code`, {
102
+ method: "POST",
103
+ json: body
104
+ }, z.null()),
105
+ signUpWithCode: (body) => request(`/v1/vibe/applications/${applicationId}/users/sign-up/with-code`, {
106
+ method: "POST",
107
+ json: body
108
+ }, z.object({
109
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
110
+ session: z.object({
111
+ jwt: z.string(),
112
+ user: userSchema,
113
+ permissions: permissionsSchema
114
+ }).nullish(),
115
+ mfa: z.object({
116
+ action: z.enum([
117
+ "VERIFICATION_REQUIRED",
118
+ "SETUP_REQUIRED",
119
+ "SETUP_OPTIONAL"
120
+ ]),
121
+ challengeToken: z.string()
122
+ }).nullish()
123
+ })),
124
+ signUpWithPassword: (body) => request(`/v1/vibe/applications/${applicationId}/users/sign-up/with-password`, {
34
125
  method: "POST",
35
126
  json: body
36
- }, z.object({ jwt: z.string().nullish() }).nullable()),
127
+ }, z.object({
128
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
129
+ session: z.object({
130
+ jwt: z.string(),
131
+ user: userSchema,
132
+ permissions: permissionsSchema
133
+ }).nullish(),
134
+ mfa: z.object({
135
+ action: z.enum([
136
+ "VERIFICATION_REQUIRED",
137
+ "SETUP_REQUIRED",
138
+ "SETUP_OPTIONAL"
139
+ ]),
140
+ challengeToken: z.string()
141
+ }).nullish()
142
+ })),
143
+ authenticatorSetupInit: (token) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/setup/init`, {
144
+ method: "POST",
145
+ token
146
+ }, z.object({
147
+ otpauthUri: z.string(),
148
+ qrPngBase64: z.string()
149
+ })),
150
+ authenticatorSetupComplete: (token, code) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/setup/complete`, {
151
+ method: "POST",
152
+ token,
153
+ json: { code }
154
+ }, z.object({
155
+ session: z.object({
156
+ jwt: z.string(),
157
+ user: userSchema,
158
+ permissions: permissionsSchema
159
+ }),
160
+ backupCodes: z.array(z.string())
161
+ })),
162
+ authenticatorSetupDismiss: (token) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/setup/dismiss`, {
163
+ method: "POST",
164
+ token
165
+ }, z.object({
166
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
167
+ session: z.object({
168
+ jwt: z.string(),
169
+ user: userSchema,
170
+ permissions: permissionsSchema
171
+ }).nullish(),
172
+ mfa: z.object({
173
+ action: z.enum([
174
+ "VERIFICATION_REQUIRED",
175
+ "SETUP_REQUIRED",
176
+ "SETUP_OPTIONAL"
177
+ ]),
178
+ challengeToken: z.string()
179
+ }).nullish()
180
+ })),
181
+ authenticatorVerify: (token, body) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/totp/verify`, {
182
+ method: "POST",
183
+ token,
184
+ json: body
185
+ }, z.object({
186
+ status: z.enum(["AUTHENTICATED", "MFA_REQUIRED"]),
187
+ session: z.object({
188
+ jwt: z.string(),
189
+ user: userSchema,
190
+ permissions: permissionsSchema
191
+ }).nullish(),
192
+ mfa: z.object({
193
+ action: z.enum([
194
+ "VERIFICATION_REQUIRED",
195
+ "SETUP_REQUIRED",
196
+ "SETUP_OPTIONAL"
197
+ ]),
198
+ challengeToken: z.string()
199
+ }).nullish()
200
+ })),
201
+ authenticatorSendResetCode: (token) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/reset/send-code`, {
202
+ method: "POST",
203
+ token
204
+ }, z.null()),
205
+ authenticatorReset: (token, code) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/reset`, {
206
+ method: "POST",
207
+ token,
208
+ json: { code }
209
+ }, z.null()),
210
+ authenticatorRemove: (token, code) => request(`/v1/vibe/applications/${applicationId}/users/authenticator/remove`, {
211
+ method: "POST",
212
+ token,
213
+ json: { code }
214
+ }, z.null()),
37
215
  signOut: (token) => request(`/v1/applications/${applicationId}/users/sign-out`, {
38
216
  method: "POST",
39
217
  token
@@ -1,5 +1,9 @@
1
+ import { confirmAuthenticatorSetup, removeAuthenticator, resetAuthenticator, sendAuthenticatorResetCode, skipAuthenticatorSetup, startAuthenticatorSetup, verifyAuthenticator } from "./methods/authenticator.js";
2
+ import { sendSignInCode, signInWithCode } from "./methods/code.js";
3
+ import { signInWithMagicLink } from "./methods/magicLink.js";
1
4
  import { signIn, signOut } from "./methods/password.js";
2
5
  import { confirmSignUp, signUp } from "./methods/signup.js";
6
+ import { signInWithGoogle } from "./methods/social.js";
3
7
  import "@tanstack/react-start/server-only";
4
8
 
5
9
  //#region src/auth/server.d.ts
@@ -12,6 +16,17 @@ declare const auth: {
12
16
  signOut: typeof signOut;
13
17
  signUp: typeof signUp;
14
18
  confirmSignUp: typeof confirmSignUp;
19
+ sendSignInCode: typeof sendSignInCode;
20
+ signInWithCode: typeof signInWithCode;
21
+ signInWithGoogle: typeof signInWithGoogle;
22
+ signInWithMagicLink: typeof signInWithMagicLink;
23
+ startAuthenticatorSetup: typeof startAuthenticatorSetup;
24
+ confirmAuthenticatorSetup: typeof confirmAuthenticatorSetup;
25
+ skipAuthenticatorSetup: typeof skipAuthenticatorSetup;
26
+ verifyAuthenticator: typeof verifyAuthenticator;
27
+ sendAuthenticatorResetCode: typeof sendAuthenticatorResetCode;
28
+ resetAuthenticator: typeof resetAuthenticator;
29
+ removeAuthenticator: typeof removeAuthenticator;
15
30
  };
16
31
  //#endregion
17
32
  export { auth };
@@ -1,5 +1,9 @@
1
+ import { confirmAuthenticatorSetup, removeAuthenticator, resetAuthenticator, sendAuthenticatorResetCode, skipAuthenticatorSetup, startAuthenticatorSetup, verifyAuthenticator } from "./methods/authenticator.js";
2
+ import { sendSignInCode, signInWithCode } from "./methods/code.js";
3
+ import { signInWithMagicLink } from "./methods/magicLink.js";
1
4
  import { signIn, signOut } from "./methods/password.js";
2
5
  import { confirmSignUp, signUp } from "./methods/signup.js";
6
+ import { signInWithGoogle } from "./methods/social.js";
3
7
  import "@tanstack/react-start/server-only";
4
8
 
5
9
  //#region src/auth/server.ts
@@ -10,7 +14,18 @@ const auth = {
10
14
  signIn,
11
15
  signOut,
12
16
  signUp,
13
- confirmSignUp
17
+ confirmSignUp,
18
+ sendSignInCode,
19
+ signInWithCode,
20
+ signInWithGoogle,
21
+ signInWithMagicLink,
22
+ startAuthenticatorSetup,
23
+ confirmAuthenticatorSetup,
24
+ skipAuthenticatorSetup,
25
+ verifyAuthenticator,
26
+ sendAuthenticatorResetCode,
27
+ resetAuthenticator,
28
+ removeAuthenticator
14
29
  };
15
30
 
16
31
  //#endregion
@@ -9,8 +9,14 @@ import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:
9
9
  //#region src/auth/session.ts
10
10
  const SESSION_TOKEN = "session_token";
11
11
  const SESSION_DATA = "session_data";
12
+ const PENDING_AUTH = "pending_auth";
12
13
  const SESSION_DATA_TTL_SECONDS = 300;
13
14
  /**
15
+ * How long a visitor has to answer a second factor. The platform expires the
16
+ * challenge token itself. This only decides how long the browser carries it.
17
+ */
18
+ const PENDING_AUTH_TTL_SECONDS = 600;
19
+ /**
14
20
  * A browser refuses a `__Host-` cookie unless it is `Secure`, `Path=/` and free
15
21
  * of `Domain` — that last clause is the one worth having, since it stops a
16
22
  * sibling host planting a cookie of this name for us to honour.
@@ -67,10 +73,37 @@ function makeSessionDataCookie(session, sessionToken) {
67
73
  });
68
74
  }
69
75
  /**
76
+ * The challenge token from a sign-in that stopped at a second factor, or
77
+ * `null`.
78
+ *
79
+ * It is a bearer credential scoped to the authenticator endpoints, so it stays
80
+ * sealed in the jar the way a session token does, instead of passing through
81
+ * the app.
82
+ */
83
+ function readPendingAuthToken() {
84
+ const { name } = sessionCookie(PENDING_AUTH);
85
+ return openEnvelope(readRequestCookies()[name], PENDING_AUTH);
86
+ }
87
+ function makePendingAuthCookie(token) {
88
+ const { name, secure } = sessionCookie(PENDING_AUTH);
89
+ return serializeCookie(name, sealEnvelope(token, PENDING_AUTH), {
90
+ maxAge: PENDING_AUTH_TTL_SECONDS,
91
+ secure
92
+ });
93
+ }
94
+ /** Drops an outstanding challenge without touching the session. */
95
+ function clearPendingAuth() {
96
+ clearCookies([PENDING_AUTH]);
97
+ }
98
+ /**
70
99
  * Writes rather than returns: a forgotten list would leave the session live.
71
100
  */
72
101
  function clearSession() {
73
- clearCookies([SESSION_TOKEN, SESSION_DATA]);
102
+ clearCookies([
103
+ SESSION_TOKEN,
104
+ SESSION_DATA,
105
+ PENDING_AUTH
106
+ ]);
74
107
  }
75
108
  const sessionDataSchema = z.object({
76
109
  user: userSchema.nullable(),
@@ -163,4 +196,4 @@ function openEnvelope(raw, purpose) {
163
196
  }
164
197
 
165
198
  //#endregion
166
- export { clearSession, makeSessionDataCookie, makeSessionTokenCookie, readSessionData, readSessionToken };
199
+ export { clearPendingAuth, clearSession, makePendingAuthCookie, makeSessionDataCookie, makeSessionTokenCookie, readPendingAuthToken, readSessionData, readSessionToken };
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { version } from "./package.js";
3
+ import { fetchSoftrEnvInput, metadataSourceFromEnv } from "./codegen/fetch-metadata.js";
4
+ import { renderSoftrEnv } from "./codegen/softr-env.js";
5
+ import { writeFileSync } from "node:fs";
6
+ import path from "node:path";
7
+
8
+ //#region src/cli.ts
9
+ const OUTPUT = "softr-env.d.ts";
10
+ async function generate() {
11
+ writeFileSync(path.resolve(process.cwd(), OUTPUT), renderSoftrEnv(await fetchSoftrEnvInput(metadataSourceFromEnv()), version), "utf8");
12
+ console.log(`[softr] wrote ${OUTPUT}`);
13
+ }
14
+ const [command] = process.argv.slice(2);
15
+ if (command === "generate") await generate();
16
+ else {
17
+ console.error(command ? `softr-sdk: unknown command '${command}'` : "softr-sdk: no command given");
18
+ console.error("usage: softr-sdk generate");
19
+ process.exit(1);
20
+ }
21
+
22
+ //#endregion
23
+ export { };