@protobase/server 0.48.0 → 0.49.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 (69) hide show
  1. package/dist/admin-options.d.ts +2 -2
  2. package/dist/app-identity.d.ts +2 -2
  3. package/dist/app-name.d.ts +2 -0
  4. package/dist/better-auth/auth-settings.d.ts +8754 -0
  5. package/dist/better-auth/auth-settings.js +43 -0
  6. package/dist/better-auth/authenticate-settings.d.ts +15 -0
  7. package/dist/better-auth/authenticate-settings.js +12 -0
  8. package/dist/better-auth/create-auth.d.ts +23 -11
  9. package/dist/better-auth/create-auth.js +21 -9
  10. package/dist/better-auth/mcp/mcp-auth-plugins.d.ts +2719 -0
  11. package/dist/better-auth/mcp/mcp-auth-plugins.js +68 -0
  12. package/dist/better-auth/mcp/mcp-plugins.d.ts +7 -2
  13. package/dist/better-auth/mcp/mcp-plugins.js +3 -68
  14. package/dist/better-auth/mcp/mcp-token-claims.js +1 -1
  15. package/dist/better-auth/organizations/store.d.ts +1 -0
  16. package/dist/better-auth/saml-plugin.d.ts +993 -0
  17. package/dist/better-auth/saml-plugin.js +36 -0
  18. package/dist/better-auth/saml-sign-in.d.ts +27 -1
  19. package/dist/better-auth/saml-sign-in.js +1 -33
  20. package/dist/better-auth/user-table.js +1 -1
  21. package/dist/better-auth/users.d.ts +1 -1
  22. package/dist/create-admin.d.ts +5 -3
  23. package/dist/create-admin.js +3 -1
  24. package/dist/encryption/keyring.js +1 -1
  25. package/dist/files/options.d.ts +5 -8
  26. package/dist/files/provider-settings.d.ts +16 -0
  27. package/dist/files/provider-settings.js +17 -0
  28. package/dist/files/runtime.js +4 -4
  29. package/dist/forms/runtime.js +3 -3
  30. package/dist/index.d.ts +16 -15
  31. package/dist/index.js +8 -10
  32. package/dist/internal.d.ts +13 -0
  33. package/dist/internal.js +13 -0
  34. package/dist/jobs/declared-job.d.ts +24 -0
  35. package/dist/jobs/declared-job.js +26 -0
  36. package/dist/jobs/job-types.d.ts +1 -1
  37. package/dist/mcp/mcp-authenticator.js +3 -3
  38. package/dist/notifications/device-store-of.d.ts +1 -1
  39. package/dist/notifications/device-store-of.js +1 -1
  40. package/dist/notifications/device-store.d.ts +1 -1
  41. package/dist/notifications/device-store.js +1 -1
  42. package/dist/notifications/history-store-of.d.ts +1 -1
  43. package/dist/notifications/history-store-of.js +1 -1
  44. package/dist/notifications/history-store.d.ts +1 -1
  45. package/dist/notifications/history-store.js +1 -1
  46. package/dist/notifications/options.d.ts +3 -1
  47. package/dist/notifications/options.js +1 -1
  48. package/dist/notifications/schema.d.ts +2 -2
  49. package/dist/notifications/schema.js +7 -7
  50. package/dist/notifications/send-notification.js +1 -1
  51. package/dist/notifications/sender.d.ts +1 -1
  52. package/dist/notifications/sender.js +2 -2
  53. package/dist/notifications/senders-of.d.ts +1 -1
  54. package/dist/notifications/senders-of.js +1 -1
  55. package/dist/package.js +1 -1
  56. package/dist/webhooks/subscription.d.ts +1 -0
  57. package/dist/webhooks/table/options.d.ts +1 -1
  58. package/dist/webhooks/table/schema.d.ts +2 -2
  59. package/dist/webhooks/table/schema.js +2 -2
  60. package/dist/webhooks/table/webhook-table.js +2 -2
  61. package/dist/webhooks/table/webhooks-module.d.ts +108 -0
  62. package/dist/webhooks/table/webhooks-module.js +11 -0
  63. package/package.json +6 -5
  64. package/dist/notifications/plugin.d.ts +0 -13
  65. package/dist/notifications/plugin.js +0 -16
  66. package/dist/project-config.d.ts +0 -54
  67. package/dist/project-config.js +0 -182
  68. package/dist/webhooks/table/plugin.d.ts +0 -10
  69. package/dist/webhooks/table/plugin.js +0 -18
@@ -0,0 +1,36 @@
1
+ import { samlEntityId } from "./saml-sign-in.js";
2
+ import { sso } from "@better-auth/sso";
3
+ //#region src/better-auth/saml-plugin.ts
4
+ /** The provider as one of the SSO plugin's configured providers (`defaultSSO`). */
5
+ const defaultSsoEntry = (provider, baseURL) => {
6
+ const { idp, attributes = {} } = provider;
7
+ const mapping = Object.fromEntries(Object.entries(attributes).filter(([, name]) => name !== void 0));
8
+ return {
9
+ providerId: provider.id,
10
+ domain: provider.domains.join(","),
11
+ samlConfig: {
12
+ issuer: samlEntityId(baseURL, provider.id),
13
+ entryPoint: "ssoUrl" in idp ? idp.ssoUrl : "",
14
+ idpMetadata: "metadata" in idp ? { metadata: idp.metadata } : {
15
+ entityID: idp.entityId,
16
+ cert: idp.certificate
17
+ },
18
+ ...Object.keys(mapping).length > 0 && { mapping }
19
+ }
20
+ };
21
+ };
22
+ /**
23
+ * Better Auth's SSO plugin with the configured providers. Their domains are trusted, so an address there links to the
24
+ * account that has it; organizations are not assigned by provider, and nobody registers providers.
25
+ */
26
+ const samlPlugin = (providers, baseURL) => {
27
+ const { schema: _schema, ...plugin } = sso({
28
+ defaultSSO: providers.map((provider) => defaultSsoEntry(provider, baseURL)),
29
+ domainVerification: { enabled: true },
30
+ organizationProvisioning: { disabled: true },
31
+ providersLimit: 0
32
+ });
33
+ return plugin;
34
+ };
35
+ //#endregion
36
+ export { defaultSsoEntry, samlPlugin };
@@ -1,4 +1,3 @@
1
- import "@better-auth/sso";
2
1
  //#region src/better-auth/saml-sign-in.d.ts
