@dossierhq/sqlite-core
Version:
A library used by concrete SQLite adapters for Dossier.
71 lines • 4.54 kB
JavaScript
/// <reference types="./createEntity.d.ts" />
/* eslint-disable @typescript-eslint/no-unused-expressions */
import { EventType, notOk, ok, } from '@dossierhq/core';
import { buildSqliteSqlQuery, } from '@dossierhq/database-adapter';
import { EntitiesUniqueNameConstraint, EntitiesUniquePublishedNameConstraint, EntitiesUniqueUuidConstraint, } from '../DatabaseSchema.js';
import { queryOne, queryRun } from '../QueryFunctions.js';
import { getTransactionTimestamp } from '../SqliteTransaction.js';
import { createEntityEvent } from '../utils/EventUtils.js';
import { getSessionSubjectInternalId } from '../utils/SessionUtils.js';
import { withUniqueNameAttempt } from '../utils/withUniqueNameAttempt.js';
import { getEntitiesUpdatedSeq } from './getEntitiesUpdatedSeq.js';
export async function adminCreateEntity(database, context, randomNameGenerator, entity, syncEvent) {
const now = syncEvent?.createdAt ?? getTransactionTimestamp(context.transaction);
const createEntityRowResult = await createEntityRow(database, context, randomNameGenerator, entity, now);
if (createEntityRowResult.isError())
return createEntityRowResult;
const { uuid, actualName, entityId } = createEntityRowResult.value;
const createEntityVersionResult = await queryOne(database, context, buildSqliteSqlQuery(({ sql }) => {
const createdBy = getSessionSubjectInternalId(entity.session);
sql `INSERT INTO entity_versions (entities_id, type, name, version, created_at, created_by, schema_version, encode_version, fields)`;
sql `VALUES (${entityId}, ${entity.type}, ${actualName}, ${entity.version}, ${now.toISOString()}, ${createdBy}, ${entity.schemaVersion}, ${entity.encodeVersion}, ${JSON.stringify(entity.fields)}) RETURNING id`;
}));
if (createEntityVersionResult.isError())
return createEntityVersionResult;
const { id: versionsId } = createEntityVersionResult.value;
const updateLatestDraftIdResult = await queryRun(database, context, {
text: 'UPDATE entities SET latest_entity_versions_id = ?1 WHERE id = ?2',
values: [versionsId, entityId],
});
if (updateLatestDraftIdResult.isError())
return updateLatestDraftIdResult;
const createEventResult = await createEntityEvent(database, context, entity.session, entity.publish ? EventType.createAndPublishEntity : EventType.createEntity, [{ entityVersionsId: versionsId }], syncEvent);
if (createEventResult.isError())
return createEventResult;
return ok({
id: uuid,
entityInternalId: entityId,
name: actualName,
createdAt: now,
updatedAt: now,
});
}
async function createEntityRow(database, context, randomNameGenerator, entity, now) {
const uuid = entity.id ?? database.adapter.randomUUID();
const updatedSecResult = await getEntitiesUpdatedSeq(database, context);
if (updatedSecResult.isError())
return updatedSecResult;
return await withUniqueNameAttempt(context, entity.name, randomNameGenerator, async (context, name, nameConflictErrorMessage) => {
const publishedName = entity.publish ? name : null;
const createResult = await queryOne(database, context, buildSqliteSqlQuery(({ sql, addValue }) => {
const nowValue = addValue(now.toISOString());
sql `INSERT INTO entities (uuid, name, published_name, type, auth_key, resolved_auth_key, status, created_at, updated_at, updated_seq)`;
sql `VALUES (${uuid}, ${name}, ${publishedName}, ${entity.type}, ${entity.resolvedAuthKey.authKey}, ${entity.resolvedAuthKey.resolvedAuthKey}, 'draft', ${nowValue}, ${nowValue}, ${updatedSecResult.value})`;
sql `RETURNING id`;
}), (error) => {
if (database.adapter.isUniqueViolationOfConstraint(error, EntitiesUniqueNameConstraint) ||
database.adapter.isUniqueViolationOfConstraint(error, EntitiesUniquePublishedNameConstraint)) {
return notOk.Conflict(nameConflictErrorMessage);
}
else if (database.adapter.isUniqueViolationOfConstraint(error, EntitiesUniqueUuidConstraint)) {
return notOk.Conflict(`Entity with id (${entity.id}) already exists`);
}
return notOk.GenericUnexpectedException(context, error);
});
if (createResult.isError())
return createResult;
const { id: entityId } = createResult.value;
return ok({ uuid, actualName: name, entityId });
});
}
//# sourceMappingURL=createEntity.js.map