refactor: zones => topics
This commit is contained in:
parent
20a5d1bc88
commit
fac8f409f4
26 changed files with 470 additions and 469 deletions
23
public/api/topics/:topic_id/README.md
Normal file
23
public/api/topics/:topic_id/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# /api/topics/:topic_id
|
||||
|
||||
Interact with a specific topic.
|
||||
|
||||
## GET /api/topics/:topic_id
|
||||
|
||||
Get the topic specified by `:topic_id`.
|
||||
|
||||
## PUT /api/topics/:topic_id
|
||||
|
||||
Update the topics specified by `:topic_id`.
|
||||
|
||||
Eg:
|
||||
|
||||
```
|
||||
{
|
||||
name?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## DELETE /api/topics/:topic_id
|
||||
|
||||
Delete the topic specified by `:topic_id`.
|
||||
|
|
@ -1,36 +1,36 @@
|
|||
import { FSDB_COLLECTION } from '@andyburke/fsdb';
|
||||
import { EVENT, get_events_collection_for_zone } from '../../../../../../models/event.ts';
|
||||
import { ZONE, ZONES } from '../../../../../../models/zone.ts';
|
||||
import { EVENT, get_events_collection_for_topic } from '../../../../../../models/event.ts';
|
||||
import { TOPIC, TOPICS } from '../../../../../../models/topic.ts';
|
||||
import parse_body from '../../../../../../utils/bodyparser.ts';
|
||||
import * as CANNED_RESPONSES from '../../../../../../utils/canned_responses.ts';
|
||||
import { get_session, get_user, PRECHECK_TABLE, require_user } from '../../../../../../utils/prechecks.ts';
|
||||
|
||||
export const PRECHECKS: PRECHECK_TABLE = {};
|
||||
|
||||
// GET /api/zones/:zone_id/events/:id - Get an event
|
||||
// GET /api/topics/:topic_id/events/:id - Get an event
|
||||
PRECHECKS.GET = [get_session, get_user, require_user, async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const zone_is_public = zone.permissions.read.length === 0;
|
||||
const user_has_read_for_zone = zone_is_public || zone.permissions.read.includes(meta.user.id);
|
||||
const zone_has_public_events = user_has_read_for_zone && (zone.permissions.read_events.length === 0);
|
||||
const user_has_read_events_for_zone = user_has_read_for_zone &&
|
||||
(zone_has_public_events || zone.permissions.read_events.includes(meta.user.id));
|
||||
meta.topic = topic;
|
||||
const topic_is_public = topic.permissions.read.length === 0;
|
||||
const user_has_read_for_topic = topic_is_public || topic.permissions.read.includes(meta.user.id);
|
||||
const topic_has_public_events = user_has_read_for_topic && (topic.permissions.read_events.length === 0);
|
||||
const user_has_read_events_for_topic = user_has_read_for_topic &&
|
||||
(topic_has_public_events || topic.permissions.read_events.includes(meta.user.id));
|
||||
|
||||
if (!user_has_read_events_for_zone) {
|
||||
if (!user_has_read_events_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
export async function GET(_req: Request, meta: Record<string, any>): Promise<Response> {
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_zone(meta.zone.id);
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_topic(meta.topic.id);
|
||||
const event: EVENT | null = await events.get(meta.params.event_id);
|
||||
|
||||
if (!event) {
|
||||
|
|
@ -42,7 +42,7 @@ export async function GET(_req: Request, meta: Record<string, any>): Promise<Res
|
|||
});
|
||||
}
|
||||
|
||||
// PUT /api/zones/:zone_id/events/:event_id - Update event
|
||||
// PUT /api/topics/:topic_id/events/:event_id - Update event
|
||||
PRECHECKS.PUT = [
|
||||
get_session,
|
||||
get_user,
|
||||
|
|
@ -53,23 +53,23 @@ PRECHECKS.PUT = [
|
|||
}
|
||||
},
|
||||
async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const zone_is_public: boolean = meta.zone.permissions.read.length === 0;
|
||||
const user_has_read_for_zone = zone_is_public || meta.zone.permissions.read.includes(meta.user.id);
|
||||
const zone_events_are_publicly_writable = meta.zone.permissions.write_events.length === 0;
|
||||
const user_has_write_events_for_zone = user_has_read_for_zone &&
|
||||
(zone_events_are_publicly_writable || meta.zone.permissions.write_events.includes(meta.user.id));
|
||||
meta.topic = topic;
|
||||
const topic_is_public: boolean = meta.topic.permissions.read.length === 0;
|
||||
const user_has_read_for_topic = topic_is_public || meta.topic.permissions.read.includes(meta.user.id);
|
||||
const topic_events_are_publicly_writable = meta.topic.permissions.write_events.length === 0;
|
||||
const user_has_write_events_for_topic = user_has_read_for_topic &&
|
||||
(topic_events_are_publicly_writable || meta.topic.permissions.write_events.includes(meta.user.id));
|
||||
|
||||
if (!user_has_write_events_for_zone) {
|
||||
if (!user_has_write_events_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ export async function PUT(req: Request, meta: Record<string, any>): Promise<Resp
|
|||
const now = new Date().toISOString();
|
||||
|
||||
try {
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_zone(meta.zone.id);
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_topic(meta.topic.id);
|
||||
const event: EVENT | null = await events.get(meta.params.event_id);
|
||||
|
||||
if (!event) {
|
||||
|
|
@ -117,7 +117,7 @@ export async function PUT(req: Request, meta: Record<string, any>): Promise<Resp
|
|||
}
|
||||
}
|
||||
|
||||
// DELETE /api/zones/:zone_id/events/:event_id - Delete event
|
||||
// DELETE /api/topics/:topic_id/events/:event_id - Delete event
|
||||
PRECHECKS.DELETE = [
|
||||
get_session,
|
||||
get_user,
|
||||
|
|
@ -128,29 +128,29 @@ PRECHECKS.DELETE = [
|
|||
}
|
||||
},
|
||||
async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const zone_is_public: boolean = meta.zone.permissions.read.length === 0;
|
||||
const user_has_read_for_zone = zone_is_public || meta.zone.permissions.read.includes(meta.user.id);
|
||||
const zone_events_are_publicly_writable = meta.zone.permissions.write_events.length === 0;
|
||||
const user_has_write_events_for_zone = user_has_read_for_zone &&
|
||||
(zone_events_are_publicly_writable || meta.zone.permissions.write_events.includes(meta.user.id));
|
||||
meta.topic = topic;
|
||||
const topic_is_public: boolean = meta.topic.permissions.read.length === 0;
|
||||
const user_has_read_for_topic = topic_is_public || meta.topic.permissions.read.includes(meta.user.id);
|
||||
const topic_events_are_publicly_writable = meta.topic.permissions.write_events.length === 0;
|
||||
const user_has_write_events_for_topic = user_has_read_for_topic &&
|
||||
(topic_events_are_publicly_writable || meta.topic.permissions.write_events.includes(meta.user.id));
|
||||
|
||||
if (!user_has_write_events_for_zone) {
|
||||
if (!user_has_write_events_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}
|
||||
];
|
||||
export async function DELETE(_req: Request, meta: Record<string, any>): Promise<Response> {
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_zone(meta.zone.id);
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_topic(meta.topic.id);
|
||||
const event: EVENT | null = await events.get(meta.params.event_id);
|
||||
if (!event) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
15
public/api/topics/:topic_id/events/README.md
Normal file
15
public/api/topics/:topic_id/events/README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# /api/topics/:topic_id/events
|
||||
|
||||
Interact with a events for a topic.
|
||||
|
||||
## GET /api/topics/:topic_id/events
|
||||
|
||||
Get events for the given topic.
|
||||
|
||||
## PUT /api/topics/:topic_id/events/:event_id
|
||||
|
||||
Update an event.
|
||||
|
||||
## DELETE /api/topics/:topic_id/events/:event_id
|
||||
|
||||
Delete an event.
|
||||
|
|
@ -1,40 +1,40 @@
|
|||
import lurid from '@andyburke/lurid';
|
||||
import { get_session, get_user, PRECHECK_TABLE, require_user } from '../../../../../utils/prechecks.ts';
|
||||
import { ZONE, ZONES } from '../../../../../models/zone.ts';
|
||||
import { TOPIC, TOPICS } from '../../../../../models/topic.ts';
|
||||
import * as CANNED_RESPONSES from '../../../../../utils/canned_responses.ts';
|
||||
import { EVENT, get_events_collection_for_zone } from '../../../../../models/event.ts';
|
||||
import { EVENT, get_events_collection_for_topic } from '../../../../../models/event.ts';
|
||||
import parse_body from '../../../../../utils/bodyparser.ts';
|
||||
import { FSDB_COLLECTION, FSDB_SEARCH_OPTIONS, WALK_ENTRY } from '@andyburke/fsdb';
|
||||
import * as path from '@std/path';
|
||||
|
||||
export const PRECHECKS: PRECHECK_TABLE = {};
|
||||
|
||||
// GET /api/zones/:zone_id/events - get zone events
|
||||
// GET /api/topics/:topic_id/events - get topic events
|
||||
// query parameters:
|
||||
// partial_id: the partial id subset you would like to match (remember, lurids are lexigraphically sorted)
|
||||
PRECHECKS.GET = [get_session, get_user, require_user, async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const zone_is_public: boolean = meta.zone.permissions.read.length === 0;
|
||||
const user_has_read_for_zone = zone_is_public || meta.zone.permissions.read.includes(meta.user.id);
|
||||
const zone_events_are_public = meta.zone.permissions.read_events.length === 0;
|
||||
const user_has_read_events_for_zone = user_has_read_for_zone &&
|
||||
(zone_events_are_public || meta.zone.permissions.read_events.includes(meta.user.id));
|
||||
meta.topic = topic;
|
||||
const topic_is_public: boolean = meta.topic.permissions.read.length === 0;
|
||||
const user_has_read_for_topic = topic_is_public || meta.topic.permissions.read.includes(meta.user.id);
|
||||
const topic_events_are_public = meta.topic.permissions.read_events.length === 0;
|
||||
const user_has_read_events_for_topic = user_has_read_for_topic &&
|
||||
(topic_events_are_public || meta.topic.permissions.read_events.includes(meta.user.id));
|
||||
|
||||
if (!user_has_read_events_for_zone) {
|
||||
if (!user_has_read_events_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
export async function GET(request: Request, meta: Record<string, any>): Promise<Response> {
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_zone(meta.zone.id);
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_topic(meta.topic.id);
|
||||
|
||||
const sorts = events.sorts;
|
||||
const sort_name: string = meta.query.sort ?? 'newest';
|
||||
|
|
@ -126,31 +126,31 @@ export async function GET(request: Request, meta: Record<string, any>): Promise<
|
|||
});
|
||||
}
|
||||
|
||||
// POST /api/zones/:zone_id/events - Create an event
|
||||
// POST /api/topics/:topic_id/events - Create an event
|
||||
PRECHECKS.POST = [get_session, get_user, require_user, async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const zone_is_public: boolean = meta.zone.permissions.read.length === 0;
|
||||
const user_has_read_for_zone = zone_is_public || meta.zone.permissions.read.includes(meta.user.id);
|
||||
const zone_events_are_publicly_writable = meta.zone.permissions.write_events.length === 0;
|
||||
const user_has_write_events_for_zone = user_has_read_for_zone &&
|
||||
(zone_events_are_publicly_writable || meta.zone.permissions.write_events.includes(meta.user.id));
|
||||
meta.topic = topic;
|
||||
const topic_is_public: boolean = meta.topic.permissions.read.length === 0;
|
||||
const user_has_read_for_topic = topic_is_public || meta.topic.permissions.read.includes(meta.user.id);
|
||||
const topic_events_are_publicly_writable = meta.topic.permissions.write_events.length === 0;
|
||||
const user_has_write_events_for_topic = user_has_read_for_topic &&
|
||||
(topic_events_are_publicly_writable || meta.topic.permissions.write_events.includes(meta.user.id));
|
||||
|
||||
if (!user_has_write_events_for_zone) {
|
||||
if (!user_has_write_events_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
export async function POST(req: Request, meta: Record<string, any>): Promise<Response> {
|
||||
try {
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_zone(meta.zone.id);
|
||||
const events: FSDB_COLLECTION<EVENT> = get_events_collection_for_topic(meta.topic.id);
|
||||
|
||||
const now = new Date().toISOString();
|
||||
|
||||
|
|
@ -1,50 +1,50 @@
|
|||
import { get_session, get_user, PRECHECK_TABLE, require_user } from '../../../../utils/prechecks.ts';
|
||||
import parse_body from '../../../../utils/bodyparser.ts';
|
||||
import * as CANNED_RESPONSES from '../../../../utils/canned_responses.ts';
|
||||
import { ZONE, ZONES } from '../../../../models/zone.ts';
|
||||
import { TOPIC, TOPICS } from '../../../../models/topic.ts';
|
||||
|
||||
export const PRECHECKS: PRECHECK_TABLE = {};
|
||||
|
||||
// GET /api/zones/:id - Get a zone
|
||||
// GET /api/topics/:id - Get a topic
|
||||
PRECHECKS.GET = [get_session, get_user, require_user, async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const zone_is_public = zone.permissions.read.length === 0;
|
||||
const user_has_read_for_zone = zone_is_public || zone.permissions.read.includes(meta.user.id);
|
||||
meta.topic = topic;
|
||||
const topic_is_public = topic.permissions.read.length === 0;
|
||||
const user_has_read_for_topic = topic_is_public || topic.permissions.read.includes(meta.user.id);
|
||||
|
||||
if (!user_has_read_for_zone) {
|
||||
if (!user_has_read_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
export function GET(_req: Request, meta: Record<string, any>): Response {
|
||||
return Response.json(meta.zone, {
|
||||
return Response.json(meta.topic, {
|
||||
status: 200
|
||||
});
|
||||
}
|
||||
|
||||
// PUT /api/zones/:id - Update zone
|
||||
// PUT /api/topics/:id - Update topic
|
||||
PRECHECKS.PUT = [get_session, get_user, require_user, async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const user_has_write_for_zone = zone.permissions.write.includes(meta.user.id);
|
||||
meta.topic = topic;
|
||||
const user_has_write_for_topic = topic.permissions.write.includes(meta.user.id);
|
||||
|
||||
if (!user_has_write_for_zone) {
|
||||
if (!user_has_write_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
|
|
@ -54,16 +54,16 @@ export async function PUT(req: Request, meta: Record<string, any>): Promise<Resp
|
|||
try {
|
||||
const body = await parse_body(req);
|
||||
const updated = {
|
||||
...meta.zone,
|
||||
...meta.topic,
|
||||
...body,
|
||||
id: meta.zone.id,
|
||||
id: meta.topic.id,
|
||||
timestamps: {
|
||||
created: meta.zone.timestamps.created,
|
||||
created: meta.topic.timestamps.created,
|
||||
updated: now
|
||||
}
|
||||
};
|
||||
|
||||
await ZONES.update(updated);
|
||||
await TOPICS.update(updated);
|
||||
return Response.json(updated, {
|
||||
status: 200
|
||||
});
|
||||
|
|
@ -79,31 +79,31 @@ export async function PUT(req: Request, meta: Record<string, any>): Promise<Resp
|
|||
}
|
||||
}
|
||||
|
||||
// DELETE /api/zones/:id - Delete zone
|
||||
// DELETE /api/topics/:id - Delete topic
|
||||
PRECHECKS.DELETE = [
|
||||
get_session,
|
||||
get_user,
|
||||
require_user,
|
||||
async (_req: Request, meta: Record<string, any>): Promise<Response | undefined> => {
|
||||
const zone_id: string = meta.params?.zone_id?.toLowerCase().trim() ?? '';
|
||||
const topic_id: string = meta.params?.topic_id?.toLowerCase().trim() ?? '';
|
||||
|
||||
// lurid is 49 chars as we use them, eg: "also-play-flow-want-form-wide-thus-work-burn-same"
|
||||
const zone: ZONE | null = zone_id.length === 49 ? await ZONES.get(zone_id) : null;
|
||||
const topic: TOPIC | null = topic_id.length === 49 ? await TOPICS.get(topic_id) : null;
|
||||
|
||||
if (!zone) {
|
||||
if (!topic) {
|
||||
return CANNED_RESPONSES.not_found();
|
||||
}
|
||||
|
||||
meta.zone = zone;
|
||||
const user_has_write_for_zone = zone.permissions.write.includes(meta.user.id);
|
||||
meta.topic = topic;
|
||||
const user_has_write_for_topic = topic.permissions.write.includes(meta.user.id);
|
||||
|
||||
if (!user_has_write_for_zone) {
|
||||
if (!user_has_write_for_topic) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}
|
||||
];
|
||||
export async function DELETE(_req: Request, meta: Record<string, any>): Promise<Response> {
|
||||
await ZONES.delete(meta.zone);
|
||||
await TOPICS.delete(meta.topic);
|
||||
|
||||
return Response.json({
|
||||
deleted: true
|
||||
28
public/api/topics/README.md
Normal file
28
public/api/topics/README.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# /api/topics
|
||||
|
||||
Interact with topics.
|
||||
|
||||
## POST /api/topics
|
||||
|
||||
Create a new topic.
|
||||
|
||||
```
|
||||
export type TOPIC = {
|
||||
id: string; // unique id for this topic
|
||||
name: string; // the name of the topic (max 128 characters)
|
||||
icon_url?: string; // optional url for a topic icon
|
||||
topic?: string; // optional topic topic
|
||||
tags: string[]; // a list of tags for the topic
|
||||
meta: Record<string, any>;
|
||||
limits: {
|
||||
users: number;
|
||||
user_messages_per_minute: number;
|
||||
};
|
||||
creator_id: string; // user_id of the topic creator
|
||||
emojis: Record<string, string>; // either: string: emoji eg: { 'rofl: 🤣, ... } or { 'rofl': 🤣, 'blap': 'https://somewhere.someplace/image.jpg' }
|
||||
};
|
||||
```
|
||||
|
||||
## GET /api/topics
|
||||
|
||||
Get topics.
|
||||
|
|
@ -3,40 +3,40 @@ import parse_body from '../../../utils/bodyparser.ts';
|
|||
import { get_session, get_user, require_user } from '../../../utils/prechecks.ts';
|
||||
import * as CANNED_RESPONSES from '../../../utils/canned_responses.ts';
|
||||
import { PRECHECK_TABLE } from '../../../utils/prechecks.ts';
|
||||
import { ZONE, ZONES } from '../../../models/zone.ts';
|
||||
import { TOPIC, TOPICS } from '../../../models/topic.ts';
|
||||
import { WALK_ENTRY } from '@andyburke/fsdb';
|
||||
|
||||
export const PRECHECKS: PRECHECK_TABLE = {};
|
||||
|
||||
// GET /api/zones - get zones
|
||||
// GET /api/topics - get topics
|
||||
PRECHECKS.GET = [get_session, get_user, require_user, (_req: Request, meta: Record<string, any>): Response | undefined => {
|
||||
const can_read_zones = meta.user.permissions.includes('zones.read');
|
||||
const can_read_topics = meta.user.permissions.includes('topics.read');
|
||||
|
||||
if (!can_read_zones) {
|
||||
if (!can_read_topics) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
export async function GET(_req: Request, meta: Record<string, any>): Promise<Response> {
|
||||
const limit = Math.min(parseInt(meta.query.limit ?? '100'), 100);
|
||||
const zones = (await ZONES.all({
|
||||
const topics = (await TOPICS.all({
|
||||
limit,
|
||||
filter: (entry: WALK_ENTRY<ZONE>) => {
|
||||
// we push our event collections into the zones, and fsdb
|
||||
filter: (entry: WALK_ENTRY<TOPIC>) => {
|
||||
// we push our event collections into the topics, and fsdb
|
||||
// doesn't yet filter that out in its all() logic
|
||||
return entry.path.indexOf('/events/') === -1;
|
||||
}
|
||||
})).map((zone_entry) => zone_entry.load());
|
||||
})).map((topic_entry) => topic_entry.load());
|
||||
|
||||
return Response.json(zones, {
|
||||
return Response.json(topics, {
|
||||
status: 200
|
||||
});
|
||||
}
|
||||
|
||||
// POST /api/zones - Create a zone
|
||||
// POST /api/topics - Create a topic
|
||||
PRECHECKS.POST = [get_session, get_user, require_user, (_req: Request, meta: Record<string, any>): Response | undefined => {
|
||||
const can_create_zones = meta.user.permissions.includes('zones.create');
|
||||
const can_create_topics = meta.user.permissions.includes('topics.create');
|
||||
|
||||
if (!can_create_zones) {
|
||||
if (!can_create_topics) {
|
||||
return CANNED_RESPONSES.permission_denied();
|
||||
}
|
||||
}];
|
||||
|
|
@ -49,8 +49,8 @@ export async function POST(req: Request, meta: Record<string, any>): Promise<Res
|
|||
if (typeof body.name !== 'string' || body.name.length === 0) {
|
||||
return Response.json({
|
||||
error: {
|
||||
cause: 'missing_zone_name',
|
||||
message: 'You must specify a unique name for a zone.'
|
||||
cause: 'missing_topic_name',
|
||||
message: 'You must specify a unique name for a topic.'
|
||||
}
|
||||
}, {
|
||||
status: 400
|
||||
|
|
@ -60,8 +60,8 @@ export async function POST(req: Request, meta: Record<string, any>): Promise<Res
|
|||
if (body.name.length > 64) {
|
||||
return Response.json({
|
||||
error: {
|
||||
cause: 'invalid_zone_name',
|
||||
message: 'zone names must be 64 characters or fewer.'
|
||||
cause: 'invalid_topic_name',
|
||||
message: 'topic names must be 64 characters or fewer.'
|
||||
}
|
||||
}, {
|
||||
status: 400
|
||||
|
|
@ -70,21 +70,21 @@ export async function POST(req: Request, meta: Record<string, any>): Promise<Res
|
|||
|
||||
const normalized_name = body.name.toLowerCase();
|
||||
|
||||
const existing_zone = (await ZONES.find({
|
||||
const existing_topic = (await TOPICS.find({
|
||||
name: normalized_name
|
||||
})).shift();
|
||||
if (existing_zone) {
|
||||
if (existing_topic) {
|
||||
return Response.json({
|
||||
error: {
|
||||
cause: 'zone_name_conflict',
|
||||
message: 'There is already a zone with this name.'
|
||||
cause: 'topic_name_conflict',
|
||||
message: 'There is already a topic with this name.'
|
||||
}
|
||||
}, {
|
||||
status: 400
|
||||
});
|
||||
}
|
||||
|
||||
const zone: ZONE = {
|
||||
const topic: TOPIC = {
|
||||
...body,
|
||||
id: lurid(),
|
||||
creator_id: meta.user.id,
|
||||
|
|
@ -101,9 +101,9 @@ export async function POST(req: Request, meta: Record<string, any>): Promise<Res
|
|||
}
|
||||
};
|
||||
|
||||
await ZONES.create(zone);
|
||||
await TOPICS.create(topic);
|
||||
|
||||
return Response.json(zone, {
|
||||
return Response.json(topic, {
|
||||
status: 201
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -13,7 +13,7 @@ const DEFAULT_USER_PERMISSIONS: string[] = [
|
|||
'files.write.own',
|
||||
'self.read',
|
||||
'self.write',
|
||||
'zones.read',
|
||||
'topics.read',
|
||||
'users.read'
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# /api/zones/:zone_id
|
||||
|
||||
Interact with a specific zone.
|
||||
|
||||
## GET /api/zones/:zone_id
|
||||
|
||||
Get the zone specified by `:zone_id`.
|
||||
|
||||
## PUT /api/zones/:zone_id
|
||||
|
||||
Update the zones specified by `:zone_id`.
|
||||
|
||||
Eg:
|
||||
|
||||
```
|
||||
{
|
||||
name?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## DELETE /api/zones/:zone_id
|
||||
|
||||
Delete the zone specified by `:zone_id`.
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# /api/zones/:zone_id/events
|
||||
|
||||
Interact with a events for a zone.
|
||||
|
||||
## GET /api/zones/:zone_id/events
|
||||
|
||||
Get events for the given zone.
|
||||
|
||||
## PUT /api/zones/:zone_id/events/:event_id
|
||||
|
||||
Update an event.
|
||||
|
||||
## DELETE /api/zones/:zone_id/events/:event_id
|
||||
|
||||
Delete an event.
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# /api/zones
|
||||
|
||||
Interact with zones.
|
||||
|
||||
## POST /api/zones
|
||||
|
||||
Create a new zone.
|
||||
|
||||
```
|
||||
export type ZONE = {
|
||||
id: string; // unique id for this zone
|
||||
name: string; // the name of the zone (max 128 characters)
|
||||
icon_url?: string; // optional url for a zone icon
|
||||
topic?: string; // optional zone topic
|
||||
tags: string[]; // a list of tags for the zone
|
||||
meta: Record<string, any>;
|
||||
limits: {
|
||||
users: number;
|
||||
user_messages_per_minute: number;
|
||||
};
|
||||
creator_id: string; // user_id of the zone creator
|
||||
emojis: Record<string, string>; // either: string: emoji eg: { 'rofl: 🤣, ... } or { 'rofl': 🤣, 'blap': 'https://somewhere.someplace/image.jpg' }
|
||||
};
|
||||
```
|
||||
|
||||
## GET /api/zones
|
||||
|
||||
Get zones.
|
||||
Loading…
Add table
Add a link
Reference in a new issue