3
2
  /**
4
3
  * A SAML 2.0 identity provider people of the app sign in with, for example the company's Okta, Entra ID or Google
@@ -34,4 +33,31 @@ export type SamlProvider = {
34
33
  export type SsoOptions = {
35
34
  saml: SamlProvider[];
36
35
  };
36
+ /**
37
+ * The providers with their defaults filled in: the name `SSO`, and the domains trimmed and lowercased. A malformed id,
38
+ * an id used twice or by another sign-in provider (`takenIds`), no domains or a domain that is not a host name, and IdP
39
+ * settings that are missing or not a URL are errors.
40
+ */
41
+ export declare const resolveSamlProviders: (saml: SamlProvider[], takenIds: string[]) => {
42
+ name: string;
43
+ domains: string[];
44
+ /** The id: the button's `?sign-in=` link, the provider's paths and the namespace of its accounts. Lowercase letters, digits or "-". */
45
+ id: string;
46
+ /** The provider's metadata XML, or its entity ID, sign-in URL and signing certificate(s) (PEM; several while one rotates). */
47
+ idp: {
48
+ metadata: string;
49
+ } | {
50
+ entityId: string;
51
+ ssoUrl: string;
52
+ certificate: string | string[];
53
+ };
54
+ /** The assertion's attribute names, when they are not `email`, `givenName`, `surname` and `displayName`. */
55
+ attributes?: {
56
+ email?: string;
57
+ name?: string;
58
+ firstName?: string;
59
+ lastName?: string;
60
+ };
61
+ }[];
62
+ export type ResolvedSamlProvider = ReturnType<typeof resolveSamlProviders>[number];
37
63
  //#endregion
@@ -1,7 +1,6 @@
1
1
  import { authBasePath } from "./auth-base-path.js";
2
2
  import { providerIdPattern } from "./platform-sign-in.js";
3
3
  import { APIError, createAuthMiddleware } from "better-auth/api";
4
- import { sso } from "@better-auth/sso";
5
4
  //#region src/better-auth/saml-sign-in.ts
6
5
  const domainPattern = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
