@protobase/server 0.59.1 → 0.59.3
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/better-auth/store/migrations-table.js +1 -1
- package/dist/channels/binary-frame.js +44 -0
- package/dist/channels/channel-protocol.js +16 -3
- package/dist/channels/channel-refusals.js +1 -1
- package/dist/channels/channel-routes.js +22 -9
- package/dist/channels/channel-sender.d.ts +1 -1
- package/dist/channels/channel-sender.js +24 -12
- package/dist/channels/channel-socket.js +12 -7
- package/dist/channels/database-sends.js +57 -0
- package/dist/channels/sends-prune.js +15 -0
- package/dist/channels/sends-schema-sql.js +30 -0
- package/dist/channels/sends-schema.d.ts +7 -0
- package/dist/channels/sends-schema.js +18 -0
- package/dist/channels/sent.js +17 -1
- package/dist/create-admin.d.ts +5 -2
- package/dist/create-admin.js +33 -4
- package/dist/deps.d.ts +2 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/internal.d.ts +2 -1
- package/dist/internal.js +2 -1
- package/dist/meta.d.ts +2 -0
- package/dist/meta.js +1 -0
- package/dist/notifications/caller.js +2 -2
- package/dist/notifications/deliver.js +14 -2
- package/dist/notifications/push-job.js +5 -3
- package/dist/notifications/schema.js +7 -4
- package/dist/package.js +1 -1
- package/dist/realtime/database-broadcasts.js +2 -25
- package/dist/realtime/followed-poll.js +34 -0
- package/dist/realtime/realtime-prune.d.ts +5 -3
- package/dist/realtime/realtime-prune.js +8 -3
- package/dist/realtime/relay/realtime-options.d.ts +7 -0
- package/dist/realtime/relay/realtime-options.js +7 -1
- package/dist/status/do-not-disturb.d.ts +9 -0
- package/dist/status/do-not-disturb.js +15 -0
- package/dist/status/options.d.ts +15 -0
- package/dist/status/options.js +25 -0
- package/dist/status/routes.js +38 -0
- package/dist/status/schema-sql.js +19 -0
- package/dist/status/schema.d.ts +12 -0
- package/dist/status/schema.js +33 -0
- package/dist/status/status-input.js +33 -0
- package/dist/status/status-store.js +39 -0
- package/package.json +4 -4
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { badRequest } from "../problem.js";
|
|
2
|
+
import { availabilities, statusTextProblem } from "@protobase/schema/internal";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/status/status-input.ts
|
|
5
|
+
const body = z.strictObject({
|
|
6
|
+
availability: z.enum(availabilities),
|
|
7
|
+
text: z.string().nullable(),
|
|
8
|
+
clearsAt: z.iso.datetime({ offset: true }).nullable()
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* The status a request sets, checked: an availability, a one-line text of at most `maxStatusText` characters, kept
|
|
12
|
+
* trimmed, an empty one as none, and a clear time to come or `null` for never. Anything else, a user named in it
|
|
13
|
+
* too, is a 400 that says what is wrong.
|
|
14
|
+
*/
|
|
15
|
+
const statusInput = (given, now = /* @__PURE__ */ new Date()) => {
|
|
16
|
+
const parsed = body.safeParse(given);
|
|
17
|
+
if (!parsed.success) {
|
|
18
|
+
const issue = parsed.error.issues[0];
|
|
19
|
+
throw badRequest("invalid-status", `Send { availability, text, clearsAt }: ${issue.path.join(".") || "the body"} ${issue.message.toLowerCase()}`);
|
|
20
|
+
}
|
|
21
|
+
const { availability, clearsAt } = parsed.data;
|
|
22
|
+
const text = parsed.data.text?.trim() || null;
|
|
23
|
+
const problem = text === null ? void 0 : statusTextProblem(text);
|
|
24
|
+
if (problem) throw badRequest("invalid-status-text", problem);
|
|
25
|
+
if (clearsAt !== null && Date.parse(clearsAt) <= now.getTime()) throw badRequest("invalid-clear-time", "A status clears at a time still to come, or never");
|
|
26
|
+
return {
|
|
27
|
+
availability,
|
|
28
|
+
text,
|
|
29
|
+
clearsAt: clearsAt === null ? null : new Date(clearsAt).toISOString()
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { statusInput };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { qualified } from "../notifications/schema-sql.js";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
//#region src/status/status-store.ts
|
|
4
|
+
const statusOf = (row) => ({
|
|
5
|
+
userId: String(row.user_id),
|
|
6
|
+
availability: row.availability,
|
|
7
|
+
text: row.text,
|
|
8
|
+
clearsAt: row.clears_at?.toISOString() ?? null
|
|
9
|
+
});
|
|
10
|
+
const holds = sql`(clears_at is null or clears_at > now())`;
|
|
11
|
+
/** The person's own status, as it holds now; `undefined` when they have none. */
|
|
12
|
+
const ownStatus = async (db, tables, userId) => {
|
|
13
|
+
const statuses = sql.raw(qualified(tables.statuses));
|
|
14
|
+
const { rows } = await sql`select user_id, availability, text, clears_at from ${statuses} where user_id = ${userId} and ${holds}`.execute(db);
|
|
15
|
+
return rows[0] && statusOf(rows[0]);
|
|
16
|
+
};
|
|
17
|
+
/** The statuses that hold now of everyone who shares an organization with `viewerId`, their own included when they have one. */
|
|
18
|
+
const visibleStatuses = async (db, tables, viewerId) => {
|
|
19
|
+
const statuses = sql.raw(qualified(tables.statuses));
|
|
20
|
+
const members = sql.raw(qualified(tables.members));
|
|
21
|
+
const { rows } = await sql`select s.user_id, s.availability, s.text, s.clears_at from ${statuses} s
|
|
22
|
+
where ${holds} and exists (select from ${members} own join ${members} other on other.organization_id = own.organization_id
|
|
23
|
+
where own.user_id = ${viewerId} and other.user_id = s.user_id)
|
|
24
|
+
order by s.user_id`.execute(db);
|
|
25
|
+
return rows.map(statusOf);
|
|
26
|
+
};
|
|
27
|
+
/** Sets the person's status, replacing the one they had; one that says nothing, automatic without a text, clears it. */
|
|
28
|
+
const setStatus = async (db, tables, userId, input) => {
|
|
29
|
+
if (input.availability === "automatic" && input.text === null) return clearStatus(db, tables, userId);
|
|
30
|
+
const statuses = sql.raw(qualified(tables.statuses));
|
|
31
|
+
await sql`insert into ${statuses} (user_id, availability, text, clears_at, updated_at) values (${userId}, ${input.availability}, ${input.text}, ${input.clearsAt}, now())
|
|
32
|
+
on conflict (user_id) do update set availability = excluded.availability, text = excluded.text, clears_at = excluded.clears_at, updated_at = excluded.updated_at`.execute(db);
|
|
33
|
+
};
|
|
34
|
+
/** Clears the person's status, whether or not they had one. */
|
|
35
|
+
const clearStatus = async (db, tables, userId) => {
|
|
36
|
+
await sql`delete from ${sql.raw(qualified(tables.statuses))} where user_id = ${userId}`.execute(db);
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { clearStatus, ownStatus, setStatus, visibleStatuses };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.59.
|
|
3
|
+
"version": "0.59.3",
|
|
4
4
|
"description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"@better-auth/sso": "^1.7.12",
|
|
43
43
|
"@livekit/protocol": "1.53.1",
|
|
44
44
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
45
|
-
"@protobase/layout": "0.59.
|
|
46
|
-
"@protobase/query": "0.59.
|
|
47
|
-
"@protobase/schema": "0.59.
|
|
45
|
+
"@protobase/layout": "0.59.3",
|
|
46
|
+
"@protobase/query": "0.59.3",
|
|
47
|
+
"@protobase/schema": "0.59.3",
|
|
48
48
|
"@react-email/render": "^2.1.0",
|
|
49
49
|
"@scalar/hono-api-reference": "^0.12.10",
|
|
50
50
|
"@sentry/core": "^11.7.0",
|