lib.xp.content.ts Maven / Gradle / Ivy
The newest version!
/**
* Functions and constants to find and manipulate content.
*
* @example
* var contentLib = require('/lib/xp/content');
*
* @module content
*/
declare global {
interface XpLibraries {
'/lib/xp/content': typeof import('./content');
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface XpXData {}
}
import type {
Aggregations,
AggregationsResult,
AggregationsToAggregationResults,
ByteSource,
Content,
Filter,
FormItem,
Highlight,
HighlightResult,
PublishInfo,
QueryDsl,
SortDsl,
} from '@enonic-types/core';
const isString = (value: unknown): value is string => value instanceof String || typeof value === 'string';
const isNumber = (value: unknown): value is number => typeof value === 'number' && isFinite(value);
function checkRequiredString(obj: T, name: keyof T): void {
checkRequired(obj, name);
if (!isString(obj[name])) {
throw `Required parameter '${String(name)}' is not a string!`;
}
}
function checkOptionalString(obj: T, name: keyof T): void {
if (obj?.[name] != null && !isString(obj[name])) {
throw `Optional parameter '${String(name)}' is not a string!`;
}
}
function checkOptionalNumber(obj: T, name: keyof T): void {
if (obj?.[name] != null && !isNumber(obj[name])) {
throw `Optional parameter '${String(name)}' is not a number!`;
}
}
export type {
Aggregation,
Aggregations,
AggregationsResult,
Attachment,
BooleanDslExpression,
BooleanFilter,
Bucket,
BucketsAggregationResult,
BucketsAggregationsUnion,
ByteSource,
Component,
Content,
DateBucket,
DateHistogramAggregation,
DateRange,
DateRangeAggregation,
DistanceUnit,
DslOperator,
DslQueryType,
ExistsDslExpression,
ExistsFilter,
FieldSortDsl,
Filter,
FormItem,
FormItemInlineMixin,
FormItemInput,
FormItemLayout,
FormItemOptionSet,
FormItemSet,
FulltextDslExpression,
GeoDistanceAggregation,
GeoDistanceSortDsl,
GroupKey,
HasValueFilter,
Highlight,
HighlightResult,
HistogramAggregation,
IdsFilter,
InDslExpression,
InputType,
LikeDslExpression,
MatchAllDslExpression,
MaxAggregation,
MinAggregation,
NgramDslExpression,
NotExistsFilter,
NumericBucket,
NumericRange,
NumericRangeAggregation,
PathMatchDslExpression,
PublishInfo,
QueryDsl,
RangeDslExpression,
Region,
RoleKey,
SingleValueMetricAggregationResult,
SingleValueMetricAggregationsUnion,
SortDirection,
SortDsl,
StatsAggregation,
StatsAggregationResult,
StemmedDslExpression,
TermDslExpression,
TermsAggregation,
UserKey,
ValueCountAggregation,
ValueType,
} from '@enonic-types/core';
type Attachments = Content['attachments'];
type ContentInheritType = Content['inherit'];
type Workflow = Content['workflow'];
export type Schedule = Omit;
/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any*/
declare const Java: any;
export const ARCHIVE_ROOT_PATH = Java.type('com.enonic.xp.archive.ArchiveConstants').ARCHIVE_ROOT_PATH as string;
export const CONTENT_ROOT_PATH = Java.type('com.enonic.xp.content.ContentConstants').CONTENT_ROOT_PATH as string;
/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
function checkRequired(obj: T, name: keyof T): void {
if (obj == null || obj[name] == null) {
throw `Parameter '${String(name)}' is required`;
}
}
export interface GetContentParams {
key: string;
versionId?: string | null;
}
interface GetContentHandler {
setKey(value?: string): void;
setVersionId(value?: string | null): void;
execute>(): Hit | null;
}
interface GetAttachmentsHandler {
setKey(value?: string | null): void;
execute(): Attachments | null;
}
/**
* This function fetches a content.
*
* @example-ref examples/content/get.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {string} [params.versionId] Version Id of the content.
*
* @returns {object} The content (as JSON) fetched from the repository.
*/
export function get = Content>(params: GetContentParams): Hit | null {
checkRequired(params, 'key');
const bean = __.newBean('com.enonic.xp.lib.content.GetContentHandler');
bean.setKey(params.key);
bean.setVersionId(__.nullOrValue(params.versionId));
return __.toNativeObject(bean.execute());
}
/**
* This function returns a content attachments.
*
* @example-ref examples/content/getAttachments.js
*
* @param {string} key Path or id to the content.
*
* @returns {object} An object with all the attachments that belong to the content, where the key is the attachment name. Or null if the content cannot be found.
*/
export function getAttachments(key: string): Attachments | null {
const bean = __.newBean('com.enonic.xp.lib.content.GetAttachmentsHandler');
bean.setKey(__.nullOrValue(key));
return __.toNativeObject(bean.execute());
}
export interface GetAttachmentStreamParams {
key: string;
name: string;
}
interface GetAttachmentStreamHandler {
setKey(value: string): void;
setName(value: string): void;
getStream(): ByteSource | null;
}
/**
* This function returns a data-stream for the specified content attachment.
*
* @example-ref examples/content/getAttachmentStream.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {string} params.name Attachment name.
*
* @returns {*} Stream of the attachment data.
*/
export function getAttachmentStream(params: GetAttachmentStreamParams): ByteSource | null {
checkRequired(params, 'key');
checkRequired(params, 'name');
const bean = __.newBean('com.enonic.xp.lib.content.GetAttachmentStreamHandler');
bean.setKey(params.key);
bean.setName(params.name);
return bean.getStream();
}
export interface AddAttachmentParam {
key: string;
name: string;
mimeType: string;
data: ByteSource;
label?: string;
}
interface AddAttachmentHandler {
setKey(value: string): void;
setName(value: string): void;
setMimeType(value: string): void;
setData(value: ByteSource): void;
setLabel(value?: string | null): void;
execute(): void;
}
/**
* Adds an attachment to an existing content.
*
* @example-ref examples/content/addAttachment.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {string} params.name Attachment name.
* @param {string} params.mimeType Attachment content type.
* @param {string} [params.label] Attachment label.
* @param {object} params.data Stream with the binary data for the attachment.
*/
export function addAttachment(params: AddAttachmentParam): void {
checkRequired(params, 'key');
checkRequired(params, 'name');
checkRequired(params, 'mimeType');
checkRequired(params, 'data');
const bean = __.newBean('com.enonic.xp.lib.content.AddAttachmentHandler');
bean.setKey(params.key);
bean.setName(params.name);
bean.setMimeType(params.mimeType);
bean.setData(params.data);
bean.setLabel(__.nullOrValue(params.label));
bean.execute();
}
export interface RemoveAttachmentParams {
key: string;
name: string | string[];
}
interface RemoveAttachmentHandler {
setKey(value: string): void;
setName(value: string[]): void;
execute(): void;
}
/**
* Removes an attachment from an existing content.
*
* @example-ref examples/content/removeAttachment.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {string|string[]} params.name Attachment name, or array of names.
*/
export function removeAttachment(params: RemoveAttachmentParams): void {
checkRequired(params, 'key');
checkRequired(params, 'name');
const {
key,
name = [],
} = params ?? {};
const bean = __.newBean('com.enonic.xp.lib.content.RemoveAttachmentHandler');
bean.setKey(key);
bean.setName(([] as string[]).concat(name));
bean.execute();
}
export interface SiteConfig {
applicationKey: string;
config: Config;
}
export type Site = Content<{
description?: string;
siteConfig: SiteConfig | SiteConfig[];
}, 'portal:site'>;
export interface GetSiteParams {
key?: string | null;
}
interface GetSiteHandler {
setKey(value?: string | null): void;
execute(): Site | null;
}
/**
* This function returns the parent site of a content.
*
* @example-ref examples/content/getSite.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
*
* @returns {object} The current site as JSON.
*/
export function getSite>(params: GetSiteParams): Site | null {
checkRequired(params, 'key');
const bean = __.newBean('com.enonic.xp.lib.content.GetSiteHandler');
bean.setKey(params.key);
return __.toNativeObject(bean.execute());
}
export interface GetSiteConfigParams {
key: string;
applicationKey: string;
}
interface GetSiteConfigHandler {
setKey(value?: string | null): void;
setApplicationKey(value?: string | null): void;
execute(): Config | null;
}
/**
* This function returns the site configuration for this app in the parent site of a content.
*
* @example-ref examples/content/getSiteConfig.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {string} params.applicationKey Application key.
*
* @returns {object} The site configuration for current application as JSON.
*/
export function getSiteConfig>(params: GetSiteConfigParams): Config | null {
const bean = __.newBean('com.enonic.xp.lib.content.GetSiteConfigHandler');
bean.setKey(__.nullOrValue(params.key));
bean.setApplicationKey(__.nullOrValue(params.applicationKey));
return __.toNativeObject(bean.execute());
}
export interface DeleteContentParams {
key: string;
}
interface DeleteContentHandler {
setKey(value: string): void;
execute(): boolean;
}
/**
* This function deletes a content.
*
* @example-ref examples/content/delete.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
*
* @returns {boolean} True if deleted, false otherwise.
*/
function _delete(params: DeleteContentParams): boolean {
checkRequired(params, 'key');
const bean = __.newBean('com.enonic.xp.lib.content.DeleteContentHandler');
bean.setKey(params.key);
return bean.execute();
}
export {
_delete as delete,
};
export interface ContentsResult<
Hit extends Content,
AggregationOutput extends Record | undefined = undefined
> {
total: number;
count: number;
hits: Hit[];
aggregations: AggregationOutput;
highlight?: Record;
}
export interface GetChildContentParams {
key: string;
start?: number;
count?: number;
sort?: string;
}
interface GetChildContentHandler {
setKey(value: string): void;
setStart(value: number): void;
setCount(value: number): void;
setSort(value?: string | null): void;
execute<
Hit extends Content,
AggregationOutput extends Record
>(): ContentsResult;
}
/**
* This function fetches children of a content.
*
* @example-ref examples/content/getChildren.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the parent content.
* @param {number} [params.start=0] Start index (used for paging).
* @param {number} [params.count=10] Number of contents to fetch.
* @param {string} [params.sort] Sorting expression.
*
* @returns {Object} Result (of content) fetched from the repository.
*/
export function getChildren<
Hit extends Content = Content,
AggregationOutput extends Record = never
>(params: GetChildContentParams): ContentsResult {
checkRequired(params, 'key');
const {
key,
start = 0,
count = 10,
sort,
} = params ?? {};
const bean = __.newBean('com.enonic.xp.lib.content.GetChildContentHandler');
bean.setKey(key);
bean.setStart(start);
bean.setCount(count);
bean.setSort(__.nullOrValue(sort));
return __.toNativeObject(bean.execute());
}
export type IdGeneratorSupplier = (value: string) => string;
export interface CreateContentParams {
name?: string;
parentPath: string;
displayName?: string;
requireValid?: boolean;
refresh?: boolean;
contentType: Type;
language?: string;
childOrder?: string;
data: Data;
x?: XpXData;
idGenerator?: IdGeneratorSupplier;
workflow?: Workflow;
}
interface CreateContentHandler {
setName(value?: string | null): void;
setParentPath(value?: string | null): void;
setDisplayName(value?: string | null): void;
setContentType(value?: string | null): void;
setRequireValid(value?: boolean | null): void;
setRefresh(value?: boolean | null): void;
setLanguage(value?: string | null): void;
setChildOrder(value?: string | null): void;
setData(value: ScriptValue): void;
setX(value: ScriptValue): void;
setWorkflow(value: ScriptValue): void;
setIdGenerator(value?: IdGeneratorSupplier | string | null): void;
execute(): Content;
}
/**
* This function creates a content.
*
* The parameter `name` is optional, but if it is not set then `displayName` must be specified. When name is not set, the
* system will auto-generate a `name` based on the `displayName`, by lower-casing and replacing certain characters. If there
* is already a content with the auto-generated name, a suffix will be added to the `name` in order to make it unique.
*
* To create a content where the name is not important and there could be multiple instances under the same parent content,
* skip the `name` parameter and specify a `displayName`.
*
* @example-ref examples/content/create.js
*
* @param {object} params JSON with the parameters.
* @param {string} [params.name] Name of content.
* @param {string} params.parentPath Path to place content under.
* @param {string} [params.displayName] Display name. Default is same as `name`.
* @param {boolean} [params.requireValid=true] The content has to be valid, according to the content type, to be created. If requireValid=true and the content is not strictly valid, an error will be thrown.
* @param {boolean} [params.refresh=true] If refresh is true, the created content will to be searchable through queries immediately, else within 1 second. Since there is a performance penalty doing this refresh, refresh should be set to false for bulk operations.
* @param {string} params.contentType Content type to use.
* @param {string} [params.language] The language tag representing the content’s locale.
* @param {string} [params.childOrder] Default ordering of children when doing getChildren if no order is given in query
* @param {object} params.data Actual content data.
* @param {object} [params.x] eXtra data to use.
* @param {object} [params.workflow] Workflow information to use. Default has state READY and empty check list.
*
* @returns {object} Content created as JSON.
*/
export function create<
Data = Record,
Type extends string = string
>(params: CreateContentParams): Content {
const {
name,
parentPath,
displayName,
requireValid = true,
refresh = true,
contentType,
language,
childOrder,
data,
x,
idGenerator,
workflow,
} = params ?? {};
const bean = __.newBean('com.enonic.xp.lib.content.CreateContentHandler');
bean.setName(__.nullOrValue(name));
bean.setParentPath(__.nullOrValue(parentPath));
bean.setDisplayName(__.nullOrValue(displayName));
bean.setContentType(__.nullOrValue(contentType));
bean.setRequireValid(__.nullOrValue(requireValid));
bean.setRefresh(__.nullOrValue(refresh));
bean.setLanguage(__.nullOrValue(language));
bean.setChildOrder(__.nullOrValue(childOrder));
bean.setData(__.toScriptValue(data));
bean.setX(__.toScriptValue(x));
bean.setIdGenerator(__.nullOrValue(idGenerator));
bean.setWorkflow(__.toScriptValue(workflow));
return __.toNativeObject(bean.execute());
}
export interface QueryContentParams {
start?: number;
count?: number;
query?: QueryDsl | string;
sort?: string | SortDsl | SortDsl[];
filters?: Filter | Filter[];
aggregations?: AggregationInput;
contentTypes?: string[];
highlight?: Highlight;
}
interface QueryContentHandler {
setStart(value?: number | null): void;
setCount(value?: number | null): void;
setQuery(value: ScriptValue): void;
setSort(value: ScriptValue): void;
setAggregations(value: ScriptValue): void;
setContentTypes(value: ScriptValue): void;
setFilters(value: ScriptValue): void;
setHighlight(value: ScriptValue): void;
execute<
Hit extends Content,
AggregationInput extends Aggregations = never
>(): ContentsResult>;
}
/**
* This command queries content.
*
* @example-ref examples/content/query.js
*
* @param {object} params JSON with the parameters.
* @param {number} [params.start=0] Start index (used for paging).
* @param {number} [params.count=10] Number of contents to fetch.
* @param {string|object} params.query Query expression.
* @param {object|object[]} [params.filters] Filters to apply to query result
* @param {string|object|object[]} [params.sort] Sorting expression.
* @param {object} [params.aggregations] Aggregations expression.
* @param {string[]} [params.contentTypes] Content types to filter on.
*
* @returns {object} Result of query.
*/
export function query<
Hit extends Content = Content,
AggregationInput extends Aggregations = never
>(params: QueryContentParams): ContentsResult> {
const bean = __.newBean('com.enonic.xp.lib.content.QueryContentHandler');
bean.setStart(params.start);
bean.setCount(params.count);
bean.setQuery(__.toScriptValue((params.query)));
bean.setSort(__.toScriptValue(params.sort));
bean.setAggregations(__.toScriptValue(params.aggregations));
bean.setContentTypes(__.toScriptValue(params.contentTypes));
bean.setFilters(__.toScriptValue(params.filters));
bean.setHighlight(__.toScriptValue(params.highlight));
return __.toNativeObject(bean.execute());
}
export interface ModifyContentParams {
key: string;
editor: (v: Content) => Content;
requireValid?: boolean;
}
interface ModifyContentHandler {
setKey(value: string): void;
setEditor(value: ScriptValue): void;
setRequireValid(value: boolean): void;
execute(): Content | null;
}
/**
* This function modifies a content.
*
* @example-ref examples/content/modify.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {function} params.editor Editor callback function.
* @param {boolean} [params.requireValid=true] The content has to be valid, according to the content type, to be updated. If requireValid=true and the content is not strictly valid, an error will be thrown.
*
* @returns {object} Modified content as JSON.
*/
export function modify, Type extends string = string>(params: ModifyContentParams): Content | null {
checkRequired(params, 'key');
const {
key,
editor,
requireValid = true,
} = params ?? {};
const bean = __.newBean('com.enonic.xp.lib.content.ModifyContentHandler');
bean.setKey(key);
bean.setEditor(__.toScriptValue(editor));
bean.setRequireValid(requireValid);
return __.toNativeObject(bean.execute());
}
export interface PublishContentParams {
keys: string[];
schedule?: Schedule;
includeChildren?: boolean;
excludeChildrenIds?: string[];
includeDependencies?: boolean;
message?: string;
}
export interface PublishContentResult {
pushedContents: string[];
deletedContents: string[];
failedContents: string[];
}
interface PublishContentHandler {
setKeys(value: string[]): void;
setContentPublishInfo(value: ScriptValue): void;
setExcludeChildrenIds(value: string[]): void;
setIncludeChildren(value?: boolean): void;
setIncludeDependencies(value?: boolean): void;
setMessage(value?: string | null): void;
execute(): PublishContentResult;
}
/**
* This function publishes content from the draft branch to the master branch.
*
* @example-ref examples/content/publish.js
*
* @param {object} params JSON with the parameters.
* @param {string[]} params.keys List of all content keys(path or id) that should be published.
* to another, and publishing user content from master to draft is therefore also valid usage of this function, which may be practical if user input to a web-page is stored on master.
* @param {object} [params.schedule] Schedule the publish.
* @param {string} [params.schedule.from] Time from which the content is considered published. Defaults to the time of the publish
* @param {string} [params.schedule.to] Time until which the content is considered published.
* @param {string[]} [params.excludeChildrenIds] List of all content keys which children should be excluded from publishing content.
* @param {boolean} [params.includeDependencies=true] Whether all related content should be included when publishing content.
* @param {string} [params.message] Publish message.
*
* @returns {object} Status of the publish operation in JSON.
*/
export function publish(params: PublishContentParams): PublishContentResult {
checkRequired(params, 'keys');
const bean = __.newBean('com.enonic.xp.lib.content.PublishContentHandler');
bean.setKeys(params.keys);
if (params.schedule) {
bean.setContentPublishInfo(__.toScriptValue(params.schedule));
}
if (params.excludeChildrenIds) {
bean.setExcludeChildrenIds(params.excludeChildrenIds);
}
if (!__.nullOrValue(params.includeChildren)) {
// keep for backwards compatibility
bean.setIncludeChildren(params.includeChildren);
}
if (!__.nullOrValue(params.includeDependencies)) {
bean.setIncludeDependencies(params.includeDependencies);
}
bean.setMessage(__.nullOrValue(params.message));
return __.toNativeObject(bean.execute());
}
export interface UnpublishContentParams {
keys: string[];
}
interface UnpublishContentHandler {
setKeys(value: string[]): void;
execute(): string[];
}
/**
* This function unpublishes content that had been published to the master branch.
*
* @example-ref examples/content/unpublish.js
*
* @param {object} params JSON with the parameters.
* @param {string[]} params.keys List of all content keys(path or id) that should be unpublished.
*
* @returns {string[]} List with ids of the content that were unpublished.
*/
export function unpublish(params: UnpublishContentParams): string[] {
checkRequired(params, 'keys');
const bean = __.newBean('com.enonic.xp.lib.content.UnpublishContentHandler');
bean.setKeys(params.keys);
return __.toNativeObject(bean.execute());
}
export interface ContentExistsParams {
key: string;
}
interface ContentExistsHandler {
setKey(value: string): void;
execute(): boolean;
}
/**
* Check if content exists.
*
* @example-ref examples/content/exists.js
*
* @param {string} params.key content id.
*
* @returns {boolean} True if exist, false otherwise.
*/
export function exists(params: ContentExistsParams): boolean {
checkRequired(params, 'key');
const bean = __.newBean('com.enonic.xp.lib.content.ContentExistsHandler');
bean.setKey(params.key);
return __.toNativeObject(bean.execute());
}
export interface CreateMediaParams {
name: string;
parentPath?: string;
mimeType?: string;
focalX?: number;
focalY?: number;
data: ByteSource;
idGenerator?: (v: string) => string;
}
interface CreateMediaHandler {
setName(value: string): void;
setParentPath(value?: string | null): void;
setMimeType(value?: string | null): void;
setFocalX(value?: number): void;
setFocalY(value?: number): void;
setData(value?: ByteSource | null): void;
setIdGenerator(value?: IdGeneratorSupplier | null): void;
execute(): Content;
}
/**
* Creates a media content.
*
* @example-ref examples/content/createMedia.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.name Name of content.
* @param {string} [params.parentPath=/] Path to place content under.
* @param {string} [params.mimeType] Mime-type of the data.
* @param {number} [params.focalX=0.5] Focal point for X axis (if it's an image).
* @param {number} [params.focalY=0.5] Focal point for Y axis (if it's an image).
* @param params.data Data (as stream) to use.
*
* @returns {object} Returns the created media content.
*/
export function createMedia, Type extends string = string>(params: CreateMediaParams): Content {
checkRequired(params, 'name');
const bean = __.newBean('com.enonic.xp.lib.content.CreateMediaHandler');
bean.setName(params.name);
bean.setParentPath(__.nullOrValue(params.parentPath));
bean.setMimeType(__.nullOrValue(params.mimeType));
bean.setData(__.nullOrValue(params.data));
bean.setIdGenerator(__.nullOrValue(params.idGenerator));
if (params.focalX) {
bean.setFocalX(params.focalX);
}
if (params.focalY) {
bean.setFocalY(params.focalY);
}
return __.toNativeObject(bean.execute());
}
export interface MoveContentParams {
source: string;
target: string;
}
interface MoveContentHandler {
setSource(value: string): void;
setTarget(value: string): void;
execute(): Content;
}
/**
* Rename a content or move it to a new path.
*
* @example-ref examples/content/move.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.source Path or id of the content to be moved or renamed.
* @param {string} params.target New path or name for the content. If the target ends in slash '/', it specifies the parent path where to be moved. Otherwise it means the new desired path or name for the content.
*
* @returns {object} The content that was moved or renamed.
*/
export function move, Type extends string = string>(params: MoveContentParams): Content {
checkRequired(params, 'source');
checkRequired(params, 'target');
const bean = __.newBean('com.enonic.xp.lib.content.MoveContentHandler');
bean.setSource(params.source);
bean.setTarget(params.target);
return __.toNativeObject(bean.execute());
}
export interface ArchiveContentParams {
content: string;
}
interface ArchiveContentHandler {
setContent(value: string): void;
execute(): string[];
}
/**
* Archive a content.
*
* @example-ref examples/content/archive.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.content Path or id of the content to be archived.
*
* @returns {string[]} List with ids of the contents that were archived.
*/
export function archive(params: ArchiveContentParams): string[] {
checkRequired(params, 'content');
const bean = __.newBean('com.enonic.xp.lib.content.ArchiveContentHandler');
bean.setContent(params.content);
return __.toNativeObject(bean.execute());
}
export interface RestoreContentParams {
content: string;
path: string;
}
interface RestoreContentHandler {
setContent(value: string): void;
setPath(value?: string | null): void;
execute(): string[];
}
/**
* Restore a content from the archive.
*
* @example-ref examples/content/restore.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.content Path or id of the content to be restored.
* @param {string} params.path Path of parent for restored content.
*
* @returns {string[]} List with ids of the contents that were restored.
*/
export function restore(params: RestoreContentParams): string[] {
checkRequired(params, 'content');
const bean = __.newBean('com.enonic.xp.lib.content.RestoreContentHandler');
bean.setContent(params.content);
bean.setPath(__.nullOrValue(params.path));
return __.toNativeObject(bean.execute());
}
export type Permission = 'READ' | 'CREATE' | 'MODIFY' | 'DELETE' | 'PUBLISH' | 'READ_PERMISSIONS' | 'WRITE_PERMISSIONS';
export interface AccessControlEntry {
principal: string;
allow?: Permission[];
deny?: Permission[];
}
export interface SetPermissionsParams {
key: string;
inheritPermissions?: boolean;
overwriteChildPermissions?: boolean;
permissions?: AccessControlEntry[];
}
export interface Permissions {
inheritsPermissions: boolean;
permissions?: AccessControlEntry[];
}
interface SetPermissionsHandler {
setKey(value: string): void;
setInheritPermissions(value: boolean): void;
setOverwriteChildPermissions(value: boolean): void;
setPermissions(value: ScriptValue): void;
execute(): boolean;
}
/**
* Sets permissions on a content.
*
* @example-ref examples/content/setPermissions.js
*
* @param {object} params JSON parameters.
* @param {string} params.key Path or id of the content.
* @param {boolean} [params.inheritPermissions] Set to true if the content must inherit permissions. Default to false.
* @param {boolean} [params.overwriteChildPermissions] Set to true to overwrite child permissions. Default to false.
* @param {array} [params.permissions] Array of permissions.
* @param {string} params.permissions.principal Principal key.
* @param {array} params.permissions.allow Allowed permissions.
* @param {array} params.permissions.deny Denied permissions.
* @returns {boolean} True if successful, false otherwise.
*/
export function setPermissions(params: SetPermissionsParams): boolean {
const bean = __.newBean('com.enonic.xp.lib.content.SetPermissionsHandler');
if (params.key) {
bean.setKey(params.key);
}
if (params.inheritPermissions) {
bean.setInheritPermissions(params.inheritPermissions);
}
if (params.overwriteChildPermissions) {
bean.setOverwriteChildPermissions(params.overwriteChildPermissions);
}
if (params.permissions) {
bean.setPermissions(__.toScriptValue(params.permissions));
}
return __.toNativeObject(bean.execute());
}
export interface GetPermissionsParams {
key: string;
}
interface GetPermissionsHandler {
setKey(key: string): void;
execute(): Permissions | null;
}
/**
* Gets permissions on a content.
*
* @example-ref examples/content/getPermissions.js
*
* @param {object} params JSON parameters.
* @param {string} params.key Path or id of the content.
* @returns {object} Content permissions.
*/
export function getPermissions(params: GetPermissionsParams): Permissions | null {
const bean = __.newBean('com.enonic.xp.lib.content.GetPermissionsHandler');
if (params.key) {
bean.setKey(params.key);
}
return __.toNativeObject(bean.execute());
}
export interface Icon {
data: ByteSource;
mimeType: string;
modifiedTime: string;
}
/**
* @typedef ContentType
* @type Object
* @property {string} name Name of the content type.
* @property {string} displayName Display name of the content type.
* @property {string} description Description of the content type.
* @property {string} superType Name of the super type, or null if it has no super type.
* @property {boolean} abstract Whether or not content of this type may be instantiated.
* @property {boolean} final Whether or not it may be used as super type of other content types.
* @property {boolean} allowChildContent Whether or not allow creating child items on content of this type.
* @property {string} displayNameExpression ES6 string template for generating the content name based on values in the content form.
* @property {object} [icon] Icon of the content type.
* @property {object} [icon.data] Stream with the binary data for the icon.
* @property {string} [icon.mimeType] Mime type of the icon image.
* @property {string} [icon.modifiedTime] Modified time of the icon. May be used for caching.
* @property {object[]} form Form schema represented as an array of form items: Input, ItemSet, Layout, OptionSet.
*/
export interface ContentType {
name: string;
displayName: string;
description: string;
superType: string;
abstract: boolean;
final: boolean;
allowChildContent: boolean;
displayNameExpression: string;
modifiedTime: string;
icon?: Icon;
form: FormItem[];
}
interface ContentTypeHandler {
setName(value?: string | null): void;
getContentType(): ContentType | null;
getAllContentTypes(): ContentType[];
}
/**
* Returns the properties and icon of the specified content type.
*
* @example-ref examples/content/getType.js
*
* @param name Name of the content type, as 'app:name' (e.g. 'com.enonic.myapp:article').
* @returns {ContentType} The content type object if found, or null otherwise. See ContentType type definition below.
*/
export function getType(name: string): ContentType | null {
const bean = __.newBean('com.enonic.xp.lib.content.ContentTypeHandler');
bean.setName(__.nullOrValue(name));
return __.toNativeObject(bean.getContentType());
}
/**
* Returns the list of all the content types currently registered in the system.
*
* @example-ref examples/content/getTypes.js
*
* @returns {ContentType[]} Array with all the content types found. See ContentType type definition below.
*/
export function getTypes(): ContentType[] {
const bean = __.newBean('com.enonic.xp.lib.content.ContentTypeHandler');
return __.toNativeObject(bean.getAllContentTypes());
}
export interface GetOutboundDependenciesParams {
key: string;
}
interface GetOutboundDependenciesHandler {
setKey(value: string): void;
execute(): string[];
}
/**
* Returns outbound dependencies on a content.
*
* @param {object} params JSON parameters.
* @param {string} params.key Path or id of the content.
* @returns {object} Content Ids.
*/
export function getOutboundDependencies(params: GetOutboundDependenciesParams): string[] {
checkRequired(params, 'key');
const bean = __.newBean('com.enonic.xp.lib.content.GetOutboundDependenciesHandler');
bean.setKey(params.key);
return __.toNativeObject(bean.execute());
}
export interface ResetInheritanceParams {
key: string;
projectName: string;
inherit: ContentInheritType[];
}
export interface ResetInheritanceHandler {
setKey(value: string): void;
setProjectName(value: string): void;
setInherit(value: ContentInheritType[]): void;
execute(): void;
}
/** Resets dropped inherit flags back.
*
* @param {object} params JSON parameters.
* @param {string} params.key Path or id of the content.
* @param {string} params.projectName name of project with content.
* @param {string[]} params.inherit flags to be reset.
*/
export function resetInheritance(params: ResetInheritanceParams): void {
checkRequired(params, 'key');
checkRequired(params, 'projectName');
checkRequired(params, 'inherit');
const bean = __.newBean('com.enonic.xp.lib.content.ResetInheritanceHandler');
bean.setKey(params.key);
bean.setProjectName(params.projectName);
bean.setInherit(params.inherit);
bean.execute();
}
export interface ModifyMediaParams {
key: string;
name: string;
data: ByteSource;
artist?: string | string[];
caption?: string;
copyright?: string;
focalX?: number;
focalY?: number;
mimeType?: string;
tags?: string | string[];
workflow?: Workflow;
}
interface ModifyMediaHandler {
setKey(value: string): void;
setName(value: string): void;
setData(value: ByteSource): void;
setFocalX(value: number): void;
setFocalY(value: number): void;
setArtist(value: string[]): void;
setCaption(value?: string | null): void;
setCopyright(value?: string | null): void;
setMimeType(value?: string | null): void;
setTags(value: string[]): void;
setWorkflow(value: ScriptValue): void;
execute(): Content;
}
/** This function modifies a media content.
*
* @example-ref examples/content/modifyMedia.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.key Path or id to the content.
* @param {string} params.name Name to the content.
* @param {function} params.data Data (as stream) to use.
* @param {string} [params.mimeType] Mime-type of the data.
* @param {string|string[]} [params.artist] Artist to the content.
* @param {string} [params.caption] Caption to the content.
* @param {string} [params.copyright] Copyright to the content.
* @param {string|string[]} [params.tags] Tags to the content.
* @param {object} [params.workflow] Workflow information to use. Default has state READY and empty check list.
* @param {number} [params.focalX=0.5] Focal point for X axis (if it's an image).
* @param {number} [params.focalY=0.5] Focal point for Y axis (if it's an image).
*
* @returns {object} Modified content as JSON.
*/
export function modifyMedia, Type extends string = string>(params: ModifyMediaParams): Content | null {
checkRequired(params, 'data');
checkRequiredString(params, 'key');
checkRequiredString(params, 'name');
checkOptionalString(params, 'caption');
checkOptionalString(params, 'copyright');
checkOptionalString(params, 'mimeType');
checkOptionalNumber(params, 'focalX');
checkOptionalNumber(params, 'focalY');
const {
data,
key,
name,
caption,
copyright,
mimeType,
focalX,
focalY,
workflow,
artist = [],
tags = [],
} = params;
const bean = __.newBean('com.enonic.xp.lib.content.ModifyMediaHandler');
bean.setKey(key);
bean.setName(name);
bean.setData(data);
bean.setCaption(__.nullOrValue(caption));
bean.setCopyright(__.nullOrValue(copyright));
bean.setMimeType(__.nullOrValue(mimeType));
bean.setWorkflow(__.toScriptValue(workflow));
bean.setArtist(([] as string[]).concat(artist));
bean.setTags(([] as string[]).concat(tags));
if (params.focalX != null) {
bean.setFocalX(focalX);
}
if (params.focalY != null) {
bean.setFocalY(focalY);
}
return __.toNativeObject(bean.execute());
}
export interface DuplicateContentParams {
contentId: string;
workflow?: Workflow;
includeChildren?: boolean;
variant?: boolean;
parent?: string;
name?: string;
}
export interface DuplicateContentsResult {
contentName: string;
sourceContentPath: string;
duplicatedContents: string[];
}
interface DuplicateContentHandler {
setContentId(value: string): void;
setWorkflow(value: ScriptValue): void;
setIncludeChildren(value: boolean);
setVariant(value: boolean);
setName(value?: string);
setParentPath(value?: string);
execute(): DuplicateContentsResult;
}
/** This function duplicates a content.
*
* @example-ref examples/content/duplicate.js
*
* @param {object} params JSON with the parameters.
* @param {string} params.contentId Id to the content.
* @param {object} [params.workflow] Workflow information to use. Default has state READY and empty check list.
* @param {boolean} [params.includeChildren=true] Indicates that children contents must be duplicated, too. Default value `true`. Ignored if `variant=true`.
* @param {boolean} [params.variant=false] Indicates that duplicated content is a variant. Default value `false`.
* @param {string} [params.parent] Destination parent path. By default, a duplicated content will be added as a sibling of the source content.
* @param {string} [params.name] New content name.
*
* @returns {object} summary about duplicated content.
*/
export function duplicate(params: DuplicateContentParams): DuplicateContentsResult {
checkRequired(params, 'contentId');
const {
contentId,
workflow,
includeChildren = true,
variant = false,
parent,
name,
} = params ?? {};
const bean = __.newBean('com.enonic.xp.lib.content.DuplicateContentHandler');
bean.setContentId(contentId);
bean.setWorkflow(__.toScriptValue(workflow));
bean.setName(__.nullOrValue(name));
bean.setParentPath(__.nullOrValue(parent));
bean.setIncludeChildren(includeChildren);
bean.setVariant(variant);
return __.toNativeObject(bean.execute());
}