@microsoft/app-manifest 1.0.4-alpha.3344620f2.0 → 1.0.4-alpha.3446e1b60.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.
Files changed (32) hide show
  1. package/build/ManifestCommonProperties.d.ts +4 -0
  2. package/build/declarativeCopilotManifest.d.ts +43 -0
  3. package/build/declarativeCopilotManifest.js +3 -0
  4. package/build/declarativeCopilotManifest.js.map +1 -1
  5. package/build/generated-types/index.js +10 -3
  6. package/build/generated-types/index.js.map +1 -1
  7. package/build/index.d.ts +1 -0
  8. package/build/index.js +1 -0
  9. package/build/index.js.map +1 -1
  10. package/build/manifest.d.ts +78 -2
  11. package/build/manifest.js +2 -2
  12. package/build/manifest.js.map +1 -1
  13. package/build/pluginManifest.d.ts +56 -0
  14. package/build/pluginManifest.js +2 -0
  15. package/build/pluginManifest.js.map +1 -1
  16. package/build/tsconfig.tsbuildinfo +1 -1
  17. package/build/wrappers/APIPluginManifestWrapper.d.ts +185 -0
  18. package/build/wrappers/APIPluginManifestWrapper.js +309 -0
  19. package/build/wrappers/APIPluginManifestWrapper.js.map +1 -0
  20. package/build/wrappers/BaseManifest.d.ts +57 -0
  21. package/build/wrappers/BaseManifest.js +84 -0
  22. package/build/wrappers/BaseManifest.js.map +1 -0
  23. package/build/wrappers/DeclarativeAgentManifestWrapper.d.ts +245 -0
  24. package/build/wrappers/DeclarativeAgentManifestWrapper.js +403 -0
  25. package/build/wrappers/DeclarativeAgentManifestWrapper.js.map +1 -0
  26. package/build/wrappers/TeamsManifestWrapper.d.ts +436 -0
  27. package/build/wrappers/TeamsManifestWrapper.js +709 -0
  28. package/build/wrappers/TeamsManifestWrapper.js.map +1 -0
  29. package/build/wrappers/index.d.ts +15 -0
  30. package/build/wrappers/index.js +28 -0
  31. package/build/wrappers/index.js.map +1 -0
  32. package/package.json +5 -3
