@mcp-consultant-tools/powerplatform-data 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Best Practices Validation Module
3
+ *
4
+ * Hard-coded SmartImpact CRM best practices for entity and attribute customization.
5
+ * These rules are enforced during entity and attribute creation/update operations.
6
+ */
7
+ /**
8
+ * Hard-coded best practices rules for SmartImpact CRM customizations
9
+ */
10
+ export const BEST_PRACTICES = {
11
+ publisher: {
12
+ prefix: 'sic_',
13
+ name: 'SmartImpactCustomer',
14
+ optionValuePrefix: 15743
15
+ },
16
+ entity: {
17
+ ownershipType: {
18
+ allowed: ['UserOwned', 'TeamOwned'],
19
+ forbidden: ['OrganizationOwned'],
20
+ default: 'UserOwned'
21
+ },
22
+ // Naming pattern: prefix + "ref_" + tablename (for RefData) or prefix + tablename (for BAU)
23
+ // Example RefData: sic_ref_cancellationreason (prefix=sic_, ref_ inserted, name=cancellationreason)
24
+ // Example BAU: sic_application (prefix=sic_, name=application)
25
+ prefix: 'sic_', // Publisher prefix
26
+ refDataInfix: 'ref_', // Inserted after prefix for reference data tables
27
+ caseRule: 'lowercase'
28
+ },
29
+ attribute: {
30
+ lookupSuffix: 'id',
31
+ caseRule: 'lowercase',
32
+ avoidBooleans: true,
33
+ dateTimeDefaultBehavior: 'TimeZoneIndependent'
34
+ },
35
+ requiredColumns: {
36
+ allTables: [
37
+ {
38
+ schemaName: 'sic_updatedbyprocess',
39
+ displayName: 'Updated by process',
40
+ description: 'This field is updated, each time an automated process updates this record.',
41
+ type: 'String',
42
+ maxLength: 4000
43
+ }
44
+ ],
45
+ refDataTables: [
46
+ {
47
+ schemaName: 'sic_startdate',
48
+ displayName: 'Start Date',
49
+ description: 'The date this reference data record started being used.',
50
+ type: 'DateTime',
51
+ format: 'DateOnly',
52
+ behavior: 'TimeZoneIndependent'
53
+ },
54
+ {
55
+ schemaName: 'sic_enddate',
56
+ displayName: 'End Date',
57
+ description: 'The date this reference data record stopped being used.',
58
+ type: 'DateTime',
59
+ format: 'DateOnly',
60
+ behavior: 'TimeZoneIndependent'
61
+ },
62
+ {
63
+ schemaName: 'sic_description',
64
+ displayName: 'Description',
65
+ description: 'Useful information about this reference data record.',
66
+ type: 'Memo',
67
+ maxLength: 20000
68
+ },
69
+ {
70
+ schemaName: 'sic_code',
71
+ displayName: 'Code',
72
+ description: 'Code to identify the record, instead of GUID',
73
+ type: 'String',
74
+ maxLength: 100
75
+ }
76
+ ]
77
+ },
78
+ form: {
79
+ firstColumnMustBeName: true,
80
+ standardColumnOrder: ['name', 'createdon', 'createdby', 'modifiedon', 'modifiedby', 'statuscode', 'status'],
81
+ colorPalette: {
82
+ amber: '#ffd175',
83
+ green: '#8ed483',
84
+ red: '#ff8c8c',
85
+ grey: '#d1d1d1'
86
+ },
87
+ timelineActivityLimit: 10
88
+ },
89
+ status: {
90
+ preferGlobalOptionSets: true,
91
+ avoidOOTBStateStatus: true
92
+ }
93
+ };
94
+ /**
95
+ * Best Practices Validator Class
96
+ */
97
+ export class BestPracticesValidator {
98
+ /**
99
+ * Validate entity naming conventions
100
+ * Pattern for RefData: prefix + "ref_" + tablename (e.g., sic_ref_cancellationreason)
101
+ * Pattern for BAU: prefix + tablename (e.g., sic_application)
102
+ */
103
+ validateEntityName(schemaName, isRefData) {
104
+ const rules = BEST_PRACTICES.entity;
105
+ const issues = [];
106
+ const warnings = [];
107
+ // Check lowercase
108
+ if (schemaName !== schemaName.toLowerCase()) {
109
+ issues.push(`Entity schema name must be all lowercase. Got: "${schemaName}"`);
110
+ }
111
+ // Check prefix and infix
112
+ if (!schemaName.startsWith(rules.prefix)) {
113
+ issues.push(`Entity schema name must start with publisher prefix "${rules.prefix}". Got: "${schemaName}"`);
114
+ }
115
+ else if (isRefData) {
116
+ // For RefData tables, check that "ref_" follows the prefix
117
+ const expectedPattern = rules.prefix + rules.refDataInfix;
118
+ if (!schemaName.startsWith(expectedPattern)) {
119
+ issues.push(`RefData entity schema name must follow pattern "${expectedPattern}<tablename>". ` +
120
+ `Example: ${expectedPattern}cancellationreason. Got: "${schemaName}"`);
121
+ }
122
+ }
123
+ return {
124
+ isValid: issues.length === 0,
125
+ issues,
126
+ warnings
127
+ };
128
+ }
129
+ /**
130
+ * Validate attribute naming conventions
131
+ */
132
+ validateAttributeName(schemaName, isLookup) {
133
+ const rules = BEST_PRACTICES.attribute;
134
+ const issues = [];
135
+ const warnings = [];
136
+ // Check lowercase
137
+ if (schemaName !== schemaName.toLowerCase()) {
138
+ issues.push(`Attribute schema name must be all lowercase. Got: "${schemaName}"`);
139
+ }
140
+ // Check publisher prefix
141
+ if (!schemaName.startsWith(BEST_PRACTICES.publisher.prefix)) {
142
+ issues.push(`Attribute schema name must start with "${BEST_PRACTICES.publisher.prefix}". Got: "${schemaName}"`);
143
+ }
144
+ // Check lookup suffix
145
+ if (isLookup && !schemaName.endsWith(rules.lookupSuffix)) {
146
+ warnings.push(`Lookup attribute should end with "${rules.lookupSuffix}". Got: "${schemaName}"`);
147
+ }
148
+ return {
149
+ isValid: issues.length === 0,
150
+ issues,
151
+ warnings
152
+ };
153
+ }
154
+ /**
155
+ * Validate entity ownership type
156
+ */
157
+ validateOwnershipType(ownershipType) {
158
+ const rules = BEST_PRACTICES.entity.ownershipType;
159
+ const issues = [];
160
+ if (rules.forbidden.includes(ownershipType)) {
161
+ issues.push(`Ownership type "${ownershipType}" is forbidden. Use "${rules.default}" instead.`);
162
+ }
163
+ if (!rules.allowed.includes(ownershipType)) {
164
+ issues.push(`Ownership type "${ownershipType}" is not in allowed list: ${rules.allowed.join(', ')}`);
165
+ }
166
+ return {
167
+ isValid: issues.length === 0,
168
+ issues,
169
+ warnings: []
170
+ };
171
+ }
172
+ /**
173
+ * Check if required columns are present
174
+ */
175
+ validateRequiredColumns(existingColumns, isRefData) {
176
+ const rules = BEST_PRACTICES.requiredColumns;
177
+ const issues = [];
178
+ const missingColumns = [];
179
+ // Check all-tables columns
180
+ for (const column of rules.allTables) {
181
+ if (!existingColumns.includes(column.schemaName)) {
182
+ missingColumns.push(column);
183
+ issues.push(`Missing required column: ${column.schemaName} (${column.displayName})`);
184
+ }
185
+ }
186
+ // Check ref-data-specific columns
187
+ if (isRefData) {
188
+ for (const column of rules.refDataTables) {
189
+ if (!existingColumns.includes(column.schemaName)) {
190
+ missingColumns.push(column);
191
+ issues.push(`Missing required RefData column: ${column.schemaName} (${column.displayName})`);
192
+ }
193
+ }
194
+ }
195
+ return {
196
+ isValid: issues.length === 0,
197
+ issues,
198
+ warnings: [],
199
+ missingColumns
200
+ };
201
+ }
202
+ /**
203
+ * Validate boolean usage (discouraged)
204
+ */
205
+ validateBooleanUsage(attributeType, schemaName) {
206
+ const issues = [];
207
+ const warnings = [];
208
+ if (attributeType === 'Boolean' && BEST_PRACTICES.attribute.avoidBooleans) {
209
+ warnings.push(`Boolean attribute "${schemaName}" should be avoided. ` +
210
+ `Consider using a picklist with explicit values instead for better clarity.`);
211
+ }
212
+ return {
213
+ isValid: true, // Warnings only, not an error
214
+ issues,
215
+ warnings
216
+ };
217
+ }
218
+ /**
219
+ * Validate DateTime behavior
220
+ */
221
+ validateDateTimeBehavior(behavior) {
222
+ const issues = [];
223
+ const warnings = [];
224
+ const defaultBehavior = BEST_PRACTICES.attribute.dateTimeDefaultBehavior;
225
+ if (behavior && behavior !== defaultBehavior) {
226
+ warnings.push(`DateTime behavior "${behavior}" differs from recommended "${defaultBehavior}". ` +
227
+ `Consider using "${defaultBehavior}" for consistency.`);
228
+ }
229
+ return {
230
+ isValid: true, // Warnings only
231
+ issues,
232
+ warnings
233
+ };
234
+ }
235
+ /**
236
+ * Get required columns for entity type
237
+ */
238
+ getRequiredColumns(isRefData) {
239
+ const columns = [...BEST_PRACTICES.requiredColumns.allTables];
240
+ if (isRefData) {
241
+ columns.push(...BEST_PRACTICES.requiredColumns.refDataTables);
242
+ }
243
+ return columns;
244
+ }
245
+ /**
246
+ * Validate option set value prefix
247
+ */
248
+ validateOptionSetValuePrefix(value) {
249
+ const issues = [];
250
+ const warnings = [];
251
+ const expectedPrefix = BEST_PRACTICES.publisher.optionValuePrefix;
252
+ const valueStr = value.toString();
253
+ const prefixStr = expectedPrefix.toString();
254
+ if (!valueStr.startsWith(prefixStr)) {
255
+ warnings.push(`Option set value ${value} does not start with publisher prefix ${expectedPrefix}. ` +
256
+ `Values should start with ${prefixStr} for consistency.`);
257
+ }
258
+ return {
259
+ isValid: true, // Warnings only
260
+ issues,
261
+ warnings
262
+ };
263
+ }
264
+ /**
265
+ * Generate next option set value with proper prefix
266
+ */
267
+ getNextOptionSetValue(existingValues) {
268
+ const prefix = BEST_PRACTICES.publisher.optionValuePrefix;
269
+ const prefixStr = prefix.toString();
270
+ // Find all values that start with our prefix
271
+ const ourValues = existingValues
272
+ .filter(v => v.toString().startsWith(prefixStr))
273
+ .sort((a, b) => b - a);
274
+ if (ourValues.length === 0) {
275
+ // Start with prefix + 0001
276
+ return prefix * 10000 + 1;
277
+ }
278
+ // Increment the highest value
279
+ return ourValues[0] + 1;
280
+ }
281
+ /**
282
+ * Comprehensive entity validation
283
+ */
284
+ validateEntity(params) {
285
+ const allIssues = [];
286
+ const allWarnings = [];
287
+ let missingColumns;
288
+ // Validate schema name
289
+ const nameResult = this.validateEntityName(params.schemaName, params.isRefData);
290
+ allIssues.push(...nameResult.issues);
291
+ allWarnings.push(...nameResult.warnings);
292
+ // Validate ownership type
293
+ const ownershipResult = this.validateOwnershipType(params.ownershipType);
294
+ allIssues.push(...ownershipResult.issues);
295
+ allWarnings.push(...ownershipResult.warnings);
296
+ // Validate required columns if checking existing entity
297
+ if (params.existingColumns) {
298
+ const columnsResult = this.validateRequiredColumns(params.existingColumns, params.isRefData);
299
+ allIssues.push(...columnsResult.issues);
300
+ allWarnings.push(...columnsResult.warnings);
301
+ missingColumns = columnsResult.missingColumns;
302
+ }
303
+ return {
304
+ isValid: allIssues.length === 0,
305
+ issues: allIssues,
306
+ warnings: allWarnings,
307
+ missingColumns
308
+ };
309
+ }
310
+ /**
311
+ * Comprehensive attribute validation
312
+ */
313
+ validateAttribute(params) {
314
+ const allIssues = [];
315
+ const allWarnings = [];
316
+ // Validate schema name
317
+ const isLookup = params.attributeType === 'Lookup' || params.attributeType === 'Customer';
318
+ const nameResult = this.validateAttributeName(params.schemaName, isLookup);
319
+ allIssues.push(...nameResult.issues);
320
+ allWarnings.push(...nameResult.warnings);
321
+ // Validate boolean usage
322
+ const boolResult = this.validateBooleanUsage(params.attributeType, params.schemaName);
323
+ allWarnings.push(...boolResult.warnings);
324
+ // Validate DateTime behavior if applicable
325
+ if (params.attributeType === 'DateTime' && params.dateTimeBehavior) {
326
+ const behaviorResult = this.validateDateTimeBehavior(params.dateTimeBehavior);
327
+ allWarnings.push(...behaviorResult.warnings);
328
+ }
329
+ return {
330
+ isValid: allIssues.length === 0,
331
+ issues: allIssues,
332
+ warnings: allWarnings
333
+ };
334
+ }
335
+ }
336
+ // Export singleton instance
337
+ export const bestPracticesValidator = new BestPracticesValidator();
338
+ //# sourceMappingURL=bestPractices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bestPractices.js","sourceRoot":"","sources":["../../src/utils/bestPractices.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE;QACT,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,qBAAqB;QAC3B,iBAAiB,EAAE,KAAK;KACzB;IAED,MAAM,EAAE;QACN,aAAa,EAAE;YACb,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;YACnC,SAAS,EAAE,CAAC,mBAAmB,CAAC;YAChC,OAAO,EAAE,WAAW;SACrB;QACD,4FAA4F;QAC5F,oGAAoG;QACpG,+DAA+D;QAC/D,MAAM,EAAE,MAAM,EAAS,mBAAmB;QAC1C,YAAY,EAAE,MAAM,EAAG,kDAAkD;QACzE,QAAQ,EAAE,WAAW;KACtB;IAED,SAAS,EAAE;QACT,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,WAAW;QACrB,aAAa,EAAE,IAAI;QACnB,uBAAuB,EAAE,qBAAqB;KAC/C;IAED,eAAe,EAAE;QACf,SAAS,EAAE;YACT;gBACE,UAAU,EAAE,sBAAsB;gBAClC,WAAW,EAAE,oBAAoB;gBACjC,WAAW,EAAE,4EAA4E;gBACzF,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,IAAI;aAChB;SACF;QACD,aAAa,EAAE;YACb;gBACE,UAAU,EAAE,eAAe;gBAC3B,WAAW,EAAE,YAAY;gBACzB,WAAW,EAAE,yDAAyD;gBACtE,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,QAAQ,EAAE,qBAAqB;aAChC;YACD;gBACE,UAAU,EAAE,aAAa;gBACzB,WAAW,EAAE,UAAU;gBACvB,WAAW,EAAE,yDAAyD;gBACtE,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,QAAQ,EAAE,qBAAqB;aAChC;YACD;gBACE,UAAU,EAAE,iBAAiB;gBAC7B,WAAW,EAAE,aAAa;gBAC1B,WAAW,EAAE,sDAAsD;gBACnE,IAAI,EAAE,MAAM;gBACZ,SAAS,EAAE,KAAK;aACjB;YACD;gBACE,UAAU,EAAE,UAAU;gBACtB,WAAW,EAAE,MAAM;gBACnB,WAAW,EAAE,8CAA8C;gBAC3D,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,GAAG;aACf;SACF;KACF;IAED,IAAI,EAAE;QACJ,qBAAqB,EAAE,IAAI;QAC3B,mBAAmB,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC;QAC3G,YAAY,EAAE;YACZ,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,SAAS;SAChB;QACD,qBAAqB,EAAE,EAAE;KAC1B;IAED,MAAM,EAAE;QACN,sBAAsB,EAAE,IAAI;QAC5B,oBAAoB,EAAE,IAAI;KAC3B;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAEjC;;;;OAIG;IACH,kBAAkB,CAAC,UAAkB,EAAE,SAAkB;QACvD,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC;QACpC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,kBAAkB;QAClB,IAAI,UAAU,KAAK,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,mDAAmD,UAAU,GAAG,CAAC,CAAC;QAChF,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,wDAAwD,KAAK,CAAC,MAAM,YAAY,UAAU,GAAG,CAAC,CAAC;QAC7G,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,2DAA2D;YAC3D,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,CACT,mDAAmD,eAAe,gBAAgB;oBAClF,YAAY,eAAe,6BAA6B,UAAU,GAAG,CACtE,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;YAC5B,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,UAAkB,EAAE,QAAiB;QACzD,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,CAAC;QACvC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,kBAAkB;QAClB,IAAI,UAAU,KAAK,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,sDAAsD,UAAU,GAAG,CAAC,CAAC;QACnF,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5D,MAAM,CAAC,IAAI,CAAC,0CAA0C,cAAc,CAAC,SAAS,CAAC,MAAM,YAAY,UAAU,GAAG,CAAC,CAAC;QAClH,CAAC;QAED,sBAAsB;QACtB,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YACzD,QAAQ,CAAC,IAAI,CAAC,qCAAqC,KAAK,CAAC,YAAY,YAAY,UAAU,GAAG,CAAC,CAAC;QAClG,CAAC;QAED,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;YAC5B,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,aAAqB;QACzC,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC;QAClD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,mBAAmB,aAAa,wBAAwB,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;QACjG,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,mBAAmB,aAAa,6BAA6B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvG,CAAC;QAED,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;YAC5B,MAAM;YACN,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,uBAAuB,CACrB,eAAyB,EACzB,SAAkB;QAElB,MAAM,KAAK,GAAG,cAAc,CAAC,eAAe,CAAC;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,cAAc,GAAqB,EAAE,CAAC;QAE5C,2BAA2B;QAC3B,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjD,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC5B,MAAM,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACzC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;oBACjD,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,oCAAoC,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;gBAC/F,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;YAC5B,MAAM;YACN,QAAQ,EAAE,EAAE;YACZ,cAAc;SACf,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,oBAAoB,CAAC,aAAqB,EAAE,UAAkB;QAC5D,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,IAAI,aAAa,KAAK,SAAS,IAAI,cAAc,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC;YAC1E,QAAQ,CAAC,IAAI,CACX,sBAAsB,UAAU,uBAAuB;gBACvD,4EAA4E,CAC7E,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI,EAAE,8BAA8B;YAC7C,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,wBAAwB,CAAC,QAA4B;QACnD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,eAAe,GAAG,cAAc,CAAC,SAAS,CAAC,uBAAuB,CAAC;QAEzE,IAAI,QAAQ,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;YAC7C,QAAQ,CAAC,IAAI,CACX,sBAAsB,QAAQ,+BAA+B,eAAe,KAAK;gBACjF,mBAAmB,eAAe,oBAAoB,CACvD,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI,EAAE,gBAAgB;YAC/B,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,SAAkB;QACnC,MAAM,OAAO,GAAqB,CAAC,GAAG,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAChF,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,eAAe,CAAC,aAAiC,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,4BAA4B,CAAC,KAAa;QACxC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,cAAc,GAAG,cAAc,CAAC,SAAS,CAAC,iBAAiB,CAAC;QAElE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;QAE5C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CACX,oBAAoB,KAAK,yCAAyC,cAAc,IAAI;gBACpF,4BAA4B,SAAS,mBAAmB,CACzD,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI,EAAE,gBAAgB;YAC/B,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,cAAwB;QAC5C,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,iBAAiB,CAAC;QAC1D,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEpC,6CAA6C;QAC7C,MAAM,SAAS,GAAG,cAAc;aAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;aAC/C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,2BAA2B;YAC3B,OAAO,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC;QAC5B,CAAC;QAED,8BAA8B;QAC9B,OAAO,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,MAMd;QACC,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,IAAI,cAA4C,CAAC;QAEjD,uBAAuB;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAChF,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEzC,0BAA0B;QAC1B,MAAM,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACzE,SAAS,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QAC1C,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAE9C,wDAAwD;QACxD,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YAC7F,SAAS,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YACxC,WAAW,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC5C,cAAc,GAAG,aAAa,CAAC,cAAc,CAAC;QAChD,CAAC;QAED,OAAO;YACL,OAAO,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC;YAC/B,MAAM,EAAE,SAAS;YACjB,QAAQ,EAAE,WAAW;YACrB,cAAc;SACf,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,MAIjB;QACC,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,uBAAuB;QACvB,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,KAAK,UAAU,CAAC;QAC1F,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3E,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEzC,yBAAyB;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACtF,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEzC,2CAA2C;QAC3C,IAAI,MAAM,CAAC,aAAa,KAAK,UAAU,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACnE,MAAM,cAAc,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAC9E,WAAW,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO;YACL,OAAO,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC;YAC/B,MAAM,EAAE,SAAS;YACjB,QAAQ,EAAE,WAAW;SACtB,CAAC;IACJ,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Icon Management Module
3
+ *
4
+ * Integrates with Fluent UI System Icons for entity icon management.
5
+ * Fetches SVG icons from GitHub and uploads them as web resources.
6
+ */
7
+ export interface IconSuggestion {
8
+ name: string;
9
+ fileName: string;
10
+ url: string;
11
+ category: string;
12
+ }
13
+ export interface IconUploadResult {
14
+ webResourceId: string;
15
+ webResourceName: string;
16
+ iconVectorName: string;
17
+ success: boolean;
18
+ error?: string;
19
+ }
20
+ /**
21
+ * Icon Manager Class
22
+ */
23
+ export declare class IconManager {
24
+ private baseUrl;
25
+ private cache;
26
+ constructor();
27
+ /**
28
+ * Suggest icons based on entity name or type
29
+ */
30
+ suggestIcons(entityName: string): IconSuggestion[];
31
+ /**
32
+ * Populate full URLs for icon suggestions
33
+ */
34
+ private populateUrls;
35
+ /**
36
+ * Parse icon filename and construct GitHub path
37
+ * Converts: people_community_24_filled.svg
38
+ * To: assets/People Community/SVG/ic_fluent_people_community_24_filled.svg
39
+ */
40
+ private constructFluentIconPath;
41
+ /**
42
+ * Fetch SVG icon from Fluent UI GitHub repository
43
+ */
44
+ fetchIcon(fileName: string): Promise<string>;
45
+ /**
46
+ * Generate web resource name for icon
47
+ */
48
+ generateWebResourceName(entitySchemaName: string, iconName: string): string;
49
+ /**
50
+ * Generate icon vector name for EntityMetadata
51
+ * Uses $webresource: directive which is the correct syntax for Dynamics 365
52
+ * This creates a solution dependency and tells the system to look up the web resource by name
53
+ */
54
+ generateIconVectorName(webResourceName: string): string;
55
+ /**
56
+ * Validate icon SVG content
57
+ */
58
+ validateIconSvg(svg: string): {
59
+ valid: boolean;
60
+ error?: string;
61
+ };
62
+ /**
63
+ * Get all available icon categories
64
+ */
65
+ getCategories(): string[];
66
+ /**
67
+ * Search icons by name
68
+ */
69
+ searchIcons(searchTerm: string): IconSuggestion[];
70
+ /**
71
+ * Get icons by category
72
+ */
73
+ getIconsByCategory(category: string): IconSuggestion[];
74
+ /**
75
+ * Build custom icon URL for specific size/style
76
+ */
77
+ buildIconUrl(iconName: string, size?: number, style?: 'filled' | 'regular'): string;
78
+ /**
79
+ * Clear icon cache
80
+ */
81
+ clearCache(): void;
82
+ }
83
+ export declare const iconManager: IconManager;
84
+ //# sourceMappingURL=iconManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iconManager.d.ts","sourceRoot":"","sources":["../../src/utils/iconManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4ID;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAkC;;IAM/C;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE;IAqBlD;;OAEG;IACH,OAAO,CAAC,YAAY;IAkBpB;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAqC/B;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkClD;;OAEG;IACH,uBAAuB,CAAC,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQ3E;;;;OAIG;IACH,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IAIvD;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAiBhE;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAQzB;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE;IAkBjD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE;IActD;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAW,EAAE,KAAK,GAAE,QAAQ,GAAG,SAAoB,GAAG,MAAM;IAUjG;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}