UNPKG

sp-js-provisioning

Version:
595 lines 31 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; import initSpfxJsom from 'spfx-jsom'; import * as xmljs from 'xml-js'; import { addFieldAttributes } from '../util'; import { TokenHelper } from '../util/tokenhelper'; import { HandlerBase } from './handlerbase'; /** * Describes the Lists Object Handler */ var Lists = /** @class */ (function (_super) { __extends(Lists, _super); /** * Creates a new instance of the Lists class * * @param config - Provisioning config */ function Lists(config) { return _super.call(this, 'Lists', config) || this; } /** * Provisioning lists * * @param web - The web * @param lists - The lists to provision */ Lists.prototype.ProvisionObjects = function (web, lists, context) { return __awaiter(this, void 0, void 0, function () { var _a, _b, _c, error_1; var _this = this; return __generator(this, function (_d) { switch (_d.label) { case 0: _a = this; return [4 /*yield*/, initSpfxJsom(context.web.ServerRelativeUrl)]; case 1: _a.jsomContext = (_d.sent()).jsomContext; this.context = context; this.tokenHelper = new TokenHelper(this.context, this.config); _super.prototype.scope_started.call(this); _d.label = 2; case 2: _d.trys.push([2, 9, , 10]); _b = this.context; return [4 /*yield*/, web.lists .select('Id', 'Title')()]; case 3: _b.lists = (_d.sent()).reduce(function (object, l) { object[l.Title] = l.Id; return object; }, {}); return [4 /*yield*/, lists.reduce(function (chain, list) { return chain.then(function () { return _this.processList(web, list); }); }, Promise.resolve())]; case 4: _d.sent(); return [4 /*yield*/, lists.reduce(function (chain, list) { return chain.then(function () { return _this.processListFields(web, list); }); }, Promise.resolve())]; case 5: _d.sent(); return [4 /*yield*/, lists.reduce(function (chain, list) { return chain.then(function () { return _this.processListFieldRefs(web, list); }); }, Promise.resolve())]; case 6: _d.sent(); return [4 /*yield*/, lists.reduce(function (chain, list) { return chain.then(function () { return _this.processListViews(web, list); }); }, Promise.resolve())]; case 7: _d.sent(); _c = this.context; return [4 /*yield*/, web.lists .select('Id', 'Title')()]; case 8: _c.lists = (_d.sent()).reduce(function (object, l) { object[l.Title] = l.Id; return object; }, {}); _super.prototype.scope_ended.call(this); return [3 /*break*/, 10]; case 9: error_1 = _d.sent(); _super.prototype.scope_ended.call(this, error_1); throw error_1; case 10: return [2 /*return*/]; } }); }); }; /** * Processes a list * * @param web - The web * @param lc - The list */ Lists.prototype.processList = function (web, lc) { return __awaiter(this, void 0, void 0, function () { var list, listEnsure, listAdd; return __generator(this, function (_a) { switch (_a.label) { case 0: _super.prototype.log_info.call(this, 'processList', "Processing list " + lc.Title); if (!this.context.lists[lc.Title]) return [3 /*break*/, 2]; _super.prototype.log_info.call(this, 'processList', "List " + lc.Title + " already exists. Ensuring..."); return [4 /*yield*/, web.lists.ensure(lc.Title, lc.Description, lc.Template, lc.ContentTypesEnabled, lc.AdditionalSettings)]; case 1: listEnsure = _a.sent(); list = listEnsure.list; return [3 /*break*/, 4]; case 2: _super.prototype.log_info.call(this, 'processList', "List " + lc.Title + " doesn't exist. Creating..."); return [4 /*yield*/, web.lists.add(lc.Title, lc.Description, lc.Template, lc.ContentTypesEnabled, lc.AdditionalSettings)]; case 3: listAdd = _a.sent(); list = listAdd.list; this.context.lists[listAdd.data.Title] = listAdd.data.Id; _a.label = 4; case 4: if (!lc.ContentTypeBindings) return [3 /*break*/, 6]; return [4 /*yield*/, this.processContentTypeBindings(lc, list, lc.ContentTypeBindings, lc.RemoveExistingContentTypes)]; case 5: _a.sent(); _a.label = 6; case 6: return [2 /*return*/]; } }); }); }; /** * Processes content type bindings for a list * * @param lc - The list configuration * @param list - The pnp list * @param contentTypeBindings - Content type bindings * @param removeExisting - Remove existing content type bindings */ Lists.prototype.processContentTypeBindings = function (lc, list, contentTypeBindings, removeExisting) { return __awaiter(this, void 0, void 0, function () { var promises_1, contentTypes; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: _super.prototype.log_info.call(this, 'processContentTypeBindings', "Processing content types for list " + lc.Title + "."); return [4 /*yield*/, contentTypeBindings.reduce(function (chain, ct) { return chain.then(function () { return _this.processContentTypeBinding(lc, list, ct.ContentTypeID); }); }, Promise.resolve())]; case 1: _a.sent(); if (!removeExisting) return [3 /*break*/, 4]; promises_1 = []; return [4 /*yield*/, list.contentTypes()]; case 2: contentTypes = _a.sent(); contentTypes.forEach(function (_a) { var ContentTypeId = _a.Id.StringValue; var shouldRemove = contentTypeBindings.filter(function (ctb) { return ContentTypeId.includes(ctb.ContentTypeID); }).length === 0 && !ContentTypeId.includes('0x0120'); if (shouldRemove) { _super.prototype.log_info.call(_this, 'processContentTypeBindings', "Removing content type " + ContentTypeId + " from list " + lc.Title); promises_1.push(list.contentTypes.getById(ContentTypeId).delete()); } else { _super.prototype.log_info.call(_this, 'processContentTypeBindings', "Skipping removal of content type " + ContentTypeId + " from list " + lc.Title); } }); return [4 /*yield*/, Promise.all(promises_1)]; case 3: _a.sent(); _a.label = 4; case 4: return [2 /*return*/]; } }); }); }; /** * Processes a content type binding for a list * * @param lc - The list configuration * @param list - The pnp list * @param contentTypeID - The Content Type ID */ Lists.prototype.processContentTypeBinding = function (lc, list, contentTypeID) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); _super.prototype.log_info.call(this, 'processContentTypeBinding', "Adding content Type " + contentTypeID + " to list " + lc.Title + "."); return [4 /*yield*/, list.contentTypes.addAvailableContentType(contentTypeID)]; case 1: _b.sent(); _super.prototype.log_info.call(this, 'processContentTypeBinding', "Content Type " + contentTypeID + " added successfully to list " + lc.Title + "."); return [3 /*break*/, 3]; case 2: _a = _b.sent(); _super.prototype.log_info.call(this, 'processContentTypeBinding', "Failed to add Content Type " + contentTypeID + " to list " + lc.Title + "."); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; /** * Processes fields for a list * * @param web - The web * @param list - The pnp list */ Lists.prototype.processListFields = function (web, list) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!list.Fields) return [3 /*break*/, 2]; return [4 /*yield*/, list.Fields.reduce(function (chain, field) { return chain.then(function () { return _this.processField(web, list, field); }); }, Promise.resolve())]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; /** * Processes a field for a lit * * @param web - The web * @param lc - The list configuration * @param fieldXml - Field XML */ Lists.prototype.processField = function (web, lc, fieldXml) { return __awaiter(this, void 0, void 0, function () { var list, fieldXmlJson, fieldAttribute, fieldName, fieldDisplayName, _a, fieldAddResult, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: list = web.lists.getByTitle(lc.Title); fieldXmlJson = JSON.parse(xmljs.xml2json(fieldXml)); fieldAttribute = fieldXmlJson.elements[0].attributes; fieldName = fieldAttribute.Name; fieldDisplayName = fieldAttribute.DisplayName; _super.prototype.log_info.call(this, 'processField', "Processing field " + fieldName + " (" + fieldDisplayName + ") for list " + lc.Title + "."); fieldXmlJson.elements[0].attributes.DisplayName = fieldName; fieldXml = xmljs.json2xml(fieldXmlJson); _c.label = 1; case 1: _c.trys.push([1, 3, , 4]); return [4 /*yield*/, list.fields.getById(fieldAttribute.ID).delete()]; case 2: _c.sent(); _super.prototype.log_info.call(this, 'processField', "Field " + fieldName + " (" + fieldDisplayName + ") successfully deleted from list " + lc.Title + "."); return [3 /*break*/, 4]; case 3: _a = _c.sent(); _super.prototype.log_info.call(this, 'processField', "Field " + fieldName + " (" + fieldDisplayName + ") does not exist in list " + lc.Title + "."); return [3 /*break*/, 4]; case 4: _c.trys.push([4, 7, , 8]); return [4 /*yield*/, list.fields.createFieldAsXml(this.tokenHelper.replaceTokens(fieldXml))]; case 5: fieldAddResult = _c.sent(); return [4 /*yield*/, fieldAddResult.field.update({ Title: fieldDisplayName })]; case 6: _c.sent(); _super.prototype.log_info.call(this, 'processField', "Field '" + fieldDisplayName + "' added successfully to list " + lc.Title + "."); return [3 /*break*/, 8]; case 7: _b = _c.sent(); _super.prototype.log_info.call(this, 'processField', "Failed to add field '" + fieldDisplayName + "' to list " + lc.Title + "."); return [3 /*break*/, 8]; case 8: return [2 /*return*/]; } }); }); }; /** * Processes field refs for a list * * @param web - The web * @param lc - The list configuration */ Lists.prototype.processListFieldRefs = function (web, lc) { return __awaiter(this, void 0, void 0, function () { var list_1, _a, listFields_1, webFields_1; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!lc.FieldRefs) return [3 /*break*/, 4]; _super.prototype.log_info.call(this, 'processListFieldRefs', "Retrieving fields for list " + lc.Title + " and web."); list_1 = web.lists.getByTitle(lc.Title); return [4 /*yield*/, Promise.all([ list_1.fields.select('Id', 'InternalName', 'SchemaXml')(), web.fields.select('Id', 'InternalName', 'SchemaXml')() ])]; case 1: _a = _b.sent(), listFields_1 = _a[0], webFields_1 = _a[1]; _super.prototype.log_info.call(this, 'processListFieldRefs', "Fields for list " + lc.Title + " and web retrieved. Processing field refs."); return [4 /*yield*/, lc.FieldRefs.reduce(function (chain, fieldReference) { return chain.then(function () { return _this.processFieldRef(list_1, lc, fieldReference, listFields_1, webFields_1); }); }, Promise.resolve())]; case 2: return [4 /*yield*/, _b.sent()]; case 3: _b.sent(); _b.label = 4; case 4: return [2 /*return*/]; } }); }); }; /** * * Processes a field ref for a list * * @param list - The list * @param lc - The list configuration * @param fieldRef - The list field ref * @param listFields - The list fields * @param webFields - The web fields */ Lists.prototype.processFieldRef = function (list, lc, fieldReference, listFields, webFields) { var _a, _b; return __awaiter(this, void 0, void 0, function () { var listFld, webFld, schemaXml, schemaXml, fieldAddResult; return __generator(this, function (_c) { switch (_c.label) { case 0: listFld = listFields.find(function (f) { return f.Id === fieldReference.ID; }); webFld = webFields.find(function (f) { return f.Id === fieldReference.ID; }); _super.prototype.log_info.call(this, 'processFieldRef', "Processing field ref '" + fieldReference.ID + "' for list " + lc.Title + "."); if (!Boolean(listFld)) return [3 /*break*/, 4]; return [4 /*yield*/, list.fields.getById(fieldReference.ID).update({ Hidden: fieldReference.Hidden, Required: fieldReference.Required, Title: fieldReference.DisplayName })]; case 1: _c.sent(); if (!fieldReference.AdditionalProperties) return [3 /*break*/, 3]; schemaXml = addFieldAttributes(listFld.SchemaXml, __assign({ Hidden: fieldReference.Hidden, Required: fieldReference.Required, DisplayName: fieldReference.Name }, ((_a = fieldReference.AdditionalProperties) !== null && _a !== void 0 ? _a : {}))); _super.prototype.log_info.call(this, 'processFieldRef', "Additional properties set for field ref '" + fieldReference.ID + "' for list " + lc.Title + ". Attempting to generate schema XML.", { schemaXml: schemaXml }); return [4 /*yield*/, list.fields.getById(fieldReference.ID).update({ SchemaXml: schemaXml })]; case 2: _c.sent(); _c.label = 3; case 3: _super.prototype.log_info.call(this, 'processFieldRef', "Field '" + fieldReference.ID + "' updated for list " + lc.Title + "."); return [3 /*break*/, 6]; case 4: if (!Boolean(webFld)) return [3 /*break*/, 6]; _super.prototype.log_info.call(this, 'processFieldRef', "Adding field '" + fieldReference.ID + "' to list " + lc.Title + "."); schemaXml = addFieldAttributes(webFld.SchemaXml, __assign({ DisplayName: fieldReference.Name, SourceID: "{" + this.context.lists[lc.Title] + "}" }, ((_b = fieldReference.AdditionalProperties) !== null && _b !== void 0 ? _b : {}))); return [4 /*yield*/, list.fields.createFieldAsXml(schemaXml)]; case 5: fieldAddResult = _c.sent(); fieldAddResult.field.update({ Title: fieldReference.DisplayName, Required: fieldReference.Required, Hidden: fieldReference.Hidden }); _super.prototype.log_info.call(this, 'processFieldRef', "Field '" + fieldReference.ID + "' added from web."); _c.label = 6; case 6: return [2 /*return*/]; } }); }); }; /** * Processes views for a list * * @param web - The web * @param lc - The list configuration */ Lists.prototype.processListViews = function (web, lc) { return __awaiter(this, void 0, void 0, function () { var _a; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!lc.Views) return [3 /*break*/, 4]; if (!lc.RemoveExistingViews) return [3 /*break*/, 2]; return [4 /*yield*/, this.removeExistingViews(web, lc)]; case 1: _b.sent(); _b.label = 2; case 2: return [4 /*yield*/, lc.Views.reduce(function (chain, view) { return chain.then(function () { return _this.processView(web, lc, view); }); }, Promise.resolve())]; case 3: _b.sent(); _b.label = 4; case 4: _a = this.context; return [4 /*yield*/, web.lists .getByTitle(lc.Title) .views.select('Id', 'Title')()]; case 5: _a.listViews = (_b.sent()).reduce(function (object, view) { object[lc.Title + "|" + view.Title] = view.Id; return object; }, this.context.listViews); return [2 /*return*/]; } }); }); }; /** * Removes existing views for a list * * @param web - The web * @param lc - The list configuration */ Lists.prototype.removeExistingViews = function (web, lc) { return __awaiter(this, void 0, void 0, function () { var views, promises; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, web.lists .getByTitle(lc.Title) .views.select('Id', 'Title')()]; case 1: views = _a.sent(); _super.prototype.log_info.call(this, '_removeExistingViews', "Removing existing views for list " + lc.Title + ".", views.map(function (view) { return view.Title; })); promises = views.map(function (view) { return web.lists.getByTitle(lc.Title).views.getById(view.Id).delete(); }); return [4 /*yield*/, Promise.all(promises)]; case 2: _a.sent(); _super.prototype.log_info.call(this, '_removeExistingViews', "Existing views removed for list " + lc.Title + "."); return [2 /*return*/]; } }); }); }; /** * Processes a view for a list * * @param web - The web * @param lc - The list configuration * @param lvc - The view configuration */ Lists.prototype.processView = function (web, lc, lvc) { return __awaiter(this, void 0, void 0, function () { var existingView, viewExists, _a, result, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _super.prototype.log_info.call(this, 'processView', "Processing view " + lvc.Title + " for list " + lc.Title + "."); existingView = web.lists .getByTitle(lc.Title) .views.getByTitle(lvc.Title); viewExists = false; _c.label = 1; case 1: _c.trys.push([1, 3, , 4]); return [4 /*yield*/, existingView()]; case 2: _c.sent(); viewExists = true; return [3 /*break*/, 4]; case 3: _a = _c.sent(); return [3 /*break*/, 4]; case 4: _c.trys.push([4, 11, , 12]); if (!viewExists) return [3 /*break*/, 7]; _super.prototype.log_info.call(this, 'processView', "View " + lvc.Title + " for list " + lc.Title + " already exists, updating."); return [4 /*yield*/, existingView.update(lvc.AdditionalSettings)]; case 5: _c.sent(); _super.prototype.log_info.call(this, 'processView', "View " + lvc.Title + " successfully updated for list " + lc.Title + "."); return [4 /*yield*/, this.processViewFields(existingView, lvc)]; case 6: _c.sent(); return [3 /*break*/, 10]; case 7: _super.prototype.log_info.call(this, 'processView', "View " + lvc.Title + " for list " + lc.Title + " doesn't exists, creating."); return [4 /*yield*/, web.lists .getByTitle(lc.Title) .views.add(lvc.Title, lvc.PersonalView, lvc.AdditionalSettings)]; case 8: result = _c.sent(); _super.prototype.log_info.call(this, 'processView', "View " + lvc.Title + " added successfully to list " + lc.Title + "."); return [4 /*yield*/, this.processViewFields(result.view, lvc)]; case 9: _c.sent(); _c.label = 10; case 10: return [3 /*break*/, 12]; case 11: _b = _c.sent(); _super.prototype.log_info.call(this, 'processViewFields', "Failed to process view for view " + lvc.Title + "."); return [3 /*break*/, 12]; case 12: return [2 /*return*/]; } }); }); }; /** * Processes view fields for a view * * @param view - The pnp view * @param lvc - The view configuration */ Lists.prototype.processViewFields = function (view, lvc) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 3, , 4]); _super.prototype.log_info.call(this, 'processViewFields', "Processing view fields for view " + lvc.Title + "."); return [4 /*yield*/, view.fields.removeAll()]; case 1: _b.sent(); return [4 /*yield*/, lvc.ViewFields.reduce(function (chain, viewField) { return chain.then(function () { return view.fields.add(viewField); }); }, Promise.resolve())]; case 2: _b.sent(); _super.prototype.log_info.call(this, 'processViewFields', "View fields successfully processed for view " + lvc.Title + "."); return [3 /*break*/, 4]; case 3: _a = _b.sent(); _super.prototype.log_info.call(this, 'processViewFields', "Failed to process view fields for view " + lvc.Title + "."); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; return Lists; }(HandlerBase)); export { Lists }; //# sourceMappingURL=lists.js.map