@@ -0,0 +1,709 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.TeamsManifestWrapper = exports.ComposeExtensionTypeEnum = exports.ConfigurableTabScope = exports.StaticTabScope = exports.DefaultInstallScope = void 0;
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const strip_bom_1 = __importDefault(require("strip-bom"));
11
+ const generated_types_1 = require("../generated-types");
12
+ /**
13
+ * Default install scope enum for Teams manifests.
14
+ */
15
+ exports.DefaultInstallScope = {
16
+ personal: "personal",
17
+ team: "team",
18
+ groupChat: "groupChat",
19
+ meetings: "meetings",
20
+ copilot: "copilot",
21
+ };
22
+ /**
23
+ * Static tab scope enum for Teams manifests.
24
+ */
25
+ exports.StaticTabScope = {
26
+ personal: "personal",
27
+ team: "team",
28
+ groupChat: "groupChat",
29
+ };
30
+ /**
31
+ * Configurable tab scope enum for Teams manifests.
32
+ */
33
+ exports.ConfigurableTabScope = {
34
+ team: "team",
35
+ groupChat: "groupChat",
36
+ };
37
+ /**
38
+ * Compose extension type enum for Teams manifests.
39
+ */
40
+ exports.ComposeExtensionTypeEnum = {
41
+ botBased: "botBased",
42
+ apiBased: "apiBased",
43
+ };
44
+ /**
45
+ * OOP wrapper for Teams App Manifest.
46
+ *
47
+ * Provides a fluent API for manipulating Teams app manifests with
48
+ * type safety, state tracking, and convenient operations.
49
+ *
50
+ * Note: This class does not extend BaseManifest due to TeamsManifest union type
51
+ * constraints, but provides the same interface and functionality.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // Read existing manifest
56
+ * const manifest = await TeamsManifestWrapper.read("manifest.json");
57
+ *
58
+ * // Modify with fluent API
59
+ * manifest
60
+ * .setName("My App", "My Full App Name")
61
+ * .setDescription("Short desc", "Full description")
62
+ * .addBot("bot-id", ["personal", "team"])
63
+ * .addStaticTab("home", "Home", "https://example.com/tab")
64
+ * .addDeclarativeAgent("agent1", "declarativeAgent.json");
65
+ *
66
+ * // Save changes
67
+ * await manifest.save();
68
+ * ```
69
+ */
70
+ class TeamsManifestWrapper {
71
+ constructor(data, filePath) {
72
+ this._isDirty = false;
73
+ this._data = data;
74
+ this._filePath = filePath;
75
+ }
76
+ // ============= Base Manifest Properties =============
77
+ /**
78
+ * Returns the raw manifest data.
79
+ */
80
+ get data() {
81
+ return this._data;
82
+ }
83
+ /**
84
+ * Returns the file path if the manifest was loaded from a file.
85
+ */
86
+ get filePath() {
87
+ return this._filePath;
88
+ }
89
+ /**
90
+ * Indicates whether the manifest has unsaved changes.
91
+ */
92
+ get isDirty() {
93
+ return this._isDirty;
94
+ }
95
+ /**
96
+ * Marks the manifest as having unsaved changes.
97
+ */
98
+ markDirty() {
99
+ this._isDirty = true;
100
+ }
101
+ /**
102
+ * Saves the manifest to the specified file path or the original file path.
103
+ * @param filePath - Optional path to save to. If not provided, uses the original file path.
104
+ * @throws Error if no file path is available.
105
+ */
106
+ async save(filePath) {
107
+ const targetPath = filePath !== null && filePath !== void 0 ? filePath : this._filePath;
108
+ if (!targetPath) {
109
+ throw new Error("No file path specified for saving.");
110
+ }
111
+ await fs_extra_1.default.writeFile(targetPath, this.toJSON(), "utf-8");
112
+ this._filePath = targetPath;
113
+ this._isDirty = false;
114
+ }
115
+ // ============= Static Factory Methods =============
116
+ /**
117
+ * Reads a JSON file synchronously and returns the parsed object.
118
+ * @param filePath - Path to the JSON file
119
+ */
120
+ static readJsonFileSync(filePath) {
121
+ const content = fs_extra_1.default.readFileSync(filePath, "utf-8");
122
+ // Strip BOM to handle UTF-8 BOM encoded files
123
+ const cleanContent = (0, strip_bom_1.default)(content);
124
+ return JSON.parse(cleanContent);
125
+ }
126
+ /**
127
+ * Reads a Teams manifest from a file.
128
+ * @param filePath - Path to the manifest JSON file.
129
+ * @returns A new TeamsManifestWrapper instance.
130
+ */
131
+ static async read(filePath) {
132
+ const data = await generated_types_1.AppManifestUtils.readTeamsManifest(filePath);
133
+ return new TeamsManifestWrapper(data, filePath);
134
+ }
135
+ /**
136
+ * Reads a Teams manifest from a file synchronously.
137
+ * @param filePath - Path to the manifest JSON file.
138
+ * @returns A new TeamsManifestWrapper instance.
139
+ */
140
+ static readSync(filePath) {
141
+ const json = TeamsManifestWrapper.readJsonFileSync(filePath);
142
+ const data = generated_types_1.TeamsManifestConverter.jsonToManifest(JSON.stringify(json));
143
+ return new TeamsManifestWrapper(data, filePath);
144
+ }
145
+ /**
146
+ * Creates a TeamsManifestWrapper from a JSON string.
147
+ * @param json - JSON string representing the manifest.
148
+ * @returns A new TeamsManifestWrapper instance.
149
+ */
150
+ static fromJSON(json) {
151
+ const data = generated_types_1.TeamsManifestConverter.jsonToManifest(json);
152
+ return new TeamsManifestWrapper(data);
153
+ }
154
+ /**
155
+ * Creates a new Teams manifest with required fields.
156
+ * @param init - Initial manifest data with required fields.
157
+ * @returns A new TeamsManifestWrapper instance.
158
+ */
159
+ static create(init) {
160
+ var _a;
161
+ const data = {
162
+ $schema: `https://developer.microsoft.com/en-us/json-schemas/teams/v${init.manifestVersion}/MicrosoftTeams.schema.json`,
163
+ manifestVersion: init.manifestVersion,
164
+ id: init.id,
165
+ version: init.version,
166
+ name: init.name,
167
+ description: init.description,
168
+ developer: init.developer,
169
+ icons: { color: "color.png", outline: "outline.png" },
170
+ accentColor: (_a = init.accentColor) !== null && _a !== void 0 ? _a : "#FFFFFF",
171
+ };
172
+ return new TeamsManifestWrapper(data);
173
+ }
174
+ // ============= Getters =============
175
+ /**
176
+ * Returns the manifest version.
177
+ */
178
+ get manifestVersion() {
179
+ return this._data.manifestVersion;
180
+ }
181
+ /**
182
+ * Returns the app ID.
183
+ */
184
+ get id() {
185
+ return this._data.id;
186
+ }
187
+ /**
188
+ * Returns the app version.
189
+ */
190
+ get version() {
191
+ return this._data.version;
192
+ }
193
+ /**
194
+ * Returns the app name.
195
+ */
196
+ get name() {
197
+ return this._data.name;
198
+ }
199
+ /**
200
+ * Returns the app description.
201
+ */
202
+ get description() {
203
+ return this._data.description;
204
+ }
205
+ /**
206
+ * Returns the developer information.
207
+ */
208
+ get developer() {
209
+ return this._data.developer;
210
+ }
211
+ /**
212
+ * Returns the icons configuration.
213
+ */
214
+ get icons() {
215
+ return this._data.icons;
216
+ }
217
+ /**
218
+ * Returns a readonly array of bots.
219
+ */
220
+ get bots() {
221
+ var _a;
222
+ return (_a = this._data.bots) !== null && _a !== void 0 ? _a : [];
223
+ }
224
+ /**
225
+ * Returns a readonly array of static tabs.
226
+ */
227
+ get staticTabs() {
228
+ var _a;
229
+ return (_a = this._data.staticTabs) !== null && _a !== void 0 ? _a : [];
230
+ }
231
+ /**
232
+ * Returns a readonly array of configurable tabs.
233
+ */
234
+ get configurableTabs() {
235
+ var _a;
236
+ return (_a = this._data.configurableTabs) !== null && _a !== void 0 ? _a : [];
237
+ }
238
+ /**
239
+ * Returns a readonly array of compose extensions (message extensions).
240
+ */
241
+ get composeExtensions() {
242
+ var _a;
243
+ return (_a = this._data.composeExtensions) !== null && _a !== void 0 ? _a : [];
244
+ }
245
+ /**
246
+ * Returns a readonly array of connectors.
247
+ */
248
+ get connectors() {
249
+ var _a;
250
+ return (_a = this._data.connectors) !== null && _a !== void 0 ? _a : [];
251
+ }
252
+ /**
253
+ * Returns the valid domains.
254
+ */
255
+ get validDomains() {
256
+ var _a;
257
+ return (_a = this._data.validDomains) !== null && _a !== void 0 ? _a : [];
258
+ }
259
+ /**
260
+ * Returns the web application info for SSO.
261
+ */
262
+ get webApplicationInfo() {
263
+ return this._data.webApplicationInfo;
264
+ }
265
+ /**
266
+ * Returns the copilot agents configuration.
267
+ */
268
+ get copilotAgents() {
269
+ return this._data.copilotAgents;
270
+ }
271
+ /**
272
+ * Returns a readonly array of declarative agents.
273
+ */
274
+ get declarativeAgents() {
275
+ var _a, _b;
276
+ return (_b = (_a = this._data.copilotAgents) === null || _a === void 0 ? void 0 : _a.declarativeAgents) !== null && _b !== void 0 ? _b : [];
277
+ }
278
+ /**
279
+ * Returns a readonly array of custom engine agents.
280
+ */
281
+ get customEngineAgents() {
282
+ var _a, _b;
283
+ return (_b = (_a = this._data.copilotAgents) === null || _a === void 0 ? void 0 : _a.customEngineAgents) !== null && _b !== void 0 ? _b : [];
284
+ }
285
+ // ============= Setters (Fluent API) =============
286
+ /**
287
+ * Sets the app ID.
288
+ */
289
+ setId(id) {
290
+ this._data.id = id;
291
+ this.markDirty();
292
+ return this;
293
+ }
294
+ /**
295
+ * Sets the app version.
296
+ */
297
+ setVersion(version) {
298
+ this._data.version = version;
299
+ this.markDirty();
300
+ return this;
301
+ }
302
+ /**
303
+ * Sets the app name.
304
+ */
305
+ setName(short, full) {
306
+ this._data.name = { short, full };
307
+ this.markDirty();
308
+ return this;
309
+ }
310
+ /**
311
+ * Sets the app description.
312
+ */
313
+ setDescription(short, full) {
314
+ this._data.description = { short, full };
315
+ this.markDirty();
316
+ return this;
317
+ }
318
+ /**
319
+ * Sets the developer information.
320
+ */
321
+ setDeveloper(developer) {
322
+ this._data.developer = developer;
323
+ this.markDirty();
324
+ return this;
325
+ }
326
+ /**
327
+ * Sets the icons.
328
+ */
329
+ setIcons(color, outline) {
330
+ this._data.icons = { color, outline };
331
+ this.markDirty();
332
+ return this;
333
+ }
334
+ /**
335
+ * Sets the accent color.
336
+ */
337
+ setAccentColor(color) {
338
+ this._data.accentColor = color;
339
+ this.markDirty();
340
+ return this;
341
+ }
342
+ /**
343
+ * Sets the default install scope.
344
+ */
345
+ setDefaultInstallScope(scope) {
346
+ this._data.defaultInstallScope = scope;
347
+ this.markDirty();
348
+ return this;
349
+ }
350
+ // ============= Valid Domains Operations =============
351
+ /**
352
+ * Adds a valid domain.
353
+ * @param domain - The domain to add.
354
+ */
355
+ addValidDomain(domain) {
356
+ if (!this._data.validDomains) {
357
+ this._data.validDomains = [];
358
+ }
359
+ if (!this._data.validDomains.includes(domain)) {
360
+ this._data.validDomains.push(domain);
361
+ this.markDirty();
362
+ }
363
+ return this;
364
+ }
365
+ /**
366
+ * Removes a valid domain.
367
+ * @param domain - The domain to remove.
368
+ */
369
+ removeValidDomain(domain) {
370
+ if (this._data.validDomains) {
371
+ this._data.validDomains = this._data.validDomains.filter((d) => d !== domain);
372
+ this.markDirty();
373
+ }
374
+ return this;
375
+ }
376
+ // ============= Bot Operations =============
377
+ /**
378
+ * Adds a bot to the manifest.
379
+ * @param botId - The Microsoft App ID for the bot.
380
+ * @param scopes - The scopes for the bot.
381
+ * @param options - Additional bot configuration options.
382
+ */
383
+ addBot(botId, scopes, options) {
384
+ if (!this._data.bots) {
385
+ this._data.bots = [];
386
+ }
387
+ const existing = this._data.bots.find((b) => b.botId === botId);
388
+ if (!existing) {
389
+ this._data.bots.push(Object.assign({ botId,
390
+ scopes }, options));
391
+ this.markDirty();
392
+ }
393
+ return this;
394
+ }
395
+ /**
396
+ * Removes a bot by ID.
397
+ * @param botId - The bot ID to remove.
398
+ */
399
+ removeBot(botId) {
400
+ if (this._data.bots) {
401
+ this._data.bots = this._data.bots.filter((b) => b.botId !== botId);
402
+ this.markDirty();
403
+ }
404
+ return this;
405
+ }
406
+ /**
407
+ * Checks if a bot exists by ID.
408
+ */
409
+ hasBot(botId) {
410
+ return this.bots.some((b) => b.botId === botId);
411
+ }
412
+ /**
413
+ * Gets a bot by ID.
414
+ */
415
+ getBot(botId) {
416
+ return this.bots.find((b) => b.botId === botId);
417
+ }
418
+ // ============= Static Tab Operations =============
419
+ /**
420
+ * Adds a static tab to the manifest.
421
+ * @param entityId - Unique identifier for the tab entity.
422
+ * @param name - Display name of the tab.
423
+ * @param contentUrl - URL for the tab content.
424
+ * @param scopes - The scopes for the tab.
425
+ */
426
+ addStaticTab(entityId, name, contentUrl, scopes = ["personal"]) {
427
+ if (!this._data.staticTabs) {
428
+ this._data.staticTabs = [];
429
+ }
430
+ const existing = this._data.staticTabs.find((t) => t.entityId === entityId);
431
+ if (!existing) {
432
+ this._data.staticTabs.push({
433
+ entityId,
434
+ name,
435
+ contentUrl,
436
+ scopes,
437
+ });
438
+ this.markDirty();
439
+ }
440
+ return this;
441
+ }
442
+ /**
443
+ * Removes a static tab by entity ID.
444
+ * @param entityId - The entity ID of the tab to remove.
445
+ */
446
+ removeStaticTab(entityId) {
447
+ if (this._data.staticTabs) {
448
+ this._data.staticTabs = this._data.staticTabs.filter((t) => t.entityId !== entityId);
449
+ this.markDirty();
450
+ }
451
+ return this;
452
+ }
453
+ /**
454
+ * Checks if a static tab exists by entity ID.
455
+ */
456
+ hasStaticTab(entityId) {
457
+ return this.staticTabs.some((t) => t.entityId === entityId);
458
+ }
459
+ /**
460
+ * Gets a static tab by entity ID.
461
+ */
462
+ getStaticTab(entityId) {
463
+ return this.staticTabs.find((t) => t.entityId === entityId);
464
+ }
465
+ // ============= Configurable Tab Operations =============
466
+ /**
467
+ * Adds a configurable tab to the manifest.
468
+ * @param configurationUrl - URL for the tab configuration.
469
+ * @param scopes - The scopes for the tab.
470
+ */
471
+ addConfigurableTab(configurationUrl, scopes = ["team", "groupChat"]) {
472
+ if (!this._data.configurableTabs) {
473
+ this._data.configurableTabs = [];
474
+ }
475
+ this._data.configurableTabs.push({
476
+ configurationUrl,
477
+ scopes,
478
+ });
479
+ this.markDirty();
480
+ return this;
481
+ }
482
+ /**
483
+ * Removes a configurable tab by configuration URL.
484
+ * @param configurationUrl - The configuration URL of the tab to remove.
485
+ */
486
+ removeConfigurableTab(configurationUrl) {
487
+ if (this._data.configurableTabs) {
488
+ this._data.configurableTabs = this._data.configurableTabs.filter((t) => t.configurationUrl !== configurationUrl);
489
+ this.markDirty();
490
+ }
491
+ return this;
492
+ }
493
+ // ============= Compose Extension (Message Extension) Operations =============
494
+ /**
495
+ * Adds a compose extension to the manifest.
496
+ * @param extension - The compose extension configuration.
497
+ */
498
+ addComposeExtension(extension) {
499
+ if (!this._data.composeExtensions) {
500
+ this._data.composeExtensions = [];
501
+ }
502
+ this._data.composeExtensions.push(extension);
503
+ this.markDirty();
504
+ return this;
505
+ }
506
+ /**
507
+ * Adds a bot-based compose extension.
508
+ * @param botId - The bot ID for the message extension.
509
+ * @param commands - The commands for the message extension.
510
+ */
511
+ addBotBasedComposeExtension(botId, commands = []) {
512
+ return this.addComposeExtension({
513
+ botId,
514
+ composeExtensionType: "botBased",
515
+ commands,
516
+ });
517
+ }
518
+ /**
519
+ * Adds an API-based compose extension.
520
+ * @param apiSpecificationFile - Path to the API specification file.
521
+ * @param commands - The commands for the message extension.
522
+ */
523
+ addApiBasedComposeExtension(apiSpecificationFile, commands = []) {
524
+ return this.addComposeExtension({
525
+ composeExtensionType: "apiBased",
526
+ apiSpecificationFile,
527
+ commands,
528
+ });
529
+ }
530
+ /**
531
+ * Removes a compose extension by bot ID.
532
+ * @param botId - The bot ID of the compose extension to remove.
533
+ */
534
+ removeComposeExtensionByBotId(botId) {
535
+ if (this._data.composeExtensions) {
536
+ this._data.composeExtensions = this._data.composeExtensions.filter((ce) => ce.botId !== botId);
537
+ this.markDirty();
538
+ }
539
+ return this;
540
+ }
541
+ // ============= Web Application Info (SSO) Operations =============
542
+ /**
543
+ * Sets the web application info for SSO.
544
+ * @param id - The AAD application ID.
545
+ * @param resource - Optional resource URL for acquiring auth token.
546
+ */
547
+ setWebApplicationInfo(id, resource) {
548
+ this._data.webApplicationInfo = { id, resource };
549
+ this.markDirty();
550
+ return this;
551
+ }
552
+ /**
553
+ * Removes the web application info.
554
+ */
555
+ removeWebApplicationInfo() {
556
+ delete this._data.webApplicationInfo;
557
+ this.markDirty();
558
+ return this;
559
+ }
560
+ // ============= Copilot Agents Operations =============
561
+ /**
562
+ * Adds a declarative agent reference.
563
+ * @param id - Unique identifier for the agent.
564
+ * @param file - Relative path to the agent manifest file.
565
+ */
566
+ addDeclarativeAgent(id, file) {
567
+ const data = this._data;
568
+ if (!data.copilotAgents) {
569
+ data.copilotAgents = {};
570
+ }
571
+ if (!data.copilotAgents.declarativeAgents) {
572
+ data.copilotAgents.declarativeAgents = [];
573
+ }
574
+ const existing = data.copilotAgents.declarativeAgents.find((a) => a.id === id);
575
+ if (!existing) {
576
+ data.copilotAgents.declarativeAgents.push({ id, file });
577
+ this.markDirty();
578
+ }
579
+ return this;
580
+ }
581
+ /**
582
+ * Removes a declarative agent by ID.
583
+ * @param id - The ID of the agent to remove.
584
+ */
585
+ removeDeclarativeAgent(id) {
586
+ var _a;
587
+ const data = this._data;
588
+ if ((_a = data.copilotAgents) === null || _a === void 0 ? void 0 : _a.declarativeAgents) {
589
+ data.copilotAgents.declarativeAgents = data.copilotAgents.declarativeAgents.filter((a) => a.id !== id);
590
+ this.markDirty();
591
+ }
592
+ return this;
593
+ }
594
+ /**
595
+ * Checks if a declarative agent exists by ID.
596
+ */
597
+ hasDeclarativeAgent(id) {
598
+ return this.declarativeAgents.some((a) => a.id === id);
599
+ }
600
+ /**
601
+ * Gets a declarative agent by ID.
602
+ */
603
+ getDeclarativeAgent(id) {
604
+ return this.declarativeAgents.find((a) => a.id === id);
605
+ }
606
+ /**
607
+ * Adds a custom engine agent.
608
+ * @param id - The bot ID for the custom engine agent.
609
+ */
610
+ addCustomEngineAgent(id) {
611
+ const data = this._data;
612
+ if (!data.copilotAgents) {
613
+ data.copilotAgents = {};
614
+ }
615
+ if (!data.copilotAgents.customEngineAgents) {
616
+ data.copilotAgents.customEngineAgents = [];
617
+ }
618
+ const existing = data.copilotAgents.customEngineAgents.find((a) => a.id === id);
619
+ if (!existing) {
620
+ data.copilotAgents.customEngineAgents.push({ id, type: "bot" });
621
+ this.markDirty();
622
+ }
623
+ return this;
624
+ }
625
+ /**
626
+ * Removes a custom engine agent by ID.
627
+ * @param id - The ID of the agent to remove.
628
+ */
629
+ removeCustomEngineAgent(id) {
630
+ var _a;
631
+ const data = this._data;
632
+ if ((_a = data.copilotAgents) === null || _a === void 0 ? void 0 : _a.customEngineAgents) {
633
+ data.copilotAgents.customEngineAgents = data.copilotAgents.customEngineAgents.filter((a) => a.id !== id);
634
+ this.markDirty();
635
+ }
636
+ return this;
637
+ }
638
+ // ============= Query Operations =============
639
+ /**
640
+ * Returns all bot IDs from the manifest.
641
+ */
642
+ getBotIds() {
643
+ return this.bots.map((b) => b.botId);
644
+ }
645
+ /**
646
+ * Returns all static tab entity IDs.
647
+ */
648
+ getStaticTabEntityIds() {
649
+ return this.staticTabs.map((t) => t.entityId);
650
+ }
651
+ /**
652
+ * Returns all declarative agent file paths.
653
+ */
654
+ getDeclarativeAgentPaths() {
655
+ return this.declarativeAgents.map((a) => a.file);
656
+ }
657
+ /**
658
+ * Checks if the manifest has any Copilot agent configuration.
659
+ */
660
+ hasCopilotAgents() {
661
+ return this.declarativeAgents.length > 0 || this.customEngineAgents.length > 0;
662
+ }
663
+ // ============= Validation =============
664
+ /**
665
+ * Validates the manifest against its JSON schema.
666
+ * @returns Array of validation error messages, empty if valid.
667
+ */
668
+ async validate() {
669
+ return generated_types_1.AppManifestUtils.validateAgainstSchema(this._data);
670
+ }
671
+ // ============= Serialization =============
672
+ /**
673
+ * Converts the manifest to a formatted JSON string.
674
+ */
675
+ toJSON() {
676
+ return generated_types_1.TeamsManifestConverter.manifestToJson(this._data);
677
+ }
678
+ /**
679
+ * Creates a deep clone of this manifest.
680
+ */
681
+ clone() {
682
+ const clonedData = JSON.parse(this.toJSON());
683
+ return new TeamsManifestWrapper(clonedData);
684
+ }
685
+ /**
686
+ * Creates a deep clone with partial modifications applied.
687
+ * Useful for creating a modified copy without mutating the original.
688
+ * @param changes - Partial manifest data to merge into the clone.
689
+ * @returns A new TeamsManifestWrapper with the changes applied.
690
+ */
691
+ cloneWith(changes) {
692
+ const clonedData = JSON.parse(this.toJSON());
693
+ Object.assign(clonedData, changes);
694
+ const wrapper = new TeamsManifestWrapper(clonedData);
695
+ wrapper.markDirty();
696
+ return wrapper;
697
+ }
698
+ /**
699
+ * Returns a mutable reference to the manifest data for direct modification.
700
+ * Use with caution - prefer using the fluent API methods when possible.
701
+ * Changes made through this reference will be tracked as dirty.
702
+ */
703
+ get mutableData() {
704
+ this.markDirty();
705
+ return this._data;
706
+ }
707
+ }
708
+ exports.TeamsManifestWrapper = TeamsManifestWrapper;
709
+ //# sourceMappingURL=TeamsManifestWrapper.js.map