7
6
  const checkIdp = (id, idp) => {
@@ -37,37 +36,6 @@ const resolveSamlProviders = (saml, takenIds) => {
37
36
  };
38
37
  /** The app's SP entity ID for a provider: its metadata URL on `baseURL`, the same on every origin. */
39
38
  const samlEntityId = (baseURL, id) => `${baseURL.replace(/\/$/, "")}${authBasePath}/sso/saml2/sp/metadata?providerId=${encodeURIComponent(id)}`;
40
- /** The provider as one of the SSO plugin's configured providers (`defaultSSO`). */
41
- const defaultSsoEntry = (provider, baseURL) => {
42
- const { idp, attributes = {} } = provider;
43
- const mapping = Object.fromEntries(Object.entries(attributes).filter(([, name]) => name !== void 0));
44
- return {
45
- providerId: provider.id,
46
- domain: provider.domains.join(","),
47
- samlConfig: {
48
- issuer: samlEntityId(baseURL, provider.id),
49
- entryPoint: "ssoUrl" in idp ? idp.ssoUrl : "",
50
- idpMetadata: "metadata" in idp ? { metadata: idp.metadata } : {
51
- entityID: idp.entityId,
52
- cert: idp.certificate
53
- },
54
- ...Object.keys(mapping).length > 0 && { mapping }
55
- }
56
- };
57
- };
58
- /**
59
- * Better Auth's SSO plugin with the configured providers. Their domains are trusted, so an address there links to the
60
- * account that has it; organizations are not assigned by provider, and nobody registers providers.
61
- */
62
- const samlPlugin = (providers, baseURL) => {
63
- const { schema: _schema, ...plugin } = sso({
64
- defaultSSO: providers.map((provider) => defaultSsoEntry(provider, baseURL)),
65
- domainVerification: { enabled: true },
66
- organizationProvisioning: { disabled: true },
67
- providersLimit: 0
68
- });
69
- return plugin;
70
- };
71
39
  /** The SSO plugin's endpoints for providers kept in its table, and its OIDC callback, which Protobase does not serve. */
72
40
  const samlDisabledPaths = [
73
41
  "/sso/register",
@@ -130,4 +98,4 @@ const emailInDomains = (email, domains) => {
130
98
  return domains.some((allowed) => domain === allowed || domain.endsWith(`.${allowed}`));
131
99
  };
132
100
  //#endregion
133
- export { defaultSsoEntry, emailInDomains, isSamlPath, resolveSamlProviders, samlDisabledPaths, samlEntityId, samlGuardPlugin, samlPlugin, samlRefusal };
101
+ export { emailInDomains, isSamlPath, resolveSamlProviders, samlDisabledPaths, samlEntityId, samlGuardPlugin, samlRefusal };
@@ -16,7 +16,7 @@ const userFields = {
16
16
  last_role: "lastRole",
17
17
  last_organization_id: "lastOrganizationId"
18
18
  };
19
- /** The user table's names, from `createAuth`'s `users` option; unknown columns are an error. */
19
+ /** The user table's names, from `auth.users` option; unknown columns are an error. */
20
20
  const userTable = ({ table = "user", columns = {}, metadata } = {}) => {
21
21
  const unknown = Object.keys(columns).find((name) => !(name in userFields));
22
22
  if (unknown !== void 0) throw new Error(`users.columns names "${unknown}", which is not a column of the user table: ${Object.keys(userFields).join(", ")}`);
@@ -10,7 +10,7 @@ export type LinkedAccount = {
10
10
  };
11
11
  /**
12
12
  * Without `password` the user signs in by emailed code, passkey or a sign-in provider only. `metadata` lands in the
13
- * user metadata column, which `createAuth`'s `users.metadata` names; it needs one.
13
+ * user metadata column, which `auth.users.metadata` names; it needs one.
14
14
  */
15
15
  export type NewUser = {
16
16
  email: string;
@@ -35,6 +35,8 @@ export type CreateAdminInput = {
35
35
  auth?: AdminAuth;
36
36
  /** API functions of the app's own, each served at `<systemPath>/functions/<name>` (see `defineFunction`). */
37
37
  functions?: Record<string, FunctionSource>;
38
+ /** The app's secret (`secret`): it signs public forms' bot checks, and upload tickets unless `files.secret` names another. */
39
+ secret?: string;
38
40
  /** Where file fields keep their bytes (see `FilesOptions`). */
39
41
  files?: FilesOptions;
40
42
  /** Where the changes that resources' events are raised from are captured (see `EventsOptions`). */
@@ -45,9 +47,9 @@ export type CreateAdminInput = {
45
47
  jobs?: JobDefinition[];
46
48
  /** Where the resources' events are delivered (`subscription(...)` exports of the config module). */
47
49
  subscriptions?: SubscriptionDefinition[];
48
- /** Webhook subscriptions made in the admin app, from `extends: [webhooks()]` (see `WebhooksOptions`). */
50
+ /** Webhook subscriptions made in the admin app, from `webhooks: {}` (see `WebhooksOptions`). */
49
51
  webhooks?: WebhooksOptions;
50
- /** Each user's devices and the endpoints that register them, from `extends: [notifications()]` (see `NotificationsOptions`). */
52
+ /** Each user's devices and the endpoints that register them, from `notifications: {}` (see `NotificationsOptions`). */
51
53
  notifications?: NotificationsOptions;
52
54
  /**
53
55
  * The app's iOS and Android build (see `MobileConfig`): the API answers its Capacitor origins through CORS, and sign-in
@@ -88,5 +90,5 @@ export type CreateAdminInput = {
88
90
  upgradeWebSocket?: UpgradeWebSocket;
89
91
  };
90
92
  /** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
91
- export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
93
+ export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, secret, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
92
94
  //#endregion
@@ -103,7 +103,7 @@ const declaredRoles = (auth, roles) => {
103
103
  return names.length > 0 ? [...new Set(names)] : void 0;
104
104
  };
105
105
  /** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
106
- const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
106
+ const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, secret, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
107
107
  const basePath = options.basePath ?? "/api/v1";
108
108
  const appModels = appResources.map((resource) => resource.toModel());
109
109
  const withComments = appModels.some((model) => model.comments);
@@ -154,6 +154,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
154
154
  views: viewModels,
155
155
  limits: options.roles?.limits ?? [],
156
156
  env: globalThis.process?.env ?? {},
157
+ ...secret && { secret },
157
158
  ...formsDifficulty && { difficulty: formsDifficulty }
158
159
  });
159
160
  const systemPath = basePath.slice(0, basePath.lastIndexOf("/"));
@@ -178,6 +179,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
178
179
  });
179
180
  const files = createFilesRuntime({
180
181
  ...filesOptions && { options: filesOptions },
182
+ ...secret && { secret },
181
183
  env: globalThis.process?.env ?? {},
182
184
  models: registry.entries.map((entry) => entry.model),
183
185
  systemPath,
@@ -27,7 +27,7 @@ const entriesOf = (env) => {
27
27
  }))];
28
28
  };
29
29
  const checkApart = (entries, env) => {
30
- for (const name of ["BETTER_AUTH_SECRET", "PROTOBASE_SECRET_KEY"]) {
30
+ for (const name of ["PROTOBASE_SECRET", "PROTOBASE_SECRET_KEY"]) {
31
31
  const secret = env[name]?.trim();
32
32
  const same = secret && entries.find((entry) => entry.text === secret);
33
33
  if (same) throw new Error(`${same.where} is the same as ${name}: give encryption a key of its own`);
@@ -1,21 +1,18 @@
1
1
  import { Sharp } from "./images.js";
2
2
  import { FileProvider } from "./store.js";
3
3
  //#region src/files/options.d.ts
4
- /** `files` in `protobase.config.ts`. Environment variables override it (see `resolveProviders`). */
4
+ /** Where file fields keep their bytes, as the API runs with them: `files` of `protobase.config.ts` with its providers made. Environment variables override it (see `resolveProviders`). */
5
5
  export type FilesOptions = {
6
6
  /**
7
- * Providers by name, such as `private: localFiles({ dir: './data/files' })`. A name is part of every stored value, so
8
- * name the role (`archive`), not the vendor. Without config, `private` and `public` are folders under `data/files`.
7
+ * Providers by name. A name is part of every stored value, so name the role (`archive`), not the vendor. Without
8
+ * config, `private` and `public` are folders under `data/files`.
9
9
  */
10
10
  providers?: Record<string, FileProvider>;
11
11
  /** How long bytes outlive their last reference, for restores; default `1 day`. Public providers default to 0. */
12
12
  retention?: number | string;
13
- /** Signs upload tickets and download URLs; default `PROTOBASE_FILES_SECRET`, then `BETTER_AUTH_SECRET`. */
13
+ /** Signs upload tickets and download URLs; default `PROTOBASE_FILES_SECRET`, then the app's `secret` (`PROTOBASE_SECRET`). */
14
14
  secret?: string;
15
- /**
16
- * The image library that makes the variants and placeholders of image fields: `import sharp from 'sharp'` in the
17
- * config, so a built bundle carries it with its native add-on.
18
- */
15
+ /** The image library that makes the variants and placeholders of image fields: sharp's default export. */
19
16
  sharp?: Sharp;
20
17
  /**
21
18
  * Hosts whose images the admin app draws with the page's referrer, besides the app's own and those its providers link
@@ -0,0 +1,16 @@
1
+ import { FileProvider } from "./store.js";
2
+ import { LocalFilesOptions } from "./local-files.js";
3
+ import { S3FilesOptions } from "./s3-files.js";
4
+ //#region src/files/provider-settings.d.ts
5
+ /**
6
+ * A built-in file provider in `files.providers`, as data: `{ kind: 'local', dir }`, a folder on local disk, or
7
+ * `{ kind: 's3', bucket }`, an S3-compatible bucket. The provider is made when the app serves.
8
+ */
9
+ export type FileProviderSettings = ({
10
+ kind: 'local';
11
+ } & LocalFilesOptions) | ({
12
+ kind: 's3';
13
+ } & S3FilesOptions);
14
+ /** The provider the settings describe. */
15
+ export declare const fileProviderOf: (name: string, settings: FileProviderSettings) => FileProvider;
16
+ //#endregion
@@ -0,0 +1,17 @@
1
+ import { localFiles } from "./local-files.js";
2
+ import { s3Files } from "./s3-files.js";
3
+ //#region src/files/provider-settings.ts
4
+ /** The provider the settings describe. */
5
+ const fileProviderOf = (name, settings) => {
6
+ if (settings.kind === "local") {
7
+ const { kind: _, ...options } = settings;
8
+ return localFiles(options);
9
+ }
10
+ if (settings.kind === "s3") {
11
+ const { kind: _, ...options } = settings;
12
+ return s3Files(options);
13
+ }
14
+ throw new Error(`files.providers.${name}: kind is "local", "s3" or "custom", whose provider is the default export of files/${name}.ts`);
15
+ };
16
+ //#endregion
17
+ export { fileProviderOf };
@@ -13,7 +13,7 @@ const imageFields = (models) => models.flatMap((model) => Object.values(model.fi
13
13
  * The runtime, when a resource has a file field, the config names providers or the app serves `/api/sb/storage/v1`. It fails at startup when a field's
14
14
  * provider is not configured, nothing signs uploads, or a field makes image variants or placeholders without sharp.
15
15
  */
16
- const createFilesRuntime = ({ options = {}, env, models, systemPath, storage: servesStorage = false }) => {
16
+ const createFilesRuntime = ({ options = {}, env, secret: appSecret, models, systemPath, storage: servesStorage = false }) => {
17
17
  const storageName = servesStorage ? storageProviderName(options) : void 0;
18
18
  const storage = storageName && options.storage !== false ? {
19
19
  provider: storageName,
@@ -22,10 +22,10 @@ const createFilesRuntime = ({ options = {}, env, models, systemPath, storage: se
22
22
  const fieldProviders = models.flatMap((model) => Object.values(model.fields).flatMap((field) => field.file ? [field.file.provider] : []));
23
23
  const used = [.../* @__PURE__ */ new Set([...fieldProviders, ...storage ? [storage.provider] : []])];
24
24
  if (used.length === 0 && !options.providers) return void 0;
25
- const secret = options.secret ?? env.PROTOBASE_FILES_SECRET ?? env.BETTER_AUTH_SECRET;
26
- if (!secret) throw new Error("File fields and /api/sb/storage/v1 need a secret to sign uploads: set BETTER_AUTH_SECRET, PROTOBASE_FILES_SECRET or files.secret");
25
+ const secret = options.secret ?? env.PROTOBASE_FILES_SECRET ?? appSecret ?? env.PROTOBASE_SECRET;
26
+ if (!secret) throw new Error("File fields and /api/sb/storage/v1 need a secret to sign uploads: set secret in protobase.config.ts, files.secret or PROTOBASE_FILES_SECRET");
27
27
  const images = imageFields(models);
28
- if (images.length > 0 && !options.sharp) throw new Error(`${images.join(", ")} make image variants or placeholders, which need sharp: add it to the project (bun add sharp), then import sharp from 'sharp' in the config and pass files: { sharp }`);
28
+ if (images.length > 0 && !options.sharp) throw new Error(`${images.join(", ")} make image variants or placeholders, which need sharp: add it to the project (bun add sharp), then give the config files: { sharp: () => import('sharp') }`);
29
29
  const providers = resolveProviders(options, env, used);
30
30
  const retention = retentionOf(options, env);
31
31
  return {
@@ -12,15 +12,15 @@ const anonymousCreates = (limits) => (resource) => {
12
12
  * The public forms of the views, checked, with the challenges that guard them and their rate limit; `undefined` without
13
13
  * any. Fails at startup on a form that cannot be served and when nothing signs the challenges.
14
14
  */
15
- const createFormsRuntime = ({ registry, views, limits, env, difficulty }) => {
15
+ const createFormsRuntime = ({ registry, views, limits, env, secret: appSecret, difficulty }) => {
16
16
  const declared = [...views].sort((a, b) => Number(a.roles !== void 0) - Number(b.roles !== void 0)).flatMap((view) => (view.forms ?? []).map((form) => ({
17
17
  form,
18
18
  view
19
19
  })));
20
20
  if (declared.length === 0) return void 0;
21
21
  const forms = checkForms(registry, declared, anonymousCreates(limits));
22
- const secret = env.PROTOBASE_FORMS_SECRET ?? env.BETTER_AUTH_SECRET;
23
- if (!secret) throw new Error("Public forms need a secret to sign their bot checks: set PROTOBASE_FORMS_SECRET or BETTER_AUTH_SECRET");
22
+ const secret = env.PROTOBASE_FORMS_SECRET ?? appSecret ?? env.PROTOBASE_SECRET;
23
+ if (!secret) throw new Error("Public forms need a secret to sign their bot checks: set secret in protobase.config.ts, or PROTOBASE_FORMS_SECRET");
24
24
  return {
25
25
  forms,
26
26
  challenges: createFormChallenges(secret, { ...difficulty && { difficulty } }),
package/dist/index.d.ts CHANGED
@@ -51,20 +51,25 @@ import { RuntimeOptions, runtimeUrl, runtimeVariable, seesRuntime } from "./runt
51
51
  import { AdminOptions } from "./admin-options.js";
52
52
  import { CreateAdminInput, createAdmin } from "./create-admin.js";
53
53
  import { handleDroppedConnections } from "./dropped-connections.js";
54
- import { AppPoolConfig, PgModule, appPool, longQueryPool, poolWaitMs, readDbConnections } from "./app-pool.js";
54
+ import { AppPoolConfig, PgModule, poolWaitMs, readDbConnections } from "./app-pool.js";
55
55
  import { ConnectionsBusy } from "./connections-busy.js";
56
56
  import { isBackgroundWork, runInBackground, wantsLongQueries } from "./background-work.js";
57
57
  import { longQueryTimeoutMs } from "./statement-timeout.js";
58
58
  import { checkViewQueries } from "./check-view-queries.js";
59
- import { ProjectConfig, defineConfig, mergeConfig } from "./project-config.js";
60
59
  import { consoleAuditQueue } from "./audit/console-queue.js";
61
60
  import { JwtOptions, JwtVerifyOptions, jwtAuthenticator, jwtVerifier } from "./auth/jwt.js";
61
+ import { SignInPolicy, SignInRule, StaffAccessRule, defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
62
+ import { StaffSignIn } from "./better-auth/staff-log.js";
63
+ import { RoleDefinition, RolesInput } from "./better-auth/organizations/role-definitions.js";
64
+ import { OrganizationRole, StoredMember, StoredOrganization } from "./better-auth/organizations/store.js";
65
+ import { OrganizationsOptions } from "./better-auth/organizations/options.js";
66
+ import { AuthHooks, AuthSettings, HookContext } from "./better-auth/auth-settings.js";
62
67
  import { TrustedApp, withTrustedApps } from "./better-auth/app-tokens.js";
63
- import { BetterAuthAuthenticator, BetterAuthAuthenticatorOptions, betterAuthAuthenticator, betterAuthTokens } from "./better-auth/authenticator.js";
68
+ import { BetterAuthAuthenticator, BetterAuthAuthenticatorOptions, betterAuthTokens } from "./better-auth/authenticator.js";
69
+ import { AuthenticateSettings } from "./better-auth/authenticate-settings.js";
64
70
  import { parseRoles } from "./better-auth/parse-roles.js";
65
71
  import { LinkedAccount, NewUser, StoredUser, createUser, deleteUser, hasUsers, listUsers, roleChoices, setUserBanned, setUserRole } from "./better-auth/users.js";
66
72
  import { IssueTokenOptions, issueToken, maxTokenTtlSeconds } from "./better-auth/tokens.js";
67
- import { SignInPolicy, SignInRule, StaffAccessRule, defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
68
73
  import { passwordLength } from "./better-auth/new-account-password.js";
69
74
  import { OperatorProvider, readOperatorSettings } from "./better-auth/operator-provider.js";
70
75
  import { isOAuthWellKnownPath, oauthWellKnownPaths, webauthnPath } from "./better-auth/origins.js";
@@ -72,7 +77,7 @@ import { goTruePath } from "./gotrue/keys.js";
72
77
  import { supabasePath } from "./supabase-paths.js";
73
78
  import { realtimeLimits } from "./realtime/realtime-limits.js";
74
79
  import { capSocketMessages, honorSocketMessageCaps, socketMessageCapOf } from "./functions/socket-message-cap.js";
75
- import { defaultAppName, shownAppName } from "./app-name.js";
80
+ import { appNameOver, defaultAppName, shownAppName } from "./app-name.js";
76
81
  import { webManifestPath } from "./web-app/web-manifest-route.js";
77
82
  import { PlatformSignIn, readPlatformSignIn } from "./better-auth/platform-sign-in.js";
78
83
  import { authSchemaMigration, checkAuthSchema } from "./better-auth/auth-schema.js";
@@ -86,12 +91,10 @@ import { ResourceChange, recordOf, resourceChange } from "./changes/resource-cha
86
91
  import { eventMatcher } from "./changes/match-events.js";
87
92
  import { parseColumns, readOutbox } from "./changes/outbox.js";
88
93
  import { newWebhookSecret } from "./webhooks/standard-webhooks.js";
89
- import { webhooks } from "./webhooks/table/plugin.js";
90
94
  import { checkWebhooksSchema, webhooksMigration } from "./webhooks/table/schema.js";
91
95
  import { checkComments, commentsMigration } from "./comments/comments-sql.js";
92
96
  import { CheckAiInput, checkAi } from "./ai/check-ai.js";
93
97
  import { CommentItem } from "./comments/comment-item.js";
94
- import { notifications } from "./notifications/plugin.js";
95
98
  import { checkNotificationsSchema, notificationsMigration } from "./notifications/schema.js";
96
99
  import { deviceStore, removeDevicesWithUsers } from "./notifications/device-store-of.js";
97
100
  import { DeviceStoreError, postgresDeviceStore } from "./notifications/postgres-store.js";
@@ -105,11 +108,7 @@ import { sendNotification } from "./notifications/send-notification.js";
105
108
  import { VapidSettings, readVapidSettings, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable } from "./notifications/web-push/vapid-settings.js";
106
109
  import { WebPushOptions, webPushSender } from "./notifications/web-push/web-push-sender.js";
107
110
  import { generateVapidKeys } from "./notifications/web-push/keys.js";
108
- import { RoleDefinition, RolesInput } from "./better-auth/organizations/role-definitions.js";
109
- import { OrganizationRole, StoredMember, StoredOrganization } from "./better-auth/organizations/store.js";
110
- import { OrganizationsOptions } from "./better-auth/organizations/options.js";
111
111
  import { MemberInput, NewOrganization, addAppRoleToOwners, addMember, createOrganization, listOrganizations, removeMember, setMemberRoles } from "./better-auth/organizations/host.js";
112
- import { StaffSignIn } from "./better-auth/staff-log.js";
113
112
  import { AssistantBackend, assistantProtocolRoutes } from "./assistant/protocol-routes.js";
114
113
  import { fileConversationStore } from "./assistant/file-conversation-store.js";
115
114
  import { withCacheBreakpoints } from "./assistant/cache-breakpoints.js";
@@ -139,9 +138,10 @@ import { SignatureOptions, StandardWebhookOptions, verifySignature, verifyStanda
139
138
  import { requireEnv } from "./functions/require-env.js";
140
139
  import { backgroundSettled, waitUntil } from "./functions/wait-until.js";
141
140
  import { FileLimits, limitedFileStore, storeUsage } from "./files/limits.js";
142
- import { LocalFilesOptions, localFileStore, localFiles } from "./files/local-files.js";
141
+ import { LocalFilesOptions, localFileStore } from "./files/local-files.js";
142
+ import { S3Bucket, S3FilesOptions, S3ListPage, S3Object, s3FileStore } from "./files/s3-files.js";
143
+ import { FileProviderSettings } from "./files/provider-settings.js";
143
144
  import { StoreFileInput, storeFile } from "./files/store-file.js";
144
- import { S3Bucket, S3FilesOptions, S3ListPage, S3Object, s3FileStore, s3Files } from "./files/s3-files.js";
145
145
  import { storageProvider } from "./files/storage-provider.js";
146
146
  import { objectKey } from "./storage/object-key.js";
147
147
  import { FileCleanupInput, createFileCleanup } from "./files/file-cleanup.js";
@@ -154,6 +154,7 @@ import { FileRef, formatUri, variantPath } from "./files/uri.js";
154
154
  import { aspectRatio, fileSize, fileType, imageSize, processor } from "./files/processors.js";
155
155
  import { defineJob, isJobDefinition, jobDefinitions } from "./jobs/define-job.js";
156
156
  import { FatalJobError } from "./jobs/run-job.js";
157
+ import { JobDeclaration, JobRun, enqueueJob } from "./jobs/declared-job.js";
157
158
  import { isSchedule } from "./jobs/schedule.js";
158
159
  import { EmailComponent, EmailOptions, EmailTemplate, RenderedEmail, defineEmail } from "./mail/define-email.js";
159
160
  import { DrainResult, JobsRuntime, StartJobsOptions, startJobs } from "./jobs/runtime.js";
@@ -162,5 +163,5 @@ import { checkJobsSchema, jobsSchema, jobsSchemaMigration } from "./jobs/schema.
162
163
  import { MobileRelease, ReleaseFile, ServedReleaseFile, composeRelease, releaseManifest } from "./mobile-release/release.js";
163
164
  import { MobileReleaseAppInput, OfferedRelease, mobileReleaseApp } from "./mobile-release/release-app.js";
164
165
  import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
165
- import { AdminAuth, CreateAuthOptions, UserCreatedHook, createAuth, normalizeRoles } from "./better-auth/create-auth.js";
166
- export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApnsEnvironment, type AppIcons, type AppIdentity, type AppPoolConfig, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, ConnectionsBusy, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type Device, type DeviceColumn, type DeviceKind, type DeviceStore, DeviceStoreError, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryColumn, type HistoryOptions, type HistoryPosition, type HistoryStore, HistoryStoreError, HttpProblem, type IssueTokenOptions, type JobContext, type JobDefinition, type JobOptions, type JobsRuntime, type JsonObject, type JsonValue, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpApprovals, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, type Membership, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PgModule, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProjectConfig, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type PushAnswer, type PushMessage, PushMessageError, type PushSender, type QueryOptions, type QueryResult, type ReadableResources, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type SendNotification, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredNotification, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type Urgency, type User, type UserCreatedHook, type VapidSettings, type ViewSource, type WebPushFields, type WebPushOptions, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appPool, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, localFiles, longQueryPool, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, mergeConfig, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notifications, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
166
+ import { AdminAuth, CreateAuthOptions, UserCreatedHook, normalizeRoles } from "./better-auth/create-auth.js";
167
+ export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApnsEnvironment, type AppIcons, type AppIdentity, type AppPoolConfig, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type AuthHooks, type AuthSettings, type AuthenticateSettings, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, ConnectionsBusy, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type Device, type DeviceColumn, type DeviceKind, type DeviceStore, DeviceStoreError, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileProviderSettings, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryColumn, type HistoryOptions, type HistoryPosition, type HistoryStore, HistoryStoreError, type HookContext, HttpProblem, type IssueTokenOptions, type JobContext, type JobDeclaration, type JobDefinition, type JobOptions, type JobRun, type JobsRuntime, type JsonObject, type JsonValue, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpApprovals, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, type Membership, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PgModule, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type PushAnswer, type PushMessage, PushMessageError, type PushSender, type QueryOptions, type QueryResult, type ReadableResources, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type SendNotification, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredNotification, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type Urgency, type User, type UserCreatedHook, type VapidSettings, type ViewSource, type WebPushFields, type WebPushOptions, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, enqueueJob, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import { apiKeyCaller } from "./api-keys/resolve-caller.js";
26
26
  import { jwtAuthenticator, jwtVerifier } from "./auth/jwt.js";
27
27
  import { realtimeLimits } from "./realtime/realtime-limits.js";
28
28
  import { objectKey } from "./storage/object-key.js";
29
- import { defaultAppName, shownAppName } from "./app-name.js";
29
+ import { appNameOver, defaultAppName, shownAppName } from "./app-name.js";
30
30
  import { supabasePath } from "./supabase-paths.js";
31
31
  import { goTruePath } from "./gotrue/keys.js";
32
32
  import { defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
@@ -34,7 +34,7 @@ import { parseRoles } from "./better-auth/parse-roles.js";
34
34
  import { passwordLength } from "./better-auth/new-account-password.js";
35
35
  import { readOperatorSettings } from "./better-auth/operator-provider.js";
36
36
  import { readPlatformSignIn } from "./better-auth/platform-sign-in.js";
37
- import { createAuth, normalizeRoles } from "./better-auth/create-auth.js";
37
+ import { normalizeRoles } from "./better-auth/create-auth.js";
38
38
  import { mcpApprovals } from "./mcp/mcp-approval-store.js";
39
39
  import { mcpToolContext } from "./mcp/mcp-context.js";
40
40
  import { mcpGate, sessionOf } from "./mcp/mcp-gate.js";
@@ -75,8 +75,8 @@ import { NotificationSendError, maxMessageBytes, maxRecipients } from "./notific
75
75
  import { errorReportingSettings, errorReportingVariable } from "./error-reporting/error-reporting-settings.js";
76
76
  import { storageCleanupSchedule } from "./files/cleanup-schedule.js";
77
77
  import { limitedFileStore, storeUsage } from "./files/limits.js";
78
- import { localFileStore, localFiles } from "./files/local-files.js";
79
- import { s3FileStore, s3Files } from "./files/s3-files.js";
78
+ import { localFileStore } from "./files/local-files.js";
79
+ import { s3FileStore } from "./files/s3-files.js";
80
80
  import { storageProvider } from "./files/storage-provider.js";
81
81
  import { isBackgroundWork, runInBackground, wantsLongQueries } from "./background-work.js";
82
82
  import { capSocketMessages, honorSocketMessageCaps, socketMessageCapOf } from "./functions/socket-message-cap.js";
@@ -89,22 +89,19 @@ import { pngIcons } from "./web-app/app-icons.js";
89
89
  import { webManifestPath } from "./web-app/web-manifest-route.js";
90
90
  import { createAdmin } from "./create-admin.js";
91
91
  import { handleDroppedConnections } from "./dropped-connections.js";
92
- import { appPool, longQueryPool, poolWaitMs, readDbConnections } from "./app-pool.js";
92
+ import { poolWaitMs, readDbConnections } from "./app-pool.js";
93
93
  import { configExports } from "./resource-source.js";
94
94
  import { checkViewQueries } from "./check-view-queries.js";
95
- import { defineConfig, mergeConfig } from "./project-config.js";
96
95
  import { withTrustedApps } from "./better-auth/app-tokens.js";
97
- import { betterAuthAuthenticator, betterAuthTokens } from "./better-auth/authenticator.js";
96
+ import { betterAuthTokens } from "./better-auth/authenticator.js";
98
97
  import { issueToken, maxTokenTtlSeconds } from "./better-auth/tokens.js";
99
98
  import { authSchemaMigration, checkAuthSchema } from "./better-auth/auth-schema.js";
100
99
  import { authSchemaDrift } from "./better-auth/store/drift.js";
101
100
  import { authStoreTables } from "./better-auth/auth-tables.js";
102
101
  import { checkResourcesOutsideAuthStore } from "./better-auth/store/resources-outside.js";
103
102
  import { checkComputed, computedMigration } from "./computed/computed-schema.js";
104
- import { webhooks } from "./webhooks/table/plugin.js";
105
103
  import { checkWebhooksSchema, webhooksMigration } from "./webhooks/table/schema.js";
106
104
  import { checkAi } from "./ai/check-ai.js";
107
- import { notifications } from "./notifications/plugin.js";
108
105
  import { checkNotificationsSchema, notificationsMigration } from "./notifications/schema.js";
109
106
  import { sendNotification } from "./notifications/send-notification.js";
110
107
  import { maxWidgetPropsBytes, widget } from "./assistant/widget.js";
@@ -119,10 +116,11 @@ import { storeFile } from "./files/store-file.js";
119
116
  import { createFileCleanup } from "./files/file-cleanup.js";
120
117
  import { createEncryptionTools } from "./encryption/tools.js";
121
118
  import { aspectRatio, fileSize, fileType, imageSize, processor } from "./files/processors.js";
119
+ import { enqueueJob } from "./jobs/declared-job.js";
122
120
  import { defineEmail } from "./mail/define-email.js";
123
121
  import { startJobs } from "./jobs/runtime.js";
124
122
  import { jobsDrainApp } from "./jobs/drain-route.js";
125
123
  import { composeRelease, releaseManifest } from "./mobile-release/release.js";
126
124
  import { mobileReleaseApp } from "./mobile-release/release-app.js";
127
125
  import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
128
- export { ConnectionsBusy, DeviceStoreError, FatalJobError, HistoryStoreError, HttpProblem, MissingCredentials, ModelError, NotificationSendError, PushMessageError, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appPool, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, localFiles, longQueryPool, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, mergeConfig, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notifications, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
126
+ export { ConnectionsBusy, DeviceStoreError, FatalJobError, HistoryStoreError, HttpProblem, MissingCredentials, ModelError, NotificationSendError, PushMessageError, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, enqueueJob, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
@@ -0,0 +1,13 @@
1
+ import { checkNotificationsOptions } from "./notifications/options.js";
2
+ import { isSubscription } from "./webhooks/subscription.js";
3
+ import { appPool, longQueryPool } from "./app-pool.js";
4
+ import { AppAuthInput, appAuthOptions, buildAppAuth } from "./better-auth/auth-settings.js";
5
+ import { betterAuthAuthenticator } from "./better-auth/authenticator.js";
6
+ import { buildAuthenticator } from "./better-auth/authenticate-settings.js";
7
+ import { localFiles } from "./files/local-files.js";
8
+ import { s3Files } from "./files/s3-files.js";
9
+ import { fileProviderOf } from "./files/provider-settings.js";
10
+ import { declaredJob } from "./jobs/declared-job.js";
11
+ import { AuthPlugins, buildAuth, createAuth, loadAuthPlugins } from "./better-auth/create-auth.js";
12
+ import { webhooksModule } from "./webhooks/table/webhooks-module.js";
13
+ export { type AppAuthInput, type AuthPlugins, appAuthOptions, appPool, betterAuthAuthenticator, buildAppAuth, buildAuth, buildAuthenticator, checkNotificationsOptions, createAuth, declaredJob, fileProviderOf, isSubscription, loadAuthPlugins, localFiles, longQueryPool, s3Files, webhooksModule };
@@ -0,0 +1,13 @@
1
+ import { buildAuth, createAuth, loadAuthPlugins } from "./better-auth/create-auth.js";
2
+ import { isSubscription } from "./webhooks/subscription.js";
3
+ import { checkNotificationsOptions } from "./notifications/options.js";
4
+ import { localFiles } from "./files/local-files.js";
5
+ import { s3Files } from "./files/s3-files.js";
6
+ import { appPool, longQueryPool } from "./app-pool.js";
7
+ import { betterAuthAuthenticator } from "./better-auth/authenticator.js";
8
+ import { declaredJob } from "./jobs/declared-job.js";
9
+ import { appAuthOptions, buildAppAuth } from "./better-auth/auth-settings.js";
10
+ import { buildAuthenticator } from "./better-auth/authenticate-settings.js";
11
+ import { fileProviderOf } from "./files/provider-settings.js";
12
+ import { webhooksModule } from "./webhooks/table/webhooks-module.js";
13
+ export { appAuthOptions, appPool, betterAuthAuthenticator, buildAppAuth, buildAuth, buildAuthenticator, checkNotificationsOptions, createAuth, declaredJob, fileProviderOf, isSubscription, loadAuthPlugins, localFiles, longQueryPool, s3Files, webhooksModule };
@@ -0,0 +1,24 @@
1
+ import { EnqueueOptions, JobContext, JobDefinition, JobOptions } from "./job-types.js";
2
+ import { ArgumentsSpec } from "@protobase/schema";
3
+ import { Db } from "@protobase/query";
4
+ //#region src/jobs/declared-job.d.ts
5
+ /**
6
+ * A job as `protobase.config.ts` declares it, by its name: what it does, its arguments and when it runs. Its run is the
7
+ * default export of `jobs/<name>.ts`, loaded the first time the job runs.
8
+ */
9
+ export type JobDeclaration = Omit<JobOptions<unknown>, 'name' | 'payload' | 'run'> & {
10
+ /** What the job does, for the people who read the config and the failed jobs page. */
11
+ description?: string;
12
+ /** Its arguments by name, each a field type or a type with options (see `ArgumentSpec`), such as `{ invoiceId: 'bigint' }`. */
13
+ arguments?: ArgumentsSpec;
14
+ };
15
+ /** The default export of `jobs/<name>.ts`: what the job does with its arguments. */
16
+ export type JobRun<Payload = Record<string, unknown>> = (payload: Payload, context: JobContext) => Promise<void> | void;
17
+ /** The job a config declares, whose run `load` gives on its first run. */
18
+ export declare const declaredJob: (name: string, { description: _, arguments: args, ...options }: JobDeclaration, load: () => Promise<JobRun>) => JobDefinition;
19
+ /**
20
+ * Enqueues the job named `name`, which the config declares, in `db`'s own transaction when it is one, and returns its
21
+ * id: what a write hook calls, so the job commits with the write or not at all.
22
+ */
23
+ export declare const enqueueJob: (db: Db, name: string, payload?: Record<string, unknown>, options?: EnqueueOptions) => Promise<string>;
24
+ //#endregion
@@ -0,0 +1,26 @@
1
+ import { currentJobs } from "./current.js";
2
+ import { defineJob } from "./define-job.js";
3
+ import { argumentsSchema } from "@protobase/schema";
4
+ //#region src/jobs/declared-job.ts
5
+ /** The job a config declares, whose run `load` gives on its first run. */
6
+ const declaredJob = (name, { description: _, arguments: args, ...options }, load) => {
7
+ let run;
8
+ return defineJob({
9
+ ...options,
10
+ name,
11
+ ...args && { payload: argumentsSchema(name, args) },
12
+ run: async (payload, context) => (await (run ??= load()))(payload ?? {}, context)
13
+ });
14
+ };
15
+ /**
16
+ * Enqueues the job named `name`, which the config declares, in `db`'s own transaction when it is one, and returns its
17
+ * id: what a write hook calls, so the job commits with the write or not at all.
18
+ */
19
+ const enqueueJob = (db, name, payload, options) => {
20
+ const runtime = currentJobs();
21
+ const definition = runtime.definition(name);
22
+ if (!definition) throw new Error(`There is no job "${name}": declare it in protobase.config.ts's jobs`);
23
+ return runtime.enqueue(definition, db, payload, options);
24
+ };
25
+ //#endregion
26
+ export { declaredJob, enqueueJob };