semantic-network
Version:
A utility library for manipulating a list of links that form a semantic interface to a network of resources.
105 lines • 4.83 kB
JavaScript
import { __awaiter } from "tslib";
import { instanceOfLinkedRepresentation, LinkUtil, } from 'semantic-link';
import { TrackedRepresentationFactory } from './trackedRepresentationFactory';
import anylogger from 'anylogger';
import { SparseRepresentationFactory } from './sparseRepresentationFactory';
import { LinkRelation } from '../linkRelation';
import { defaultAddToCollectionStrategy, defaultCreateFormStrategy } from './createFormMergeStrategy';
import { ApiUtil } from '../apiUtil';
import { instanceOfCollection } from '../utils/instanceOf/instanceOfCollection';
import { instanceOfForm } from '../utils/instanceOf/instanceOfForm';
const log = anylogger('create');
/**
*
* TODO: accept but don't require TrackedRepresentation interface
*
* @throws HttpRequestError
*/
export function create(document, options) {
return __awaiter(this, void 0, void 0, function* () {
if (!document) {
log.debug('No document provided to create');
return;
}
const { createContext, rel = LinkRelation.Self, } = Object.assign({}, options);
if (createContext) {
if (instanceOfCollection(createContext)) {
return yield createCollectionItem(createContext, document, options);
}
else {
log.warn('option \'createContext\' options cannot be used outside of a collection, skipping');
// fall through and keep processing
}
}
if (!instanceOfLinkedRepresentation(document)) {
const uri = LinkUtil.getUri(document, rel);
if (!uri) {
log.warn('no uri found on rel \'%s\' on resource create', rel);
}
return SparseRepresentationFactory.make(Object.assign(Object.assign({}, options), { uri }));
}
throw new Error('create options not satisfied');
});
}
/**
*
* @param resource
* @param document
* @param options
* @throws HttpRequestError
*/
function createCollectionItem(resource, document, options) {
return __awaiter(this, void 0, void 0, function* () {
const { mergeStrategy = defaultCreateFormStrategy, formRel = [LinkRelation.CreateForm, LinkRelation.SearchForm], addItemToCollectionDirectionType = 'append', addItemToCollectionStrategy = defaultAddToCollectionStrategy, throwOnCreateError, } = Object.assign({}, options);
const form = yield ApiUtil.get(resource, Object.assign(Object.assign({}, options), { rel: formRel })) /*as FormRepresentation*/;
/*
* TODO
* TODO: Upgrade to load reference collections inside form items. Note: use FormItemsUtil
* TODO
*
* The problem is that a previously loaded form is overwritten with the get above and items from a reference
* collection are removed.
* - needs a merge on existing items
* - refresh on items existing items (with merge)
*/
if (instanceOfForm(form)) {
try {
const mergedDocument = yield mergeStrategy(document, form, options);
if (mergedDocument) {
/*
* Choose where to get the uri from in cascading order:
* - form with submit, use submit href on the form
* - otherwise, Self link on the collection itself
*/
const hasSubmitRel = LinkUtil.matches(form, LinkRelation.Submit);
const contextResource = hasSubmitRel ? form : resource;
const rel = hasSubmitRel ? LinkRelation.Submit : LinkRelation.Self;
const item = yield TrackedRepresentationFactory.create(contextResource, mergedDocument, Object.assign(Object.assign({}, options), { rel }));
// 201 will return an item compared with 200, 202
if (item) {
addItemToCollectionStrategy(resource, item, addItemToCollectionDirectionType);
return item;
} // drop through and return undefined
}
else {
log.info('No create required %s', LinkUtil.getUri(resource, LinkRelation.Self));
}
}
catch (e) {
if (typeof e === 'string') {
log.error('[Merge] unknown create error %s', e);
}
else {
log.error('[Merge] unknown create error %o', e);
}
if (throwOnCreateError) {
throw e;
}
}
}
else {
log.info('Create not possible - resource has no form %s', LinkUtil.getUri(resource, LinkRelation.Self));
}
});
}
//# sourceMappingURL=create.js.map