@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
105 lines (103 loc) • 4.36 kB
JavaScript
import emitter_default from "../../emitter.js";
import { ItemsService } from "../../services/items.js";
import { getSchema } from "../../utils/get-schema.js";
import { sanitizeQuery } from "../../utils/sanitize-query.js";
import { validateQuery } from "../../utils/validate-query.js";
import { WebSocketError, handleWebSocketError } from "../errors.js";
import { WebSocketItemsMessage } from "../messages.js";
import { fmtMessage, getMessageType } from "../utils/message.js";
import { MetaService } from "../../services/meta.js";
import "../../services/index.js";
import { isSystemCollection } from "@directus/system-data";
//#region src/websocket/handlers/items.ts
var ItemsHandler = class {
constructor() {
emitter_default.onAction("websocket.message", ({ client, message }) => {
if (getMessageType(message) !== "items") return;
try {
const parsedMessage = WebSocketItemsMessage.parse(message);
this.onMessage(client, parsedMessage).catch((err) => {
handleWebSocketError(client, err, "items");
});
} catch (err) {
handleWebSocketError(client, err, "items");
}
});
}
async onMessage(client, message) {
const uid = message.uid;
const accountability = client.accountability;
const schema = await getSchema();
if (!schema.collections[message.collection] || isSystemCollection(message.collection)) throw new WebSocketError("items", "INVALID_COLLECTION", "The provided collection does not exists or is not accessible.", uid);
const isSingleton = !!schema.collections[message.collection]?.singleton;
const service = new ItemsService(message.collection, {
schema,
accountability
});
const metaService = new MetaService({
schema,
accountability
});
let result, meta;
if (message.action === "create") {
const query = await sanitizeQuery(message?.query ?? {}, schema, accountability);
validateQuery(query);
if (Array.isArray(message.data)) {
const keys = await service.createMany(message.data);
result = await service.readMany(keys, query);
} else {
const key = await service.createOne(message.data);
result = await service.readOne(key, query);
}
}
if (message.action === "read") {
const query = await sanitizeQuery(message.query ?? {}, schema, accountability);
validateQuery(query);
if (message.id) result = await service.readOne(message.id, query);
else if (message.ids) result = await service.readMany(message.ids, query);
else if (isSingleton) result = await service.readSingleton(query);
else result = await service.readByQuery(query);
meta = await metaService.getMetaForQuery(message.collection, query);
}
if (message.action === "update") {
const query = await sanitizeQuery(message.query ?? {}, schema, accountability);
validateQuery(query);
if (message.id) {
const key = await service.updateOne(message.id, message.data);
result = await service.readOne(key);
} else if (message.ids) {
const keys = await service.updateMany(message.ids, message.data);
meta = await metaService.getMetaForQuery(message.collection, query);
result = await service.readMany(keys, query);
} else if (isSingleton) {
await service.upsertSingleton(message.data);
result = await service.readSingleton(query);
} else if (Array.isArray(message.data)) {
const keys = await service.updateBatch(message.data);
meta = await metaService.getMetaForQuery(message.collection, query);
result = await service.readMany(keys, query);
} else {
const keys = await service.updateByQuery(query, message.data);
meta = await metaService.getMetaForQuery(message.collection, query);
result = await service.readMany(keys, query);
}
}
if (message.action === "delete") if (message.id) {
await service.deleteOne(message.id);
result = message.id;
} else if (message.ids) {
await service.deleteMany(message.ids);
result = message.ids;
} else if (message.query) {
const query = await sanitizeQuery(message.query, schema, accountability);
validateQuery(query);
result = await service.deleteByQuery(query);
} else throw new WebSocketError("items", "INVALID_PAYLOAD", "Either 'ids', 'id' or 'query' is required for a DELETE request.", uid);
client.send(fmtMessage("items", {
data: result,
...meta ? { meta } : {}
}, uid));
}
};
//#endregion
export { ItemsHandler };