diff --git a/config/ModulesMapping.jsonc b/config/ModulesMapping.jsonc index 42eae1ee71d..4e1ea5835bf 100644 --- a/config/ModulesMapping.jsonc +++ b/config/ModulesMapping.jsonc @@ -1,4 +1,4 @@ - { +{ "Applications": "^applicationTemplates\\.|^applications\\.|^servicePrincipals\\.|^onPremisesPublishingProfiles\\.|^users.appRoleAssignment$|^groups.appRoleAssignment$", "Bookings": "^bookingBusinesses\\.|^bookingCurrencies\\.|^solutions.booking.*.Actions$|^solutions.bookingBusiness$|^solutions.bookingCurrency$|^solutions.virtualEventsRoot$|^solutions.booking.*.Functions$|^solutions.solutionsRoot$", "BusinessScenario": "^solutions.businessScenario$|^solutions.BusinessScenario.*.Actions$|^solutions.BusinessScenario.*.Functions$", @@ -21,7 +21,7 @@ "Financials": "^financials\\.", "Groups": "^groups.group$|^groups.directoryObject$|^groups.conversation$|^groups.endpoint$|^groups.extension$|^groups.groupLifecyclePolicy$|^groups.resourceSpecificPermissionGrant$|^groups.profilePhoto$|^groups.conversationThread$|^groupLifecyclePolicies\\.|^users.group$|^groups.directorySetting$|^groups.*.Actions$|^groups.*.Functions$|^groupSettings\\.|^groups.groupSetting$|^groupSettingTemplates\\.", "Identity.DirectoryManagement": "^administrativeUnits\\.|^contacts\\.|^devices\\.|^domains\\.|^directoryRoles\\.|^directoryRoleTemplates\\.|^directorySettingTemplates\\.|^settings\\.|^subscribedSkus\\.|^contracts\\.|^directory\\.|^users.scopedRoleMembership$|^organization.organization$|^organization.organizationalBranding$|^organization.organizationSettings$|^organization.*.Actions$|^organization.extension$|^tenantRelationships.*.Actions$|^tenantRelationships.*.Functions$|admin.peopleAdminSettings$|^organization\\.partnerInformation$", - "Identity.Governance": "^accessReviews\\.|^businessFlowTemplates\\.|^programs\\.|^programControls\\.|^programControlTypes\\.|^privilegedRoles\\.|^privilegedRoleAssignments\\.|^privilegedRoleAssignmentRequests\\.|^privilegedApproval\\.|^privilegedOperationEvents\\.|^privilegedAccess\\.|^agreements\\.|^users.agreementAcceptance$|^identityGovernance\\.|^roleManagement.rbacApplication$|^roleManagement.*.Functions$|roleManagement.*.Actions$", + "Identity.Governance": "^accessReviews\\.|^businessFlowTemplates\\.|^programs\\.|^programControls\\.|^programControlTypes\\.|^privilegedRoles\\.|^privilegedRoleAssignments\\.|^privilegedRoleAssignmentRequests\\.|^privilegedApproval\\.|^privilegedOperationEvents\\.|^privilegedAccess\\.|^agreements\\.|^users.agreementAcceptance$|^identityGovernance\\.|^roleManagement.rbacApplication$|^roleManagement.*.Functions$|roleManagement.*.Actions$", "Identity.SignIns": "^organization.certificateBasedAuthConfiguration$|^invitations\\.|^identityProviders\\.|^oauth2PermissionGrants\\.|^identityProtection\\.|^dataPolicyOperations\\.|^identity\\.|^trustFramework\\.|^informationProtection\\.|^policies\\.|^users.authentication$|^users.informationProtection$|^tenantRelationships.multiTenantOrganization$|^policies.deviceRegistrationPolicy$|^policies.deviceRegistrationPolicy$", "Identity.Partner": "^tenantRelationships.delegatedAdminRelationship$|^tenantRelationships.delegatedAdminCustomer$", "Mail": "^users.inferenceClassification$|^users.mailFolder$|^users.message$", @@ -41,4 +41,4 @@ "Users.Actions": "^users.*.Actions$", "Users.Functions": "^users.*.Functions$", "WindowsUpdates": "^admin.adminWindows$" - } \ No newline at end of file +} diff --git a/openApiDocs/v1.0/Education.yml b/openApiDocs/v1.0/Education.yml index 159461e5aad..d1311f54922 100644 --- a/openApiDocs/v1.0/Education.yml +++ b/openApiDocs/v1.0/Education.yml @@ -31508,4 +31508,4 @@ components: tokenUrl: https://login.microsoftonline.com/common/oauth2/v2.0/token scopes: { } security: - - azureaadv2: [ ] + - azureaadv2: [ ] \ No newline at end of file diff --git a/src/Teams/beta/custom/MicrosoftGraphRscConfiguration.cs b/src/Teams/beta/custom/MicrosoftGraphRscConfiguration.cs index 59c19bc9ed7..260f2b36987 100644 --- a/src/Teams/beta/custom/MicrosoftGraphRscConfiguration.cs +++ b/src/Teams/beta/custom/MicrosoftGraphRscConfiguration.cs @@ -15,10 +15,6 @@ public partial class MicrosoftGraphRscConfiguration : IMicrosoftGraphRscConfigurationInternal, Runtime.IValidates { - private readonly PropertyTracker _propertyTracker = new PropertyTracker(); - public void TrackProperty(string propertyName) => _propertyTracker.TrackProperty(propertyName); - public bool IsPropertySet(string propertyName) =>_propertyTracker.IsPropertySet(propertyName); - public T SanitizeValue(object value) => PropertyTracker.SanitizeValue(value); /// /// Backing field for Inherited model /// diff --git a/src/Teams/beta/custom/MicrosoftGraphTeamsAppPreApproval.cs b/src/Teams/beta/custom/MicrosoftGraphTeamsAppPreApproval.cs index af7f1c44b91..5e1fb804a41 100644 --- a/src/Teams/beta/custom/MicrosoftGraphTeamsAppPreApproval.cs +++ b/src/Teams/beta/custom/MicrosoftGraphTeamsAppPreApproval.cs @@ -15,10 +15,6 @@ public partial class MicrosoftGraphTeamsAppPreApproval : IMicrosoftGraphTeamsAppPreApprovalInternal, Runtime.IValidates { - private readonly PropertyTracker _propertyTracker = new PropertyTracker(); - public void TrackProperty(string propertyName) => _propertyTracker.TrackProperty(propertyName); - public bool IsPropertySet(string propertyName) =>_propertyTracker.IsPropertySet(propertyName); - public T SanitizeValue(object value) => PropertyTracker.SanitizeValue(value); /// /// Backing field for Inherited model diff --git a/src/readme.graph.md b/src/readme.graph.md index ddfe0e0653c..d7d1b21ddcd 100644 --- a/src/readme.graph.md +++ b/src/readme.graph.md @@ -334,25 +334,6 @@ directive: let dateTimeToJsonRegex = /(\.Json\.JsonString\()(.*)\?(\.ToString\(@"yyyy'-'MM'-'dd'T'HH':'mm':'ss\.fffffffK")/gm $ = $.replace(dateTimeToJsonRegex, '$1System.DateTime.SpecifyKind($2.Value.ToUniversalTime(), System.DateTimeKind.Utc)$3'); - //The following regex below adds a property tracker to ensure that users can also pass $Null as an alternative to the current "null" string which gets inferred to null. - - const regexP = /AddIf\(\s*null\s*!=\s*\(\(\(object\)this\._(\w+).*?(\(Microsoft.*.PowerShell\.Runtime\.Json\.JsonNode\)).*?"(\w+)".*?container\.Add\s*\);/gm - $ = $.replace(regexP, (match, p1, p2, p3) => { - let capitalizedP1 = p1.charAt(0).toUpperCase() + p1.slice(1); // Capitalize first letter - return `if(this.IsPropertySet("${p1}"))\n\t\t{\n\t\t\tvar propertyInfo = this.GetType().GetProperty("${capitalizedP1}");\n\t\t\tif (propertyInfo != null)\n\t\t\t{\n\t\t\tSystem.Type propertyType = propertyInfo.PropertyType;\n\t\t\t\t\tAddIf(${p2}PropertyTracker.ConvertToJsonNode(propertyType, this._${p1}),"${p1}",container.Add);\n\t\t\t}\n\t\t}`; - }); - - $ = $.replace(/if\s*\(\s*null\s*!=\s*this\._(\w+)\s*\)/gm, 'if(this.IsPropertySet("$1"))') - - let nameSpacePrefixRegex = /(Microsoft(?:\.\w+)*?\.PowerShell)/gm - let nameSpacePrefix = 'Microsoft.Graph.PowerShell'; - if($.match(nameSpacePrefixRegex)){ - let prefixMatch = nameSpacePrefixRegex.exec($); - nameSpacePrefix = prefixMatch[1]; - } - $ = $.replace(/container\.Add\("(\w+)",\s*(__\w+)\);/gm, 'var nullFlag = ('+nameSpacePrefix+'.Runtime.Json.JsonNode)new '+nameSpacePrefix+'.Runtime.Json.JsonString("nullarray");\n\t\tif($2.Count == 0)\n\t\t{\n\t\t\t$2.Add(nullFlag);\n\t\t}\n\t\tcontainer.Add("$1", $2);'); - - $ =$.replace(/AddIf\(\s+null\s+!=\s+(this\._\w+)\s+\?\s+\((Microsoft\.Graph\..*?)\)\s+this\._(\w+)\.ToJson\(null,serializationMode\)\s+:\s+null,\s+"\w+"\s+,container.Add\s+\);/gm, 'if (this.IsPropertySet("$3")) \n{\n if ($1 != null)\n{\n container.Add("$3", ($2)$1.ToJson(null, serializationMode)); \n}\nelse\n{\n container.Add("$3", "null"); \n}\n}'); return $; } @@ -419,28 +400,6 @@ directive: if($.match(additionalPropertiesRegex)) { $ = $.replace(additionalPropertiesRegex, '$1$2 new $3'); } - //The following regex below adds a property tracker to ensure that users can also pass $Null as an alternative to the current "null" string which gets inferred to null. - $ = $.replace(/\bpublic\s+(\w+\??)\s+(\w+)\s*{\s*get\s*=>\s*this\.(\w+);\s*set\s*=>\s*this\.\3\s*=\s*value;\s*}/gmi,'public $1 $2\n\t{\n\t\tget=>this.$3;\n\t\tset\n\t\t{\n\t\t\tthis.$3=SanitizeValue<$1>(value);\n\t\t\tTrackProperty(nameof($2));\n\t\t}\n\t}') - - $ = $.replace(/\bpublic\s+(\w+\[\])\s+(\w+)\s*{\s*get\s*=>\s*this\.(\w+);\s*set\s*=>\s*this\.\3\s*=\s*value;\s*}/gm,'public $1 $2\n\t{\n\t\tget=>this.$3;\n\t\tset\n\t\t{\n\t\t\tthis.$3=value;\n\t\t\tTrackProperty(nameof($2));\n\t\t}\n\t}') - - $ = $.replace(/\bpublic\s+(Microsoft\.Graph\.[\w.]+\[\])\s+(\w+)\s*{\s*get\s*=>\s*this\.(\w+);\s*set\s*=>\s*this\.\3\s*=\s*value;\s*}/gm,'public $1 $2\n\t{\n\t\tget=>this.$3;\n\t\tset\n\t\t{\n\t\t\tthis.$3=value;\n\t\t\tTrackProperty(nameof($2));\n\t\t}\n\t}') - - const match = $documentPath.match(/generated%2Fapi%2FModels%2F([\w]*[\w\d]*)\.cs/gm); - if (match) { - let fileName = match[0]; - fileName = fileName.replace('generated%2Fapi%2FModels%2F','') - fileName = fileName.replace('.cs','') - const interfaceName = 'I'+fileName - $ = $.replace('interface '+interfaceName+' :', 'interface '+interfaceName+' : IPropertyTracker,') - const className = fileName - const regexP = new RegExp(`public\\s+partial\\s+class\\s+${className}\\s*:\\s*[\\s\\S]*?{`, "gm"); - var matches = regexP.exec($); - let originalMatch = matches[0]; - $ = $.replace(regexP, originalMatch+'\n\t\tprivate readonly PropertyTracker _propertyTracker = new PropertyTracker();\n\t\tpublic void TrackProperty(string propertyName) => _propertyTracker.TrackProperty(propertyName);\n\t\tpublic bool IsPropertySet(string propertyName) =>_propertyTracker.IsPropertySet(propertyName);\n\t\tpublic T SanitizeValue(object value) => PropertyTracker.SanitizeValue(value);'); - } - - $ = $.replace(/public\s+(Microsoft\.Graph\..*?)\s+(\w+)\s+{\s+get\s+=>\s+\(\s*this\.(\w+)\s+=\s*this\.\3\s+\?\?\s+new\s+(Microsoft\.Graph\..*?)\s+set\s+=>\s+this._\w+\s+=\s+value;\s+}/gm, 'public $1 $2 { \n get => (this.$3 = this.$3 ?? new $4\n set\n {\n this.$3 = value;\n TrackProperty(nameof($2));\n }\n}') return $; @@ -495,7 +454,7 @@ directive: } }); } - + return $; } @@ -697,6 +656,7 @@ directive: $ = $.replace(/request\.Content\s*=\s*new\s+global::System\.Net\.Http\.StringContent\(\s*null\s*!=\s*body\s*\?\s*new\s+Microsoft\.Graph\.Beta\.PowerShell\.Runtime\.Json\.XNodeArray\(.*?\)\s*:\s*null,\s*global::System\.Text\.Encoding\.UTF8\);/g,'request.Content = new global::System.Net.Http.StringContent(cleanedBody, global::System.Text.Encoding.UTF8);'); $ = $.replace(/cleanedBody = Microsoft.*.ReplaceAndRemoveSlashes\(cleanedBody\);/gm,'') + return $ } diff --git a/tools/Custom/IPropertyTracker.cs b/tools/Custom/IPropertyTracker.cs deleted file mode 100644 index 1eb7db34169..00000000000 --- a/tools/Custom/IPropertyTracker.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace NamespacePrefixPlaceholder.PowerShell.Models -{ - public interface IPropertyTracker - { - void TrackProperty(string propertyName); - bool IsPropertySet(string propertyName); - T SanitizeValue(object value); - } -} \ No newline at end of file diff --git a/tools/Custom/PropertyTracker.cs b/tools/Custom/PropertyTracker.cs deleted file mode 100644 index 1d8dde56db3..00000000000 --- a/tools/Custom/PropertyTracker.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; - - -namespace NamespacePrefixPlaceholder.PowerShell.Models -{ - public class PropertyTracker - { - private readonly HashSet _trackedProperties = new HashSet(); - - public void TrackProperty(string propertyName) - { - _trackedProperties.Add(propertyName); // ✅ Track properties that are set - } - - public bool IsPropertySet(string propertyName) - { - // Ensure that the first character of the property name is UpperCase - if (propertyName.Length > 0) - { - propertyName = char.ToUpper(propertyName[0]) + propertyName.Substring(1); - } - return _trackedProperties.Contains(propertyName); - } - public static T SanitizeValue(object value) - { - if (typeof(T) == typeof(string)) - { - return (T)(object)(string.IsNullOrEmpty(value as string) ? null : value); - } - return (T)value; - } - public static NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonNode ConvertToJsonNode(Type propertyType, object value) - { - if (value == null) - { - return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonString("null"); // Explicitly return null if the property is set to null - } - - // Get the declared property type using reflection - - - // Handle different types based on the declared type - if (propertyType == typeof(string)) - { - return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonString(value.ToString()); - } - else if (propertyType == typeof(int) || propertyType == typeof(int?) || - propertyType == typeof(long) || propertyType == typeof(long?) || - propertyType == typeof(short) || propertyType == typeof(short?)) - { - return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonNumber(Convert.ToDouble(value)); - } - else if (propertyType == typeof(bool) || propertyType == typeof(bool?)) - { - return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonBoolean((bool)value); - } - else if (propertyType.IsEnum) - { - return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonString(value.ToString()); - } - else if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?)) - { - return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonString(((DateTime)value).ToString("o")); // ISO 8601 format - } - - // Fallback to JSON object if the type is complex - return NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonObject.FromObject(value); - } - } -} -