text: "use strict";
  /**
   * @file normalizeSolutionDefinition.ts
   * @Copyright (c) Microsoft Corporation.  All rights reserved.
   *
   * Using a manifest map, creates component definitions and updates a package definition's element guids with
   * actual objects
   */
  Object.defineProperty(exports, "__esModule", { value: true });
  const path = require("path");
  const uuid = require("uuid");
  const gulp_core_build_1 = require("@microsoft/gulp-core-build");
  // NOTE: this value is required for the client side asset packaging feature. The base URL value must match exactly
  // with the server-side value in the file SPClientSideThirdPartyComponentProvider.cs. This informs the server-side
  // third-party component provider that it needs to replace this URL with the public CDN URL.
  const clientSideAssetLibraryPseudoUrl = 'HTTPS://SPCLIENTSIDEASSETLIBRARY/';
  function createComponent(manifest) {
      if (!manifest.id || !manifest || !manifest.componentType) {
          return undefined;
      }
      if (manifest.componentType === 'Application') {
          return createApplicationComponent(manifest);
      }
      else if (manifest.componentType === 'WebPart') {
          return createWebPartComponent(manifest);
      }
      else if (manifest.componentType === 'Extension') {
          return createExtensionComponent(manifest);
      }
      else if (manifest.componentType === 'Library') {
          return createLibraryComponent(manifest);
      }
      else {
          gulp_core_build_1.log(`Component type '${manifest.componentType}' not recognized. Skipping manifest.`);
          return undefined;
      }
  }
  function getRequiresCustomScriptProperty(manifest) {
      // a manifest either has requiresCustomScript or the deprecated safeWithCustomScriptDisabled
      // however, we are now ignoring the value of safeWithCustomScriptDisabled since it was formerly
      // set to false in the generator's templates
      // if they have the value set to 'false', we will print a warning
      const requiresCustomScript = !!manifest.requiresCustomScript;
      delete manifest.requiresCustomScript;
      delete manifest.safeWithCustomScriptDisabled;
      return requiresCustomScript; // this will default this value to false
  }
  function createExtensionComponent(manifest) {
      const requiresCustomScript = getRequiresCustomScriptProperty(manifest);
      return {
          name: manifest.alias,
          description: `${manifest.extensionType} - ${manifest.alias}`,
          id: manifest.id,
          manifest,
          requiresCustomScript,
          componentDefinition: {}
      };
  }
  function createLibraryComponent(manifest) {
      const requiresCustomScript = getRequiresCustomScriptProperty(manifest);
      return {
          name: manifest.alias,
          description: `Library - ${manifest.alias}`,
          id: manifest.id,
          manifest,
          requiresCustomScript,
          componentDefinition: {}
      };
  }
  function createApplicationComponent(manifest) {
      const requiresCustomScript = getRequiresCustomScriptProperty(manifest);
      return {
          name: manifest.title.default,
          description: manifest.description.default,
          id: manifest.id,
          manifest,
          requiresCustomScript,
          componentDefinition: {}
      };
  }
  function createWebPartComponent(manifest) {
      let i = 0;
      const entries = manifest.preconfiguredEntries.map((entry) => {
          return {
              id: manifest.id + '_' + i++,
              name: entry.title.default,
              description: entry.description.default,
              webPartData: buildWebPartData(manifest, entry)
          };
      });
      const requiresCustomScript = getRequiresCustomScriptProperty(manifest);
      // Use the first entry name and description for the component
      return {
          name: manifest.preconfiguredEntries[0].title.default,
          description: manifest.preconfiguredEntries[0].description.default,
          id: manifest.id,
          manifest,
          requiresCustomScript,
          componentDefinition: {
              entries: entries
          }
      };
  }
  // tslint:disable:no-any
  function buildWebPartData(manifest, entry) {
      // tslint:enable:no-any
      return JSON.stringify({
          id: manifest.id,
          instanceId: undefined,
          title: entry.title.default,
          description: entry.description.default,
          version: manifest.version,
          properties: entry.properties
      });
  }
  function createComponentMapFromManifests(manifests) {
      gulp_core_build_1.log(`Attempting creating component definitions for {${manifests.size}} manifests`);
      const components = new Map();
      manifests.forEach((manifest, key) => {
          const component = createComponent(manifest);
          if (component) {
              components.set(key, component);
          }
      });
      gulp_core_build_1.log(`Created component definitions for {${components.size}} manifests`);
      return components;
  }
  function createFeatureFromComponent(component) {
      return {
          title: `${component.name} Feature`,
          description: `A feature which activates the Client-Side ${component.manifest.componentType} named ` +
              `${component.name}`,
          id: component.id || uuid.v4(),
          // or generate a new uuid if it doesn't (e.g. for client-side assets feature)
          components: [component],
          assets: {
              elementFiles: [],
              elementManifests: [],
              upgradeActions: []
          }
      };
  }
  /**
   * Normalizes the passed in solution definition by cross referencing componentIds with the collected list
   * of manifests in the repo. If, for any feature, the componentId list is missing or empty, we add all the
   * components to that feature. Similarly, if the list of features in the solution is empty or missing, a
   * feature is automatically created for all solutions.
   */
  function normalizeSolutionDefinition(options, manifests) {
      if (options.solution.includeClientSideAssets) {
          manifests.forEach((manifest) => {
              manifest.loaderConfig.internalModuleBaseUrls = [clientSideAssetLibraryPseudoUrl];
          });
      }
      const componentMap = createComponentMapFromManifests(manifests);
      const numManifests = componentMap.size;
      if (numManifests === 0) {
          throw 'Could not find any valid manifests. Please double check paths.manifestsMatch in the task config.';
      }
      // Then, replace the guids in the solution definition with the component definition
      if (options.solution && options.solution.features) {
          for (const feature of options.solution.features) {
              if (feature.componentIds && feature.componentIds.length > 0) {
                  feature.components = feature.componentIds.map((componentId) => {
                      const manifest = componentMap.get(componentId);
                      if (!manifest) {
                          throw new Error(`Component {${componentId}} does not exist in feature '${feature.title}'. `
                              + 'Please update your configuration.');
                      }
                      return manifest;
                  });
              }
              else {
                  gulp_core_build_1.log('feature.componentIds not set! ' +
                      `Adding all [${numManifests}] components to feature { ${feature.title} }.`);
                  feature.components = [];
                  componentMap.forEach((component) => {
                      feature.components.push(component);
                  });
              }
              if (!feature.assets) {
                  feature.assets = {
                      elementFiles: [],
                      elementManifests: [],
                      upgradeActions: []
                  };
              }
              feature.assets.elementFiles =
                  appendBasePathToFeatureFiles(feature.assets.elementFiles, options.paths.sharepointAssetDir);
              feature.assets.elementManifests =
                  appendBasePathToFeatureFiles(feature.assets.elementManifests, options.paths.sharepointAssetDir);
              feature.assets.upgradeActions =
                  appendBasePathToFeatureFiles(feature.assets.upgradeActions, options.paths.sharepointAssetDir);
          }
      }
      else {
          gulp_core_build_1.log('config.solution.features not set! Instead generating a feature for each component.');
          options.solution.features = [];
          componentMap.forEach((component) => {
              gulp_core_build_1.log(`Creating feature for ${component.name}...`);
              options.solution.features.push(createFeatureFromComponent(component));
          });
      }
  }
  exports.default = normalizeSolutionDefinition;
  function appendBasePathToFeatureFiles(files, basePath) {
      if (files) {
          return files.map((filename) => path.posix.join(basePath, filename));
      }
      return [];
  }
  //# sourceMappingURL=normalizeSolutionDefinition.js.map