export async function tweakModel()

in powershell/plugins/ps-namer-v2.ts [50:203]


export async function tweakModel(state: State): Promise<PwshModel> {
  // get the value 
  const isAzure = await state.getValue('azure', false);
  // without setting snitize-names, isAzure is applied
  const shouldSanitize = await state.getValue('sanitize-names', isAzure);

  // make sure recursively that every details field has csharp
  for (const { index, instance } of linq.visitor(state.model)) {
    if ((index === 'details' || index === 'language') && instance && instance.default && !instance.csharp) {
      instance.csharp = linq.clone(instance.default, false, undefined, undefined, ['schema', 'origin']);
    }
  }
  // dolauli sanitize name
  if (shouldSanitize) {
    for (const operation of values(state.model.commands.operations)) {
      // clean the noun (i.e. subjectPrefix + subject)
      const prevSubjectPrefix = operation.details.csharp.subjectPrefix;
      const prevSubject = operation.details.csharp.subject;
      const dedupedNounParts = getDeduplicatedNoun(operation.details.csharp.subjectPrefix, operation.details.csharp.subject);
      if (prevSubjectPrefix !== dedupedNounParts.subjectPrefix || prevSubject !== dedupedNounParts.subject) {
        const verb = operation.details.csharp.verb;
        const variantName = operation.details.csharp.name;
        const prevCmdletName = getCmdletName(verb, prevSubjectPrefix, prevSubject);
        operation.details.csharp.subjectPrefix = dedupedNounParts.subjectPrefix;
        operation.details.csharp.subject = dedupedNounParts.subject;
        const newCmdletName = getCmdletName(verb, operation.details.csharp.subjectPrefix, operation.details.csharp.subject);
        state.message(
          {
            Channel: Channel.Debug,
            Text: `Sanitized cmdlet-name -> Changed cmdlet-name from ${prevCmdletName} to ${newCmdletName}: {subjectPrefix: ${operation.details.csharp.subjectPrefix}, subject: ${operation.details.csharp.subject}${variantName ? `, variant: ${variantName}}` : '}'}`
          }
        );
      }

      const virtualParameters = [...allVirtualParameters(operation.details.csharp.virtualParameters)];
      for (const parameter of virtualParameters) {
        let prevName = parameter.name;
        const otherParametersNames = values(virtualParameters)
          .select(each => each.name)
          .where(name => name !== parameter.name)
          .toArray();

        // first try to singularize the parameter
        const singularName = singularize(parameter.name);
        if (prevName != singularName) {
          parameter.name = singularName;
          state.message({ Channel: Channel.Debug, Text: `Sanitized parameter-name -> Changed parameter-name from ${prevName} to singular ${parameter.name} from command ${operation.verb}-${operation.details.csharp.subjectPrefix}${operation.details.csharp.subject}` });
        }

        // save the name again to compare in case it was modified
        prevName = parameter.name;

        // now remove the subject from the beginning of the parameter
        // to reduce naming redundancy, but just for path parameters
        // e.g. get-vm -vmname ---> get-vm -name
        if ((<any>parameter.origin).protocol?.http?.in === ParameterLocation.Path) {
          const sanitizedName = removeProhibitedPrefix(
            parameter.name,
            operation.details.csharp.subject,
            otherParametersNames
          );

          if (prevName !== sanitizedName) {
            if (parameter.alias === undefined) {
              parameter.alias = [];
            }

            // saved the prev name as alias
            parameter.alias.push(parameter.name);

            // change name
            parameter.name = sanitizedName;
            state.message({ Channel: Channel.Debug, Text: `Sanitized parameter-name -> Changed parameter-name from ${prevName} to ${parameter.name} from command ${operation.verb}-${operation.details.csharp.subjectPrefix}${operation.details.csharp.subject}` });
            state.message({ Channel: Channel.Debug, Text: `                         -> And, added alias '${prevName}'` });
          }
        }
      }
    }

    for (const schemaGroup of values(<Dictionary<Array<Schema>>><any>state.model.schemas)) {
      for (const schema of schemaGroup) {
        const virtualProperties = [...allVirtualProperties(schema.language.csharp?.virtualProperties)];

        for (const property of virtualProperties) {
          let prevName = property.name;
          const otherPropertiesNames = values(virtualProperties)
            .select(each => each.name)
            .where(name => name !== property.name)
            .toArray();

          // first try to singularize the property
          const singularName = singularize(property.name);
          if (prevName != singularName && !otherPropertiesNames.includes(singularName)) {
            property.name = singularName;
            state.message({ Channel: Channel.Debug, Text: `Sanitized property-name -> Changed property-name from ${prevName} to singular ${property.name} from model ${schema.language.csharp?.name}` });
          }

          // save the name again to compare in case it was modified
          prevName = property.name;

          // now remove the model=name from the beginning of the property-name
          // to reduce naming redundancy
          const sanitizedName = removeProhibitedPrefix(
            property.name,
            schema.language.csharp?.name ? schema.language.csharp?.name : '',
            otherPropertiesNames
          );

          if (prevName !== sanitizedName) {
            property.alias = property.alias || [];

            // saved the prev name as alias
            property.alias.push(property.name);

            // change name
            property.name = sanitizedName;
            state.message({ Channel: Channel.Debug, Text: `Sanitized property-name -> Changed property-name from ${prevName} to ${property.name} from model ${schema.language.csharp?.name}` });
            state.message({ Channel: Channel.Debug, Text: `                        -> And, added alias '${prevName}'` });

            // update shared properties too
            if (property.sharedWith) {
              for (const sharedProperty of property.sharedWith) {
                if (sharedProperty.name !== sanitizedName) {
                  state.message({ Channel: Channel.Debug, Text: `Changing shared property ${sharedProperty.name} to ${sanitizedName}` });
                  sharedProperty.alias = sharedProperty.alias || [];
                  sharedProperty.alias.push(sharedProperty.name);
                  sharedProperty.name = sanitizedName;
                }
              }
            }
          }
        }
      }
    }
  }

  // do collision detection work.
  for (const command of values(state.model.commands.operations)) {
    const vp = command.details.csharp?.virtualParameters;
    if (vp) {
      resolveParameterNames([], vp);
    }
  }

  for (const schemaGroup of values(<Dictionary<Array<Schema>>><any>state.model.schemas)) {
    for (const schema of schemaGroup) {
      const vp = schema.language.csharp?.virtualProperties;
      if (vp) {
        resolvePropertyNames(schema.language.csharp?.name ? [schema.language.csharp?.name] : [], vp);
      }
    }
  }
  return state.model;
}