UNPKG

@kwiz/common

Version:

KWIZ common utilities and helpers for M365 platform

997 lines 56.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RestoreListPermissionInheritance = exports.ListHasUniquePermissions = exports.ReloadListLastModified = exports.GetListLastItemModifiedDate = exports.DeleteListEventReceiver = exports.AddListEventReceiver = exports.GetListEventReceivers = exports.FindListItemById = exports.GetListItemsSync = exports.GetListItems = exports.GetFieldSchema = exports.GetFieldSchemaSync = exports.GetListFormUrl = exports.GetListContentTypesSync = exports.GetListContentTypes = exports.RemoveViewFieldFromListView = exports.AddViewFieldToListView = exports.GetListViewsSync = exports.GetListViews = exports.DeleteField = exports.ChangeDatetimeFieldMode = exports.ChangeTextFieldMode = exports.UpdateField = exports.CreateField = exports.UserHasPermissionsSync = exports.UserHasPermissions = exports.UserHasEditPermissions = exports.UserHasManagePermissions = exports.GetListEffectiveBasePermissionsSync = exports.GetListEffectiveBasePermissions = exports.GetListWorkflows = exports.GetListFieldsAsHashSync = exports.GetListFieldsAsHash = exports.GetListFieldsSync = exports.GetListFields = exports.GetStandardListFields = exports.GetListField = exports.GetListRootFolderSync = exports.GetListRootFolder = exports.GetListName = exports.GetListNameSync = exports.GetListSync = exports.GetList = exports.GetListTitle = exports.GetSiteAssetLibrary = exports.EnsureSitePagesLibrary = exports.EnsureAssetLibrary = exports.GetListIdFromPageSync = exports.GetListId = exports.GetListRestUrl = void 0; exports.SetListVersionSettings = exports.GetListVersionSettings = exports.UpdateListExperience = exports.SearchList = exports.CreateList = exports.RemoveListPermission = exports.AssignListPermission = exports.BreakListPermissionInheritance = void 0; const exports_index_1 = require("../../exports-index"); const collections_base_1 = require("../../helpers/collections.base"); const json_1 = require("../../helpers/json"); const sharepoint_1 = require("../../helpers/sharepoint"); const strings_1 = require("../../helpers/strings"); const typecheckers_1 = require("../../helpers/typecheckers"); const url_1 = require("../../helpers/url"); const rest_types_1 = require("../../types/rest.types"); const sharepoint_types_1 = require("../../types/sharepoint.types"); const consolelogger_1 = require("../consolelogger"); const rest_1 = require("../rest"); const common_1 = require("./common"); const common_2 = require("./listutils/common"); const web_1 = require("./web"); const logger = consolelogger_1.ConsoleLogger.get("SharePoint.Rest.List"); /** returns /_api/web/lists/getById() or /_api/web/lists/getByTitle() */ function GetListRestUrl(siteUrl, listIdOrTitle) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let listId = GetListId(siteUrl, listIdOrTitle); let listPart = (0, typecheckers_1.isValidGuid)(listId) ? `getById('${(0, strings_1.normalizeGuid)(listId)}')` : `getByTitle('${encodeURIComponent(listIdOrTitle)}')`; return (0, common_1.GetRestBaseUrl)(siteUrl) + `/web/lists/${listPart}`; } exports.GetListRestUrl = GetListRestUrl; function GetListId(siteUrl, listIdOrTitle) { if ((0, typecheckers_1.isNullOrEmptyString)(listIdOrTitle)) return null; if ((0, typecheckers_1.isValidGuid)(listIdOrTitle)) return listIdOrTitle; //Issue 7508 //When translation is enabled, and user changes list title but he is not on the same language as the site //he translates the list, but not changing its title //so REST api /lists/getByTitle will not work //instead, we need to get the list id from the web's lists collection. let lists = (0, web_1.GetListsSync)(siteUrl); var lower = listIdOrTitle.toLowerCase(); var list = (0, collections_base_1.firstOrNull)(lists, l => l.Title.toLowerCase() === lower); return list && list.Id || null; } exports.GetListId = GetListId; /** get the list ID from a list page, such as a list view or an item form */ function GetListIdFromPageSync(siteUrl, listPageUrl) { let url = `${(0, common_1.GetRestBaseUrl)(siteUrl)}/web/getlist('${(0, url_1.makeServerRelativeUrl)(listPageUrl.split('?')[0].split('#')[0])}')?$select=id`; let response = (0, rest_1.GetJsonSync)(url, null, { ...rest_1.longLocalCache, jsonMetadata: rest_types_1.jsonTypes.nometadata }); if (!(0, typecheckers_1.isNullOrUndefined)(response) && response.success) { let listId = response.result.Id; return (0, strings_1.normalizeGuid)(listId); } return null; } exports.GetListIdFromPageSync = GetListIdFromPageSync; /** ensures the site assets library exists and return its info. on errors - it will return null. */ function EnsureAssetLibrary(siteUrl) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let url = (0, common_1.GetRestBaseUrl)(siteUrl) + "/web/lists/EnsureSiteAssetsLibrary?$select=ID,RootFolder/Name,RootFolder/ServerRelativeUrl,RootFolder/Exists&$expand=RootFolder"; return (0, rest_1.GetJson)(url, null, { method: "POST", spWebUrl: siteUrl, ...rest_1.longLocalCache }).then(result => { if (result && result.d) { return { Id: result.d.Id, Name: result.d.RootFolder.Name, ServerRelativeUrl: result.d.RootFolder.ServerRelativeUrl }; } else return null; }).catch(() => null); } exports.EnsureAssetLibrary = EnsureAssetLibrary; /** ensures the site pages library exists and return its info. on errors - it will return null. */ async function EnsureSitePagesLibrary(siteUrl) { let url = `${(0, common_1.GetRestBaseUrl)(siteUrl)}/web/lists/EnsureSitePagesLibrary` + `?$select=ID,RootFolder/Name,RootFolder/ServerRelativeUrl,RootFolder/Exists&$expand=RootFolder`; let response = await (0, rest_1.GetJson)(url, null, { method: "POST", jsonMetadata: rest_types_1.jsonTypes.nometadata, includeDigestInPost: true, ...rest_1.longLocalCache }); if (!(0, typecheckers_1.isNullOrUndefined)(response) && !(0, typecheckers_1.isNullOrUndefined)(response.RootFolder)) { return { Id: response.Id, Name: response.RootFolder.Name, ServerRelativeUrl: response.RootFolder.ServerRelativeUrl }; } return null; } exports.EnsureSitePagesLibrary = EnsureSitePagesLibrary; function GetSiteAssetLibrary(siteUrl, sync) { let reqUrl = `${(0, common_1.GetRestBaseUrl)(siteUrl)}/web/lists?` //Issue 1492: isSiteAssetsLibrary eq true does not work for reader users. //+ `$filter=isSiteAssetsLibrary eq true&$select=ID,RootFolder/Name,RootFolder/ServerRelativeUrl,RootFolder/Exists` + `$filter=EntityTypeName%20eq%20%27SiteAssets%27&$select=ID,RootFolder/Name,RootFolder/ServerRelativeUrl,RootFolder/Exists` + `&$expand=RootFolder`; let caller = sync ? rest_1.GetJsonSync : rest_1.GetJson; let result = caller(reqUrl, null, { ...rest_1.longLocalCache, jsonMetadata: rest_types_1.jsonTypes.nometadata }); let transform = (v) => { if ((0, typecheckers_1.isNotEmptyArray)(v && v.value)) { let assetLibrary = v.value[0]; return { Id: assetLibrary.Id, Name: assetLibrary.RootFolder.Name, ServerRelativeUrl: assetLibrary.RootFolder.ServerRelativeUrl }; } return null; }; if ((0, typecheckers_1.isPromise)(result)) return result.then(r => transform(r), () => null); else return result.success ? transform(result.result) : null; } exports.GetSiteAssetLibrary = GetSiteAssetLibrary; /** Return the list Title */ function GetListTitle(siteUrl, listIdOrTitle) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); return (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/Title`, null, { allowCache: true }) .then(r => { return r.d.Title; }) .catch(() => null); } exports.GetListTitle = GetListTitle; /** Return the list */ function GetList(siteUrlOrId, listIdOrTitle, options, refreshCache = false) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); if ((0, typecheckers_1.isNullOrEmptyString)(listIdOrTitle)) { return null; } return (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `?$select=${common_1.LIST_SELECT}&$expand=${common_1.LIST_EXPAND}`, null, { allowCache: true }) .then(async (r) => { let list = r.d; if (options) { let promises = []; if (options.includeViews) { promises.push(GetListViews(siteUrl, listIdOrTitle, options.viewOptions, refreshCache).then((r) => { list.Views = r; })); } if (options.includeContentTypes) { promises.push(GetListContentTypes(siteUrl, listIdOrTitle, null, refreshCache).then((r) => { list.ContentTypes = r; })); } if (options.includeRootFolder) { promises.push(GetListRootFolder(siteUrl, listIdOrTitle).then((r) => { list.RootFolder = r; })); } if (options.includeEventReceivers) { promises.push(GetListEventReceivers(siteUrl, listIdOrTitle, refreshCache).then((r) => { list.EventReceivers = r; })); } if (promises.length > 0) { await Promise.all(promises); } } if (list.EffectiveBasePermissions && ((0, typecheckers_1.isString)(list.EffectiveBasePermissions.High) || (0, typecheckers_1.isString)(list.EffectiveBasePermissions.Low))) { list.EffectiveBasePermissions = { High: Number(list.EffectiveBasePermissions.High), Low: Number(list.EffectiveBasePermissions.Low) }; } return list; }) .catch(() => null); } exports.GetList = GetList; /** Return the list */ function GetListSync(siteUrl, listIdOrTitle) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); if ((0, typecheckers_1.isNullOrEmptyString)(listIdOrTitle)) return null; let result = (0, rest_1.GetJsonSync)(GetListRestUrl(siteUrl, listIdOrTitle) + `?$select=${common_1.LIST_SELECT}&$expand=${common_1.LIST_EXPAND}`, null, rest_1.shortLocalCache); if (result && result.success) { let list = result.result.d; if (list.EffectiveBasePermissions && ((0, typecheckers_1.isString)(list.EffectiveBasePermissions.High) || (0, typecheckers_1.isString)(list.EffectiveBasePermissions.Low))) { list.EffectiveBasePermissions = { High: Number(list.EffectiveBasePermissions.High), Low: Number(list.EffectiveBasePermissions.Low) }; } return list; } else return null; } exports.GetListSync = GetListSync; function GetListNameSync(webUrl, listIdOrTitle) { let list = GetListSync(webUrl, listIdOrTitle); return (0, sharepoint_1.NormalizeListName)({ EntityTypeName: list.EntityTypeName, BaseType: list.BaseType }); } exports.GetListNameSync = GetListNameSync; async function GetListName(webUrl, listIdOrTitle) { let list = await GetList(webUrl, listIdOrTitle); return (0, sharepoint_1.NormalizeListName)({ EntityTypeName: list.EntityTypeName, BaseType: list.BaseType }); } exports.GetListName = GetListName; function GetListRootFolder(siteUrlOrId, listIdOrTitle) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); return (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/RootFolder?$Select=Name,ServerRelativeUrl`, null, rest_1.longLocalCache) .then(r => { return r.d; }) .catch(() => null); } exports.GetListRootFolder = GetListRootFolder; function GetListRootFolderSync(siteUrlOrId, listIdOrTitle) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let result = (0, rest_1.GetJsonSync)(GetListRestUrl(siteUrl, listIdOrTitle) + `/RootFolder?$Select=Name,ServerRelativeUrl`, null, rest_1.longLocalCache); return (0, typecheckers_1.SafeIfElse)(() => result.result.d, null); } exports.GetListRootFolderSync = GetListRootFolderSync; function GetListField(siteUrlOrId, listIdOrTitle, fieldIdOrName, refreshCache) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); var url = GetListRestUrl(siteUrl, listIdOrTitle) + `/fields`; if ((0, typecheckers_1.isValidGuid)(fieldIdOrName)) { url += `('${(0, strings_1.normalizeGuid)(fieldIdOrName)}')`; } else { url += `/getbyinternalnameortitle(@u)?@u='${encodeURIComponent(fieldIdOrName)}'`; } let result = (0, rest_1.GetJson)(url, null, { allowCache: refreshCache !== true }) .then(r => { return r.d; }) .catch(() => null); return result; } exports.GetListField = GetListField; function _getListFieldsRequestUrl(siteUrl, listIdOrTitle) { return GetListRestUrl(siteUrl, listIdOrTitle) + `/fields`; } /** Gets ID, Title, ContentType Author, Editor, Created and Modified fields */ function GetStandardListFields(siteUrlOrId, listIdOrTitle, refreshCache) { let fieldNames = ["ID", "Title", "ContentType", "Author", "Editor", "Created", "Modified"]; return GetListFields(siteUrlOrId, listIdOrTitle, { refreshCache: refreshCache, fieldNames: fieldNames }); } exports.GetStandardListFields = GetStandardListFields; function _processGetListFields(fields, fieldNames) { if ((0, typecheckers_1.isNullOrEmptyArray)(fields)) { return fields; } let extendedFields = (0, sharepoint_1.extendFieldInfos)(fields); if (!(0, typecheckers_1.isNullOrEmptyArray)(fieldNames)) { return extendedFields.filter((extendedField) => { return fieldNames.includes(extendedField.InternalName); }); } return extendedFields; } function GetListFields(siteUrlOrId, listIdOrTitle, options = {}) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let url = _getListFieldsRequestUrl(siteUrl, listIdOrTitle); let restOptions = { allowCache: options.refreshCache !== true, jsonMetadata: rest_types_1.jsonTypes.nometadata }; return (0, rest_1.GetJson)(url, null, restOptions) .then((result) => { return _processGetListFields(result.value, options.fieldNames); }).catch(() => { return null; }); } exports.GetListFields = GetListFields; function GetListFieldsSync(siteUrlOrId, listIdOrTitle, options = {}) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let url = _getListFieldsRequestUrl(siteUrl, listIdOrTitle); let restOptions = { allowCache: options.refreshCache !== true, jsonMetadata: rest_types_1.jsonTypes.nometadata }; let result = (0, rest_1.GetJsonSync)(url, null, restOptions); if (result.success && !(0, typecheckers_1.isNullOrUndefined)(result.result)) { return _processGetListFields(result.result.value, options.fieldNames); } return null; } exports.GetListFieldsSync = GetListFieldsSync; async function GetListFieldsAsHash(siteUrlOrId, listIdOrTitle, refreshCache) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let fields = await GetListFields(siteUrl, listIdOrTitle, { refreshCache: refreshCache }); let hash = {}; if ((0, typecheckers_1.isNotEmptyArray)(fields)) { hash = (0, collections_base_1.toHash)(fields, f => f.InternalName); } return hash; } exports.GetListFieldsAsHash = GetListFieldsAsHash; function GetListFieldsAsHashSync(siteUrlOrId, listIdOrTitle, refreshCache) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let fields = GetListFieldsSync(siteUrl, listIdOrTitle, { refreshCache: refreshCache }); let hash = {}; if ((0, typecheckers_1.isNotEmptyArray)(fields)) { fields.forEach(f => { hash[f.InternalName] = f; }); } return hash; } exports.GetListFieldsAsHashSync = GetListFieldsAsHashSync; function GetListWorkflows(siteUrl, listIdOrTitle, refreshCache) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); return (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/workflowAssociations`, null, { allowCache: refreshCache !== true }) .then(r => { if (r && r.d && (0, typecheckers_1.isNotEmptyArray)(r.d.results)) { r.d.results.forEach(wf => { wf.BaseId = (0, strings_1.normalizeGuid)(wf.BaseId); wf.Id = (0, strings_1.normalizeGuid)(wf.Id); wf.ListId = (0, strings_1.normalizeGuid)(wf.ListId); wf.WebId = (0, strings_1.normalizeGuid)(wf.WebId); }); return r.d.results; } else return []; }) .catch(() => []); } exports.GetListWorkflows = GetListWorkflows; async function GetListEffectiveBasePermissions(siteUrlOrId, listIdOrTitle) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let response = await (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/EffectiveBasePermissions`, null, { ...rest_1.shortLocalCache }); return response.d.EffectiveBasePermissions; } exports.GetListEffectiveBasePermissions = GetListEffectiveBasePermissions; function GetListEffectiveBasePermissionsSync(siteUrlOrId, listIdOrTitle) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let response = (0, rest_1.GetJsonSync)(GetListRestUrl(siteUrl, listIdOrTitle) + `/EffectiveBasePermissions`, null, { ...rest_1.shortLocalCache }); return response.result.d.EffectiveBasePermissions; } exports.GetListEffectiveBasePermissionsSync = GetListEffectiveBasePermissionsSync; function UserHasManagePermissions(siteUrlOrId, listIdOrTitle) { return GetListEffectiveBasePermissions(siteUrlOrId, listIdOrTitle).then((effectiveBasePermissions) => { return new sharepoint_1.SPBasePermissions(effectiveBasePermissions).has(sharepoint_types_1.SPBasePermissionKind.ManageLists); }).catch(() => null); } exports.UserHasManagePermissions = UserHasManagePermissions; function UserHasEditPermissions(siteUrlOrId, listIdOrTitle) { return UserHasPermissions(siteUrlOrId, listIdOrTitle, sharepoint_types_1.SPBasePermissionKind.EditListItems); } exports.UserHasEditPermissions = UserHasEditPermissions; function UserHasPermissions(siteUrlOrId, listIdOrTitle, permissionKind) { return GetListEffectiveBasePermissions(siteUrlOrId, listIdOrTitle).then((effectiveBasePermissions) => { return new sharepoint_1.SPBasePermissions(effectiveBasePermissions).has(permissionKind); }).catch(() => null); } exports.UserHasPermissions = UserHasPermissions; function UserHasPermissionsSync(siteUrlOrId, listIdOrTitle, permissionKind) { let effectiveBasePermissions = GetListEffectiveBasePermissionsSync(siteUrlOrId, listIdOrTitle); return new sharepoint_1.SPBasePermissions(effectiveBasePermissions).has(permissionKind); } exports.UserHasPermissionsSync = UserHasPermissionsSync; /** create a new column and try to add it to default view. Send either Title and Type, or SchemaXml. Create with SchemaXml also adds to all content types */ async function CreateField(siteUrl, listIdOrTitle, options) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let finish = async (result) => { if (!result) { return null; } let internalName = result.InternalName; //we need to clear and reload the list fields cache, so call it and return our field from that collection. let fields = await GetListFields(siteUrl, listIdOrTitle, { refreshCache: true }); try { if (options.SkipAddToDefaultView !== true) { //try to add it to default view, don't wait for it GetListViews(siteUrl, listIdOrTitle).then(views => { let defaultView = (0, collections_base_1.firstOrNull)(views, v => v.DefaultView); if (defaultView) (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/views('${defaultView.Id}')/ViewFields/addViewField('${internalName}')`, null, { method: "POST", spWebUrl: siteUrl }); }); } } catch (e) { } return (0, collections_base_1.firstOrNull)(fields, f => f.InternalName === internalName); }; if (!(0, typecheckers_1.isNullOrEmptyString)(options.SchemaXml)) { try { let updateObject = { 'parameters': { '__metadata': { 'type': 'SP.XmlSchemaFieldCreationInformation' }, 'SchemaXml': options.SchemaXml, 'Options': options.SchemaXmlSpecificInternalName !== true ? 4 : //SP.AddFieldOptions.addToAllContentTypes 4 | 8 //SP.AddFieldOptions.addToAllContentTypes | addFieldInternalNameHint } }; let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/fields/createFieldAsXml`; let newFieldResult = await (0, rest_1.GetJson)(url, JSON.stringify(updateObject)); if (!(0, typecheckers_1.isNullOrUndefined)(newFieldResult) && !(0, typecheckers_1.isNullOrUndefined)(newFieldResult.d)) { if ((!(0, typecheckers_1.isNullOrEmptyString)(options.Title) && options.Title !== newFieldResult.d.Title) || ((0, typecheckers_1.isBoolean)(options.Indexed) && options.Indexed !== newFieldResult.d.Indexed)) { let updatedField = await UpdateField(siteUrl, listIdOrTitle, newFieldResult.d.InternalName, { Title: options.Title, Indexed: options.Indexed === true }); return finish(updatedField); } } return finish(newFieldResult && newFieldResult.d); } catch { } return null; } else if (!(0, typecheckers_1.isNullOrEmptyString)(options.Title) && !(0, typecheckers_1.isNullOrUndefined)(options.Type)) { let updateObject = { '__metadata': { 'type': 'SP.Field' }, 'Title': options.Title, 'FieldTypeKind': options.Type, 'Required': options.Required === true, 'Indexed': options.Indexed === true }; if (!(0, typecheckers_1.isNullOrEmptyString)(options.ClientSideComponentId)) { updateObject.ClientSideComponentId = options.ClientSideComponentId; } if (!(0, typecheckers_1.isNullOrEmptyString)(options.ClientSideComponentProperties)) { updateObject.ClientSideComponentProperties = options.ClientSideComponentProperties; } if (!(0, typecheckers_1.isNullOrEmptyString)(options.JSLink)) { updateObject.JSLink = options.JSLink; } try { let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/fields`; let newFieldResult = await (0, rest_1.GetJson)(url, JSON.stringify(updateObject)); return finish(newFieldResult && newFieldResult.d); } catch { } return null; } else { console.error("You must send either SchemaXml or Title and Type"); return null; } } exports.CreateField = CreateField; /** Update field SchemaXml OR Title, only 1 update at a time supported. */ async function UpdateField(siteUrlOrId, listIdOrTitle, fieldInternalName, options) { let siteUrl = (0, common_1.GetSiteUrl)(siteUrlOrId); let finish = async () => { //we need to clear and reload the list fields cache, so call it and return our field from that collection. let fields = await GetListFields(siteUrl, listIdOrTitle, { refreshCache: true }); return (0, collections_base_1.firstOrNull)(fields, f => f.InternalName === fieldInternalName); }; let fields = await GetListFieldsAsHash(siteUrl, listIdOrTitle, true); let thisField = fields[fieldInternalName]; //updates can either be SchemaXml, or others. Cannot be both. let updates = { '__metadata': { 'type': 'SP.Field' } }; if (!(0, typecheckers_1.isNullOrEmptyString)(options.SchemaXml)) { updates.SchemaXml = options.SchemaXml; } else { //cannot send schema updates with other updates. if (!(0, typecheckers_1.isNullOrEmptyString)(options.Title)) { updates.Title = options.Title; } if (!(0, typecheckers_1.isNullOrEmptyString)(options.FieldType)) { updates.TypeAsString = options.FieldType; } if ((0, typecheckers_1.isBoolean)(options.Required)) { updates.Required = options.Required === true; } if ((0, typecheckers_1.isBoolean)(options.Indexed)) { updates.Indexed = options.Indexed === true; } if (!(0, typecheckers_1.isNullOrEmptyArray)(options.Choices)) { let choiceType = options.FieldType || thisField.TypeAsString; if (choiceType === "Choice" || choiceType === "MultiChoice") { updates["__metadata"]["type"] = choiceType === "Choice" ? "SP.FieldChoice" : "SP.FieldMultiChoice"; updates.Choices = { "results": options.Choices }; } else { logger.warn("Can only update 'Choices' property on 'Choice' and 'MultiChoice' field types."); } } if ((0, typecheckers_1.isBoolean)(options.Hidden)) { //this requries the CanToggleHidden to be in the schema... if not - we will need to add it before we can update this. let fields = await GetListFieldsAsHash(siteUrl, listIdOrTitle, false); let thisField = fields[fieldInternalName]; if (thisField.Hidden !== options.Hidden) { if (thisField) { if (thisField.SchemaJson.Attributes.CanToggleHidden !== "TRUE") { await UpdateField(siteUrl, listIdOrTitle, fieldInternalName, { SchemaXml: thisField.SchemaXml.replace("<Field ", `<Field CanToggleHidden="TRUE" `) }); } } updates.Hidden = options.Hidden === true; } } if (!(0, typecheckers_1.isNullOrEmptyString)(options.ClientSideComponentId)) updates.ClientSideComponentId = options.ClientSideComponentId; if (!(0, typecheckers_1.isNullOrEmptyString)(options.ClientSideComponentProperties)) updates.ClientSideComponentProperties = options.ClientSideComponentProperties; if (!(0, typecheckers_1.isNullOrEmptyString)(options.JSLink)) updates.JSLink = options.JSLink; } if (Object.keys(updates).length > 1) { return (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/fields/getbyinternalnameortitle('${fieldInternalName}')`, JSON.stringify(updates), { xHttpMethod: "MERGE" }) .then(r => { return finish(); }) .catch(() => null); } else { console.error("You must send an option to update"); return null; } } exports.UpdateField = UpdateField; async function ChangeTextFieldMode(siteUrlOrId, listIdOrTitle, textMode, currentField) { const newSchema = (0, exports_index_1.jsonClone)(currentField.SchemaJson); const currentSchemaAttributes = newSchema.Attributes; switch (textMode) { case "singleline": let shouldIntermediateUpdate = false; if (currentSchemaAttributes.RichText === 'TRUE') { currentSchemaAttributes.RichText = 'FALSE'; shouldIntermediateUpdate = true; } ; if (currentSchemaAttributes.RichTextMode === 'FullHTML') { currentSchemaAttributes.RichTextMode = 'Compatible'; shouldIntermediateUpdate = true; } ; if (shouldIntermediateUpdate) { const intermediateSchema = (0, sharepoint_1.SchemaJsonToXml)(newSchema); const intermediateUpdatedField = await UpdateField(siteUrlOrId, listIdOrTitle, currentField.InternalName, { SchemaXml: intermediateSchema }); // Early exit if intermediate change failed. if ((0, typecheckers_1.isNullOrUndefined)(intermediateUpdatedField)) return false; } ; // Actual type update. currentSchemaAttributes.Type = 'Text'; delete currentSchemaAttributes.RichTextMode; delete currentSchemaAttributes.RichText; break; case "multiline": currentSchemaAttributes.Type = 'Note'; currentSchemaAttributes.RichText = 'FALSE'; currentSchemaAttributes.RichTextMode = 'Compatible'; break; case "html": currentSchemaAttributes.Type = 'Note'; currentSchemaAttributes.RichText = 'TRUE'; currentSchemaAttributes.RichTextMode = 'FullHTML'; break; } const updatedSchema = (0, sharepoint_1.SchemaJsonToXml)(newSchema); const fieldUpdated = await UpdateField(siteUrlOrId, listIdOrTitle, currentField.InternalName, { SchemaXml: updatedSchema }); // If object is null or undefined then request has failed. return !(0, typecheckers_1.isNullOrUndefined)(fieldUpdated); } exports.ChangeTextFieldMode = ChangeTextFieldMode; async function ChangeDatetimeFieldMode(siteUrlOrId, listIdOrTitle, includeTime, currentField) { const dateTimeFormat = 'DateTime'; const dateOnlyFormat = 'DateOnly'; const newSchema = (0, exports_index_1.jsonClone)(currentField.SchemaJson); const fieldAttributes = newSchema.Attributes; let needUpdate = false; if (includeTime && fieldAttributes.Format === dateOnlyFormat) { needUpdate = true; fieldAttributes.Format = dateTimeFormat; } else if (!includeTime && fieldAttributes.Format === dateTimeFormat) { needUpdate = true; fieldAttributes.Format = dateOnlyFormat; } if (needUpdate) { const updatedSchema = (0, sharepoint_1.SchemaJsonToXml)(newSchema); const updateResponse = await UpdateField(siteUrlOrId, listIdOrTitle, currentField.InternalName, { SchemaXml: updatedSchema }); return !(0, typecheckers_1.isNullOrUndefined)(updateResponse); } // If an already existing format was chosen. return true; } exports.ChangeDatetimeFieldMode = ChangeDatetimeFieldMode; async function DeleteField(siteUrl, listIdOrTitle, fieldInternalName, options) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); // let finish = async () => { // //we need to clear and reload the list fields cache, so call it and return our field from that collection. // let fields = await GetListFields(siteUrl, listIdOrTitle, { refreshCache: true }); // return firstOrNull(fields, f => f.InternalName === fieldInternalName); // }; if (options && options.DeleteHiddenField) await UpdateField(siteUrl, listIdOrTitle, fieldInternalName, { Hidden: false }); return (0, rest_1.GetJson)(GetListRestUrl(siteUrl, listIdOrTitle) + `/fields/getbyinternalnameortitle('${fieldInternalName}')`, null, { method: "POST", xHttpMethod: "DELETE" }) .then(r => true) .catch((e) => false); } exports.DeleteField = DeleteField; function GetListViews(siteUrl, listIdOrTitle, options, refreshCache = false) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/views?$select=Title,Id,ServerRelativeUrl,RowLimit,Paged,ViewQuery,ListViewXml,PersonalView,MobileView,MobileDefaultView,Hidden,DefaultView,ReadOnlyView${options && options.includeViewFields ? "&$expand=ViewFields" : ""}`; return (0, rest_1.GetJson)(url, null, { allowCache: refreshCache !== true, jsonMetadata: rest_types_1.jsonTypes.nometadata }) .then(r => { let views = r.value; if ((0, typecheckers_1.isNotEmptyArray)(views)) { views.forEach(v => { v.Id = (0, strings_1.normalizeGuid)(v.Id); if (options && options.includeViewFields) { v.ViewFields = v.ViewFields && v.ViewFields["Items"] && v.ViewFields["Items"] || []; } }); } return views; }) .catch(() => null); } exports.GetListViews = GetListViews; function GetListViewsSync(siteUrl, listIdOrTitle, options, refreshCache = false) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/views?$select=Title,Id,ServerRelativeUrl,RowLimit,Paged,ViewQuery,ListViewXml,PersonalView,MobileView,MobileDefaultView,Hidden,DefaultView,ReadOnlyView${options && options.includeViewFields ? "&$expand=ViewFields" : ""}`; let response = (0, rest_1.GetJsonSync)(url, null, { allowCache: refreshCache !== true, jsonMetadata: rest_types_1.jsonTypes.nometadata }); if (response.success) { let views = response && response.result && response.result.value; if ((0, typecheckers_1.isNotEmptyArray)(views)) { views.forEach(v => { v.Id = (0, strings_1.normalizeGuid)(v.Id); }); } return views; } return null; } exports.GetListViewsSync = GetListViewsSync; async function AddViewFieldToListView(siteUrl, listIdOrTitle, viewId, viewField) { return _addOrRemoveViewField(siteUrl, listIdOrTitle, viewId, viewField, "addviewfield"); } exports.AddViewFieldToListView = AddViewFieldToListView; async function RemoveViewFieldFromListView(siteUrl, listIdOrTitle, viewId, viewField) { return _addOrRemoveViewField(siteUrl, listIdOrTitle, viewId, viewField, "removeviewfield"); } exports.RemoveViewFieldFromListView = RemoveViewFieldFromListView; async function _addOrRemoveViewField(siteUrl, listIdOrTitle, viewId, viewField, action) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); if ((0, typecheckers_1.isNullOrEmptyString)(viewField) || !(0, typecheckers_1.isValidGuid)(viewId)) { return false; } let views = await GetListViews(siteUrl, listIdOrTitle, { includeViewFields: true }); if ((0, typecheckers_1.isNullOrEmptyArray)(views)) { return false; } let view = views.filter((view) => { return (0, strings_1.normalizeGuid)(view.Id) === (0, strings_1.normalizeGuid)(viewId); })[0]; if ((0, typecheckers_1.isNullOrUndefined)(view)) { return false; } let hasField = view.ViewFields.includes(viewField); if (action === "addviewfield" && hasField === true) { return true; } if (action === "removeviewfield" && hasField === false) { return true; } try { let url = GetListRestUrl(siteUrl, listIdOrTitle) + `/views('${(0, strings_1.normalizeGuid)(view.Id)}')/viewfields/${action}('${viewField}')`; let result = await (0, rest_1.GetJson)(url, null, { method: "POST" }); if (result && result["odata.null"] === true) { return true; } } catch { } return false; } function GetListContentTypes(siteUrl, listIdOrTitle, options, refreshCache = false) { return (0, web_1.GetContentTypes)(siteUrl, { ...(options || {}), listIdOrTitle: listIdOrTitle }, refreshCache); } exports.GetListContentTypes = GetListContentTypes; function GetListContentTypesSync(siteUrl, listIdOrTitle, options, refreshCache = false) { return (0, web_1.GetContentTypesSync)(siteUrl, { ...(options || {}), listIdOrTitle: listIdOrTitle }, refreshCache); } exports.GetListContentTypesSync = GetListContentTypesSync; /** generic version. for the KWIZ forms version that supports action id call GetListFormUrlAppsWeb instead */ function GetListFormUrl(siteUrl, listId, pageType, params) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); if (!(0, typecheckers_1.isValidGuid)(listId)) console.error('GetListFormUrl requires a list id'); let url = `${(0, url_1.normalizeUrl)(siteUrl)}/_layouts/15/listform.aspx?PageType=${pageType}&ListId=${encodeURIComponent(listId)}`; if (params) { if (!(0, typecheckers_1.isNullOrEmptyString)(params.contentTypeId)) url += `&ContentTypeId=${encodeURIComponent(params.contentTypeId)}`; if (!(0, typecheckers_1.isNullOrEmptyString)(params.itemId)) url += `&ID=${encodeURIComponent(params.itemId)}`; if (!(0, typecheckers_1.isNullOrEmptyString)(params.rootFolder)) url += `&RootFolder=${encodeURIComponent(params.rootFolder)}`; } return url; } exports.GetListFormUrl = GetListFormUrl; function GetFieldSchemaSync(siteUrl, listIdOrTitle, fieldInternalName, refreshCache) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); //ISSUE: 1516 - The get schema request will fail if the field doesn't exist in the list, so we load the fields and ensure the field //exists before requesting the schema. let fields = GetListFieldsSync(siteUrl, listIdOrTitle, { refreshCache: refreshCache, fieldNames: [fieldInternalName] }); if ((0, typecheckers_1.isNullOrEmptyArray)(fields)) { return null; } let field = fields[0]; return (0, sharepoint_1.SchemaXmlToJson)(field.SchemaXml); // let url = GetListRestUrl(siteUrl, listIdOrTitle) + `/fields/getByInternalNameOrTitle('${fieldInternalName}')?$select=SchemaXml`; // let result = GetJsonSync<{ d: { SchemaXml: string; }; }>( // url, // null, // { // ...shortLocalCache, // forceCacheUpdate: refreshCache === true // }); // if (result && result.success) { // return SchemaXmlToJson(result.result.d.SchemaXml); // } // return null; //#endregion } exports.GetFieldSchemaSync = GetFieldSchemaSync; async function GetFieldSchema(siteUrl, listIdOrTitle, fieldInternalName, refreshCache) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); //ISSUE: 1516 - The get schema request will fail if the field doesn't exist in the list, so we load the fields and ensure the field //exists before requesting the schema let fields = await GetListFields(siteUrl, listIdOrTitle, { refreshCache: refreshCache, fieldNames: [fieldInternalName] }); if ((0, typecheckers_1.isNullOrEmptyArray)(fields)) { return null; } let field = fields[0]; return (0, sharepoint_1.SchemaXmlToJson)(field.SchemaXml); } exports.GetFieldSchema = GetFieldSchema; async function GetListItems(siteUrl, listIdOrTitle, options) { let info = _GetListItemsInfo(siteUrl, listIdOrTitle, options); let items = []; do { let resultItems = []; let next = null; if (info.noMetadata) { let requestResult = (await (0, rest_1.GetJson)(info.requestUrl, null, { allowCache: options.refreshCache !== true, jsonMetadata: options.jsonMetadata })); resultItems = requestResult.value; next = requestResult["odata.nextLink"]; } else { let requestResult = (await (0, rest_1.GetJson)(info.requestUrl, null, { allowCache: options.refreshCache !== true })); resultItems = requestResult.d.results; next = requestResult.d.__next; } if ((0, typecheckers_1.isNotEmptyArray)(resultItems)) items.push(...resultItems); if (info.totalNumberOfItemsToGet > items.length) info.requestUrl = next; else info.requestUrl = null; } while (!(0, typecheckers_1.isNullOrEmptyString)(info.requestUrl)); return (0, common_2.__fixGetListItemsResults)(siteUrl, listIdOrTitle, items, options.foldersBehaviour, info.expandedLookupFields); } exports.GetListItems = GetListItems; function GetListItemsSync(siteUrl, listIdOrTitle, options) { let info = _GetListItemsInfo(siteUrl, listIdOrTitle, options); let items = []; do { let resultItems = []; let next = null; if (info.noMetadata) { let requestResult = (0, rest_1.GetJsonSync)(info.requestUrl, null, { allowCache: true }); if (requestResult.success) { resultItems = requestResult.result.value; next = requestResult.result["odata.nextLink"]; } } else { let requestResult = (0, rest_1.GetJsonSync)(info.requestUrl, null, { allowCache: true }); if (requestResult.success) { resultItems = requestResult.result.d.results; next = requestResult.result.d.__next; } } if ((0, typecheckers_1.isNotEmptyArray)(resultItems)) items.push(...resultItems); if (info.totalNumberOfItemsToGet > items.length) info.requestUrl = next; else info.requestUrl = null; } while (!(0, typecheckers_1.isNullOrEmptyString)(info.requestUrl)); return (0, common_2.__fixGetListItemsResults)(siteUrl, listIdOrTitle, items, options.foldersBehaviour, info.expandedLookupFields); } exports.GetListItemsSync = GetListItemsSync; function _GetListItemsInfo(siteUrl, listIdOrTitle, options) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let url = GetListRestUrl(siteUrl, listIdOrTitle) + `/items`; let queryParams = []; //Issue 8189 expand lookup fields let columns = []; let expand = []; let expandedLookupFields = []; options.columns.forEach(c => { if ((0, typecheckers_1.isString)(c)) columns.push(c); else { let internalName = c.InternalName; //Issue 828, 336 if (internalName.startsWith("_")) internalName = `OData_${internalName}`; let isLookupField = c.TypeAsString === "Lookup" || c.TypeAsString === "LookupMulti"; let isUserField = c.TypeAsString === "User" || c.TypeAsString === "UserMulti"; if (isLookupField || isUserField) { //ISSUE: 1519 - Added lookupField property to able to retrieve value of the additional lookup field key let lookupField = c.LookupField; if (!(0, typecheckers_1.isNullOrEmptyString)(lookupField) && isLookupField) { columns.push(`${internalName}/${lookupField}`); } //we want to expand it columns.push(`${internalName}/Title`); columns.push(`${internalName}/Id`); expand.push(internalName); expandedLookupFields.push(c); } else columns.push(internalName); } }); if ((0, typecheckers_1.isNotEmptyArray)(options.expand)) { expand.push(...options.expand); } //add the ones we need (0, collections_base_1.PushNoDuplicate)(columns, "Id"); (0, collections_base_1.PushNoDuplicate)(columns, "FileRef"); (0, collections_base_1.PushNoDuplicate)(columns, "FileSystemObjectType"); queryParams.push(`$select=${encodeURIComponent((0, collections_base_1.makeUniqueArray)(columns).join(','))}`); if ((0, typecheckers_1.isNotEmptyArray)(expand)) queryParams.push(`$expand=${encodeURIComponent((0, collections_base_1.makeUniqueArray)(expand).join(','))}`); let batchSize = 2000; let limit = options.rowLimit >= 0 && options.rowLimit < batchSize ? options.rowLimit : batchSize; let totalNumberOfItemsToGet = !(0, typecheckers_1.isNumber)(options.rowLimit) || options.rowLimit < 1 ? 99999 : options.rowLimit > batchSize ? options.rowLimit : limit; if (!(0, typecheckers_1.isNullOrEmptyString)(options.$filter)) queryParams.push(`$filter=${options.$filter}`); queryParams.push(`$top=${limit}`); let requestUrl = url + (queryParams.length > 0 ? '?' + queryParams.join('&') : ''); let noMetadata = options.jsonMetadata === rest_types_1.jsonTypes.nometadata; return { requestUrl, noMetadata, totalNumberOfItemsToGet, expandedLookupFields }; } /** Find an item by id, even if it is nested in a sub-folder */ function FindListItemById(items, itemId) { for (let i = 0; i < items.length; i++) { let current = items[i]; if (current.Id === itemId) return current; else if ((0, typecheckers_1.isNotEmptyArray)(current.__Items)) //folder? look inside { let nestedResult = FindListItemById(current.__Items, itemId); if (!(0, typecheckers_1.isNullOrUndefined)(nestedResult)) return nestedResult; } } //not found return null; } exports.FindListItemById = FindListItemById; function _getListEventReceiversRequestUrl(siteUrl, listIdOrTitle) { return GetListRestUrl(siteUrl, listIdOrTitle) + `/EventReceivers`; } async function GetListEventReceivers(siteUrl, listIdOrTitle, refreshCache) { try { let url = _getListEventReceiversRequestUrl(siteUrl, listIdOrTitle); let response = await (0, rest_1.GetJson)(url, null, { allowCache: refreshCache !== true, jsonMetadata: rest_types_1.jsonTypes.nometadata }); return !(0, typecheckers_1.isNullOrUndefined)(response) ? response.value : null; } catch { } return null; } exports.GetListEventReceivers = GetListEventReceivers; async function AddListEventReceiver(siteUrl, listIdOrTitle, eventReceiverDefinition) { let newEventReceiver = { ReceiverAssembly: "", ReceiverClass: "", ...eventReceiverDefinition }; try { let url = _getListEventReceiversRequestUrl(siteUrl, listIdOrTitle); let response = await (0, rest_1.GetJson)(url, JSON.stringify(newEventReceiver), { method: "POST", includeDigestInPost: true, jsonMetadata: rest_types_1.jsonTypes.nometadata, headers: { "content-type": rest_types_1.contentTypes.json } }); return !(0, typecheckers_1.isNullOrUndefined)(response) && (0, typecheckers_1.isValidGuid)(response.ReceiverId) ? response : null; } catch { } return null; } exports.AddListEventReceiver = AddListEventReceiver; async function DeleteListEventReceiver(siteUrl, listIdOrTitle, eventReceiverId) { try { let url = `${_getListEventReceiversRequestUrl(siteUrl, listIdOrTitle)}('${(0, strings_1.normalizeGuid)(eventReceiverId)}')/deleteObject`; let response = await (0, rest_1.GetJson)(url, null, { method: "POST", includeDigestInPost: true, jsonMetadata: rest_types_1.jsonTypes.nometadata }); return !(0, typecheckers_1.isNullOrUndefined)(response) && response["odata.null"] === true; } catch { } return false; } exports.DeleteListEventReceiver = DeleteListEventReceiver; function GetListLastItemModifiedDate(siteUrl, listIdOrTitle, options) { siteUrl = (0, common_1.GetSiteUrl)(siteUrl); let endPoint = options && options.userChangesOnly ? 'LastItemUserModifiedDate' : 'LastItemModifiedDate'; let sync = options && options.sync ? true : false; let caller = sync ? rest_1.GetJsonSync : rest_1.GetJson; let result = caller(GetListRestUrl(siteUrl, listIdOrTitle) + `/${endPoint}`, null, { allowCache: true, //in memory only jsonMetadata: rest_types_1.jsonTypes.nometadata, forceCacheUpdate: options && options.refreshCache === true || false }); if ((0, typecheckers_1.isPromise)(result)) return result.then(r => r.value, () => null); else return result.success ? result.result.value : null; } exports.GetListLastItemModifiedDate = GetListLastItemModifiedDate; async function ReloadListLastModified(siteUrl, listIdOrTitle) { await GetListLastItemModifiedDate(siteUrl, listIdOrTitle, { refreshCache: true }); //make sure we do it for both title and id, we don't know how the other callers may use this in their API if (!(0, typecheckers_1.isValidGuid)(listIdOrTitle)) { try { var listId = GetListId(siteUrl, listIdOrTitle); await GetListLastItemModifiedDate(siteUrl, listId, { refreshCache: true }); } catch (e) { } } else { try { var listTitle = await GetListTitle(siteUrl, listIdOrTitle); await GetListLastItemModifiedDate(siteUrl, listTitle, { refreshCache: true }); } catch (e) { } } } exports.ReloadListLastModified = ReloadListLastModified; async function ListHasUniquePermissions(siteUrl, listIdOrTitle) { let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/?$select=hasuniqueroleassignments`; let has = await (0, rest_1.GetJson)(url, undefined, { allowCache: false, jsonMetadata: rest_types_1.jsonTypes.nometadata }); return has.HasUniqueRoleAssignments === true; } exports.ListHasUniquePermissions = ListHasUniquePermissions; async function RestoreListPermissionInheritance(siteUrl, listIdOrTitle) { let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/ResetRoleInheritance`; await (0, rest_1.GetJson)(url, undefined, { method: "POST", allowCache: false, jsonMetadata: rest_types_1.jsonTypes.nometadata, spWebUrl: siteUrl }); } exports.RestoreListPermissionInheritance = RestoreListPermissionInheritance; async function BreakListPermissionInheritance(siteUrl, listIdOrTitle, clear = true) { let url = `${GetListRestUrl(siteUrl, listIdOrTitle)}/breakroleinheritance(copyRoleAssignments=${clear ? 'false' : 'true'}, clearSubscopes=true)`; await (0, rest_1.GetJson)(url, undefined, { method: "POST", allowCache: false, jsonMetadata: rest_types_1.jsonTypes.nometadata, spWebUrl: siteUrl }); } exports.BreakListPermissionInheritance = BreakListPermissionInheritance; async function AssignListPermission(siteUrl, listIdOrTitle, principalId, roleId) { let url = `${GetListR