@microsoft/sp-module-interfaces 1.22.1 → 1.23.0-beta.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 (59) hide show
  1. package/dist/index-internal-beta.d.ts +20 -2
  2. package/dist/index-internal-public.d.ts +20 -2
  3. package/dist/index-internal.d.ts +728 -16
  4. package/lib-commonjs/manifestSchemaValidator.js +125 -25
  5. package/lib-commonjs/manifestSchemas/examples/commandSet_2.manifest.js +59 -0
  6. package/lib-commonjs/manifestSchemas/examples/commandSet_3.manifest.js +66 -0
  7. package/lib-commonjs/manifestSchemas/examples/commandSet_4.manifest.js +73 -0
  8. package/lib-commonjs/manifestSchemas/examples/commandSet_5.manifest.js +51 -0
  9. package/lib-commonjs/manifestSchemas/jsonSchemas/adaptive-card-extension-manifest.schema.json +1 -1
  10. package/lib-commonjs/manifestSchemas/jsonSchemas/any-value.schema.json +1 -1
  11. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-application-manifest.schema.json +1 -1
  12. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-assembly-manifest.schema.json +1 -1
  13. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-component-loader-configuration.schema.json +1 -2
  14. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-component-manifest.schema.json +1 -1
  15. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-extension-manifest.schema.json +1 -1
  16. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-library-manifest.schema.json +1 -1
  17. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-manifest-base.schema.json +1 -1
  18. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-multi-version-manifest.schema.json +1 -1
  19. package/lib-commonjs/manifestSchemas/jsonSchemas/client-side-web-part-manifest.schema.json +1 -1
  20. package/lib-commonjs/manifestSchemas/jsonSchemas/command-set-extension-manifest.schema.json +9 -3
  21. package/lib-commonjs/manifestSchemas/jsonSchemas/component-fallback-version.schema.json +1 -1
  22. package/lib-commonjs/manifestSchemas/jsonSchemas/guid.schema.json +1 -1
  23. package/lib-commonjs/manifestSchemas/jsonSchemas/localized-string.schema.json +1 -1
  24. package/lib-commonjs/manifestSchemas/jsonSchemas/prefab-app-manifest.schema.json +2 -2
  25. package/lib-commonjs/manifestSchemas/jsonSchemas/semver.schema.json +1 -1
  26. package/lib-commonjs/manifestSchemas/remote/site-design-script-actions.schema.json +4 -6
  27. package/lib-dts/manifestSchemaValidator.d.ts +16 -4
  28. package/lib-dts/manifestSchemas/ICommandSetExtensionManifest.d.ts +20 -2
  29. package/lib-dts/manifestSchemas/examples/commandSet_2.manifest.d.ts +8 -0
  30. package/lib-dts/manifestSchemas/examples/commandSet_3.manifest.d.ts +8 -0
  31. package/lib-dts/manifestSchemas/examples/commandSet_4.manifest.d.ts +8 -0
  32. package/lib-dts/manifestSchemas/examples/commandSet_5.manifest.d.ts +8 -0
  33. package/lib-dts/tsdoc-metadata.json +1 -1
  34. package/lib-esm/manifestSchemaValidator.js +126 -27
  35. package/lib-esm/manifestSchemas/examples/commandSet_2.manifest.js +49 -0
  36. package/lib-esm/manifestSchemas/examples/commandSet_3.manifest.js +56 -0
  37. package/lib-esm/manifestSchemas/examples/commandSet_4.manifest.js +63 -0
  38. package/lib-esm/manifestSchemas/examples/commandSet_5.manifest.js +41 -0
  39. package/lib-esm/manifestSchemas/jsonSchemas/adaptive-card-extension-manifest.schema.json +1 -1
  40. package/lib-esm/manifestSchemas/jsonSchemas/any-value.schema.json +1 -1
  41. package/lib-esm/manifestSchemas/jsonSchemas/client-side-application-manifest.schema.json +1 -1
  42. package/lib-esm/manifestSchemas/jsonSchemas/client-side-assembly-manifest.schema.json +1 -1
  43. package/lib-esm/manifestSchemas/jsonSchemas/client-side-component-loader-configuration.schema.json +1 -2
  44. package/lib-esm/manifestSchemas/jsonSchemas/client-side-component-manifest.schema.json +1 -1
  45. package/lib-esm/manifestSchemas/jsonSchemas/client-side-extension-manifest.schema.json +1 -1
  46. package/lib-esm/manifestSchemas/jsonSchemas/client-side-library-manifest.schema.json +1 -1
  47. package/lib-esm/manifestSchemas/jsonSchemas/client-side-manifest-base.schema.json +1 -1
  48. package/lib-esm/manifestSchemas/jsonSchemas/client-side-multi-version-manifest.schema.json +1 -1
  49. package/lib-esm/manifestSchemas/jsonSchemas/client-side-web-part-manifest.schema.json +1 -1
  50. package/lib-esm/manifestSchemas/jsonSchemas/command-set-extension-manifest.schema.json +9 -3
  51. package/lib-esm/manifestSchemas/jsonSchemas/component-fallback-version.schema.json +1 -1
  52. package/lib-esm/manifestSchemas/jsonSchemas/guid.schema.json +1 -1
  53. package/lib-esm/manifestSchemas/jsonSchemas/localized-string.schema.json +1 -1
  54. package/lib-esm/manifestSchemas/jsonSchemas/prefab-app-manifest.schema.json +2 -2
  55. package/lib-esm/manifestSchemas/jsonSchemas/semver.schema.json +1 -1
  56. package/lib-esm/manifestSchemas/remote/site-design-script-actions.schema.json +4 -6
  57. package/package.json +12 -14
  58. package/lib-commonjs/manifestSchemas/remote/draft-04.schema.json +0 -137
  59. package/lib-esm/manifestSchemas/remote/draft-04.schema.json +0 -137
@@ -1,4 +1,4 @@
1
- import Ajv from 'ajv';
1
+ import type { ErrorObject } from 'ajv';
2
2
  import type { IClientSideApplicationManifest } from './manifestSchemas/IClientSideApplicationManifest';
3
3
  import type { IClientSideAssemblyManifest } from './manifestSchemas/IClientSideAssemblyManifest';
4
4
  import type { IClientSideComponentManifest } from './manifestSchemas/IClientSideComponentManifest';
@@ -10,7 +10,7 @@ import type { ICommandSetExtensionManifest } from './manifestSchemas/ICommandSet
10
10
  import type { IPrefabAppManifest } from './manifestSchemas/IPrefabAppManifest';
11
11
  export interface IManifestValidatorResult {
12
12
  result: boolean;
13
- errors: Ajv.ErrorObject[];
13
+ errors: ErrorObject[];
14
14
  }
15
15
  export default class ManifestValidator {
16
16
  static registerRemoteSchemaReferences(): Promise<void>;
@@ -23,8 +23,20 @@ export default class ManifestValidator {
23
23
  static validateAssemblyManifest(manifest: string | IClientSideAssemblyManifest): IManifestValidatorResult;
24
24
  static validateMultiVersionManifest(manifest: string | IClientSideMultiVersionManifest<any>): IManifestValidatorResult;
25
25
  static validateManifest(manifest: string | IClientSideComponentManifest): IManifestValidatorResult;
26
- static extractInnerErrorMessages(errors: Ajv.ErrorObject[]): string[];
27
- static getFormattedErrorMessage(errors: Ajv.ErrorObject[]): string;
26
+ static extractInnerErrorMessages(errors: ErrorObject[]): string[];
27
+ static getFormattedErrorMessage(errors: ErrorObject[]): string;
28
28
  private static _validateManifest;
29
+ /**
30
+ * Validates command set hierarchy rules that cannot be expressed in JSON Schema:
31
+ * - Group references must point to existing items with type 'group'
32
+ * - Maximum nesting depth is 2 levels
33
+ * - No circular references in group hierarchy
34
+ */
35
+ private static _validateCommandSetHierarchy;
36
+ /**
37
+ * Calculates the depth of an item in the group hierarchy.
38
+ * Returns Infinity if a circular reference is detected.
39
+ */
40
+ private static _getGroupDepth;
29
41
  }
30
42
  //# sourceMappingURL=manifestSchemaValidator.d.ts.map
@@ -49,9 +49,10 @@ export interface ICommandDefinition {
49
49
  title: ILocalizedString;
50
50
  /**
51
51
  * Type of the item.
52
- * Currently only "command" is allowed.
52
+ * - 'command': A standard executable command
53
+ * - 'group': A group that contains child commands (renders as submenu)
53
54
  */
54
- type: 'command';
55
+ type: 'command' | 'group';
55
56
  /**
56
57
  * Custom accessibility text for the browser's "aria-label" attribute. If omitted, the title property
57
58
  * will be used by default.
@@ -68,7 +69,24 @@ export interface ICommandDefinition {
68
69
  * the folder containing the input manifest. The icon file will be copied to the deployment folder like an asset,
69
70
  * and the output manifest's iconImageUrl will be replaced with a URL relative to the URL used to load all other
70
71
  * assets (the loaderConfig.internalModuleBaseUrls property).
72
+ *
73
+ * For groups, this icon is displayed on the parent button.
71
74
  */
72
75
  iconImageUrl?: string;
76
+ /**
77
+ * Optional ID of the parent group this command/group belongs to.
78
+ * Used to build hierarchical command structures where commands appear in submenus.
79
+ *
80
+ * @remarks
81
+ * - Must reference a valid group item ID defined in the same manifest
82
+ * - Both commands and groups can have a group property (for nested groups)
83
+ * - Maximum nesting depth is 2 levels, where a top-level group can contain one additional nested group
84
+ * - Child commands are displayed in manifest definition order within their group
85
+ * - If the parent group ID is not found, the command appears at top level
86
+ * - Groups are automatically hidden if all their children are invisible
87
+ *
88
+ * Example: "EXPORT_GROUP" (where EXPORT_GROUP is defined as type: 'group')
89
+ */
90
+ group?: string;
73
91
  }
74
92
  //# sourceMappingURL=ICommandSetExtensionManifest.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { ICommandSetExtensionManifest } from '../ICommandSetExtensionManifest';
2
+ /**
3
+ * Example manifest with single-level groups.
4
+ * Commands are organized under a parent group.
5
+ */
6
+ declare const extensionManifest: ICommandSetExtensionManifest;
7
+ export default extensionManifest;
8
+ //# sourceMappingURL=commandSet_2.manifest.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { ICommandSetExtensionManifest } from '../ICommandSetExtensionManifest';
2
+ /**
3
+ * Example manifest with nested groups (2 levels).
4
+ * Demonstrates a parent group containing a child group with commands.
5
+ */
6
+ declare const extensionManifest: ICommandSetExtensionManifest;
7
+ export default extensionManifest;
8
+ //# sourceMappingURL=commandSet_3.manifest.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { ICommandSetExtensionManifest } from '../ICommandSetExtensionManifest';
2
+ /**
3
+ * Example manifest with mixed structure.
4
+ * Demonstrates top-level commands alongside grouped commands.
5
+ */
6
+ declare const extensionManifest: ICommandSetExtensionManifest;
7
+ export default extensionManifest;
8
+ //# sourceMappingURL=commandSet_4.manifest.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { ICommandSetExtensionManifest } from '../ICommandSetExtensionManifest';
2
+ /**
3
+ * Example manifest with an empty group (no children).
4
+ * Empty groups are valid at schema level - they simply won't render at runtime.
5
+ */
6
+ declare const extensionManifest: ICommandSetExtensionManifest;
7
+ export default extensionManifest;
8
+ //# sourceMappingURL=commandSet_5.manifest.d.ts.map
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.52.5"
8
+ "packageVersion": "7.57.7"
9
9
  }
10
10
  ]
11
11
  }
@@ -12,36 +12,22 @@ import multiVersionSchema from './manifestSchemas/jsonSchemas/client-side-multi-
12
12
  // local copy of site scripts schema
13
13
  import siteScriptsSchema from './manifestSchemas/remote/site-design-script-actions.schema.json';
14
14
  // Discover the schema files
15
+ // use internal site-design-script-actions schema for validation instead of remote URL
16
+ // as this schema is only used for Prefab, which is currently only internal. When we enable Prefab
17
+ // for external use, we can switch back to the remote URL with appropriate changes.
15
18
  const schemasDirectory = `${__dirname}/manifestSchemas/jsonSchemas`;
16
19
  const schemaFiles = FileSystem.readFolderItemNames(schemasDirectory);
17
20
  const schemas = schemaFiles.map((schemaFile)=>require(`${schemasDirectory}/${schemaFile}`));
18
- const SITE_SCRIPTS_SCHEMA_URL = 'https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json';
19
- const siteScriptsSchemaPromise = fetch(SITE_SCRIPTS_SCHEMA_URL).then((response)=>{
20
- return response.text();
21
- }).catch((error)=>{
22
- // eslint-disable-next-line no-console
23
- console.error(`Failed to fetch remote schema: ${error}`);
24
- // fallback to local copy
25
- return JSON.stringify(siteScriptsSchema);
26
- });
27
21
  const schemaValidator = new Ajv();
28
- siteScriptsSchemaPromise.then((remoteSchema)=>{
29
- schemaValidator.addSchema(JSON.parse(remoteSchema), SITE_SCRIPTS_SCHEMA_URL);
30
- schemas.forEach((schema, index)=>{
31
- // Use the schema's id property as the key to avoid "schema id ignored" warnings
32
- const schemaId = schema.id || `schema-${index}`;
33
- schemaValidator.addSchema(schema, schemaId);
34
- });
35
- }).catch((error)=>{
36
- // swallowing the error here
22
+ schemaValidator.addSchema(siteScriptsSchema, siteScriptsSchema.$id);
23
+ schemas.forEach((schema, index)=>{
24
+ // Use the schema's $id property as the key
25
+ const schemaId = schema.$id || `schema-${index}`;
26
+ schemaValidator.addSchema(schema, schemaId);
37
27
  });
38
- class ManifestValidator {
28
+ export default class ManifestValidator {
39
29
  static registerRemoteSchemaReferences() {
40
- return siteScriptsSchemaPromise.then(()=>{
41
- // no-op;
42
- }).catch(()=>{
43
- // no-op;
44
- });
30
+ return Promise.resolve();
45
31
  }
46
32
  static validateApplicationManifest(manifest) {
47
33
  return ManifestValidator._validateManifest(manifest, applicationSchema);
@@ -50,7 +36,26 @@ class ManifestValidator {
50
36
  return ManifestValidator._validateManifest(manifest, prefabAppSchema);
51
37
  }
52
38
  static validateCommandSetManifest(manifest) {
53
- return ManifestValidator._validateManifest(manifest, commandSetSchema);
39
+ // First, run JSON Schema validation
40
+ const schemaValidationResult = ManifestValidator._validateManifest(manifest, commandSetSchema);
41
+ // If schema validation failed, return early
42
+ if (!schemaValidationResult.result) {
43
+ return schemaValidationResult;
44
+ }
45
+ // Parse manifest if it's a string
46
+ const manifestObject = typeof manifest === 'string' ? JSON.parse(manifest) : manifest;
47
+ // Perform custom validation for command set specific rules
48
+ const customErrors = ManifestValidator._validateCommandSetHierarchy(manifestObject);
49
+ if (customErrors.length > 0) {
50
+ return {
51
+ result: false,
52
+ errors: [
53
+ ...schemaValidationResult.errors,
54
+ ...customErrors
55
+ ]
56
+ };
57
+ }
58
+ return schemaValidationResult;
54
59
  }
55
60
  static validateExtensionManifest(manifest) {
56
61
  return ManifestValidator._validateManifest(manifest, extensionSchema);
@@ -76,7 +81,7 @@ class ManifestValidator {
76
81
  const printAjvError = (error)=>{
77
82
  // AJV errors don't have nested inner errors
78
83
  // Each error is flat and represents a single validation failure
79
- const path = error.dataPath || error.schemaPath || 'root';
84
+ const path = error.instancePath || error.schemaPath || 'root';
80
85
  const message = error.message || 'Validation error';
81
86
  return [
82
87
  `(${path}) ${message}`
@@ -109,7 +114,101 @@ class ManifestValidator {
109
114
  errors: schemaValidator.errors || []
110
115
  };
111
116
  }
117
+ /**
118
+ * Validates command set hierarchy rules that cannot be expressed in JSON Schema:
119
+ * - Group references must point to existing items with type 'group'
120
+ * - Maximum nesting depth is 2 levels
121
+ * - No circular references in group hierarchy
122
+ */ static _validateCommandSetHierarchy(manifest) {
123
+ const errors = [];
124
+ const items = manifest.items;
125
+ if (!items) {
126
+ return errors;
127
+ }
128
+ const itemIds = Object.keys(items);
129
+ // Validate each item
130
+ for (const itemId of itemIds){
131
+ const item = items[itemId];
132
+ // Check if parent group exists and is a group
133
+ if (item.group) {
134
+ if (!items[item.group]) {
135
+ errors.push({
136
+ keyword: 'group-reference',
137
+ instancePath: `/items/${itemId}/group`,
138
+ schemaPath: '#/properties/items/patternProperties/group',
139
+ params: {
140
+ groupId: item.group
141
+ },
142
+ message: `Parent group '${item.group}' does not exist in manifest`
143
+ });
144
+ } else if (items[item.group].type !== 'group') {
145
+ errors.push({
146
+ keyword: 'group-type',
147
+ instancePath: `/items/${itemId}/group`,
148
+ schemaPath: '#/properties/items/patternProperties/group',
149
+ params: {
150
+ groupId: item.group
151
+ },
152
+ message: `Parent '${item.group}' is not a group (type must be 'group')`
153
+ });
154
+ }
155
+ }
156
+ // Check nesting depth and circular references for groups only
157
+ if (item.type === 'group') {
158
+ const visited = new Set();
159
+ const depth = ManifestValidator._getGroupDepth(itemId, items, visited);
160
+ if (depth === Infinity) {
161
+ errors.push({
162
+ keyword: 'circular-reference',
163
+ instancePath: `/items/${itemId}`,
164
+ schemaPath: '#/properties/items',
165
+ params: {
166
+ itemId
167
+ },
168
+ message: `Circular reference detected in group hierarchy for '${itemId}'`
169
+ });
170
+ } else if (depth > 2) {
171
+ errors.push({
172
+ keyword: 'max-depth',
173
+ instancePath: `/items/${itemId}`,
174
+ schemaPath: '#/properties/items',
175
+ params: {
176
+ depth,
177
+ itemId
178
+ },
179
+ message: `Group '${itemId}' has nesting depth ${depth}, which exceeds maximum of 2`
180
+ });
181
+ }
182
+ }
183
+ }
184
+ return errors;
185
+ }
186
+ /**
187
+ * Calculates the depth of an item in the group hierarchy.
188
+ * Returns Infinity if a circular reference is detected.
189
+ */ static _getGroupDepth(itemId, items, visited) {
190
+ // Circular reference detection
191
+ if (visited.has(itemId)) {
192
+ return Infinity;
193
+ }
194
+ const item = items[itemId];
195
+ if (!item) {
196
+ return 0;
197
+ }
198
+ // If no parent group, depth is 1
199
+ if (!item.group) {
200
+ return 1;
201
+ }
202
+ // If parent doesn't exist, treat as depth 1
203
+ if (!items[item.group]) {
204
+ return 1;
205
+ }
206
+ // Mark as visited before recursing
207
+ visited.add(itemId);
208
+ // Recursively calculate parent's depth and add 1
209
+ const parentDepth = ManifestValidator._getGroupDepth(item.group, items, visited);
210
+ return parentDepth + 1;
211
+ }
112
212
  }
113
- export { ManifestValidator as default };
114
213
 
115
214
  //# sourceMappingURL=./manifestSchemaValidator.js.map
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Example manifest with single-level groups.
3
+ * Commands are organized under a parent group.
4
+ */ const extensionManifest = {
5
+ manifestVersion: 2,
6
+ componentType: 'Extension',
7
+ id: '00000000-0000-0000-0000-000000000001',
8
+ alias: 'singleLevelGroupExtension',
9
+ version: '0.0.1',
10
+ extensionType: 'ListViewCommandSet',
11
+ items: {
12
+ EXPORT_GROUP: {
13
+ title: {
14
+ default: 'Export'
15
+ },
16
+ type: 'group',
17
+ iconImageUrl: 'icons/export.png'
18
+ },
19
+ EXPORT_PDF: {
20
+ title: {
21
+ default: 'Export to PDF'
22
+ },
23
+ type: 'command',
24
+ group: 'EXPORT_GROUP'
25
+ },
26
+ EXPORT_EXCEL: {
27
+ title: {
28
+ default: 'Export to Excel'
29
+ },
30
+ type: 'command',
31
+ group: 'EXPORT_GROUP'
32
+ }
33
+ },
34
+ loaderConfig: {
35
+ internalModuleBaseUrls: [
36
+ 'https://cdn.net/'
37
+ ],
38
+ entryModuleId: 'main.bundle',
39
+ scriptResources: {
40
+ 'main.bundle': {
41
+ type: 'path',
42
+ path: 'bundle.script.js'
43
+ }
44
+ }
45
+ }
46
+ };
47
+ export default extensionManifest;
48
+
49
+ //# sourceMappingURL=./commandSet_2.manifest.js.map
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Example manifest with nested groups (2 levels).
3
+ * Demonstrates a parent group containing a child group with commands.
4
+ */ const extensionManifest = {
5
+ manifestVersion: 2,
6
+ componentType: 'Extension',
7
+ id: '00000000-0000-0000-0000-000000000002',
8
+ alias: 'nestedGroupExtension',
9
+ version: '0.0.1',
10
+ extensionType: 'ListViewCommandSet',
11
+ items: {
12
+ TOOLS_GROUP: {
13
+ title: {
14
+ default: 'Tools'
15
+ },
16
+ type: 'group',
17
+ iconImageUrl: 'icons/tools.png'
18
+ },
19
+ ANALYSIS_GROUP: {
20
+ title: {
21
+ default: 'Analysis'
22
+ },
23
+ type: 'group',
24
+ group: 'TOOLS_GROUP'
25
+ },
26
+ RUN_ANALYSIS: {
27
+ title: {
28
+ default: 'Run Analysis'
29
+ },
30
+ type: 'command',
31
+ group: 'ANALYSIS_GROUP'
32
+ },
33
+ VIEW_REPORT: {
34
+ title: {
35
+ default: 'View Report'
36
+ },
37
+ type: 'command',
38
+ group: 'ANALYSIS_GROUP'
39
+ }
40
+ },
41
+ loaderConfig: {
42
+ internalModuleBaseUrls: [
43
+ 'https://cdn.net/'
44
+ ],
45
+ entryModuleId: 'main.bundle',
46
+ scriptResources: {
47
+ 'main.bundle': {
48
+ type: 'path',
49
+ path: 'bundle.script.js'
50
+ }
51
+ }
52
+ }
53
+ };
54
+ export default extensionManifest;
55
+
56
+ //# sourceMappingURL=./commandSet_3.manifest.js.map
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Example manifest with mixed structure.
3
+ * Demonstrates top-level commands alongside grouped commands.
4
+ */ const extensionManifest = {
5
+ manifestVersion: 2,
6
+ componentType: 'Extension',
7
+ id: '00000000-0000-0000-0000-000000000003',
8
+ alias: 'mixedStructureExtension',
9
+ version: '0.0.1',
10
+ extensionType: 'ListViewCommandSet',
11
+ items: {
12
+ QUICK_VIEW: {
13
+ title: {
14
+ default: 'Quick View'
15
+ },
16
+ type: 'command',
17
+ iconImageUrl: 'icons/quickview.png'
18
+ },
19
+ SHARE_GROUP: {
20
+ title: {
21
+ default: 'Share'
22
+ },
23
+ type: 'group',
24
+ iconImageUrl: 'icons/share.png'
25
+ },
26
+ SHARE_EMAIL: {
27
+ title: {
28
+ default: 'Share via Email'
29
+ },
30
+ type: 'command',
31
+ group: 'SHARE_GROUP'
32
+ },
33
+ SHARE_LINK: {
34
+ title: {
35
+ default: 'Copy Link'
36
+ },
37
+ type: 'command',
38
+ group: 'SHARE_GROUP'
39
+ },
40
+ SETTINGS: {
41
+ title: {
42
+ default: 'Settings'
43
+ },
44
+ type: 'command',
45
+ iconImageUrl: 'icons/settings.png'
46
+ }
47
+ },
48
+ loaderConfig: {
49
+ internalModuleBaseUrls: [
50
+ 'https://cdn.net/'
51
+ ],
52
+ entryModuleId: 'main.bundle',
53
+ scriptResources: {
54
+ 'main.bundle': {
55
+ type: 'path',
56
+ path: 'bundle.script.js'
57
+ }
58
+ }
59
+ }
60
+ };
61
+ export default extensionManifest;
62
+
63
+ //# sourceMappingURL=./commandSet_4.manifest.js.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Example manifest with an empty group (no children).
3
+ * Empty groups are valid at schema level - they simply won't render at runtime.
4
+ */ const extensionManifest = {
5
+ manifestVersion: 2,
6
+ componentType: 'Extension',
7
+ id: '00000000-0000-0000-0000-000000000004',
8
+ alias: 'emptyGroupExtension',
9
+ version: '0.0.1',
10
+ extensionType: 'ListViewCommandSet',
11
+ items: {
12
+ EMPTY_GROUP: {
13
+ title: {
14
+ default: 'Empty Group'
15
+ },
16
+ type: 'group'
17
+ },
18
+ STANDALONE_COMMAND: {
19
+ title: {
20
+ default: 'Standalone Command'
21
+ },
22
+ type: 'command',
23
+ iconImageUrl: 'icons/standalone.png'
24
+ }
25
+ },
26
+ loaderConfig: {
27
+ internalModuleBaseUrls: [
28
+ 'https://cdn.net/'
29
+ ],
30
+ entryModuleId: 'main.bundle',
31
+ scriptResources: {
32
+ 'main.bundle': {
33
+ type: 'path',
34
+ path: 'bundle.script.js'
35
+ }
36
+ }
37
+ }
38
+ };
39
+ export default extensionManifest;
40
+
41
+ //# sourceMappingURL=./commandSet_5.manifest.js.map
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "adaptive-card-extension-manifest.schema.json",
2
+ "$id": "adaptive-card-extension-manifest.schema.json",
3
3
  "title": "Adaptive Card Extension manifest",
4
4
  "description": "All Adaptive Card Extension built on the SharePoint framework need a valid component manifest. This interface represents properties that are required by all types of BaseAdaptiveCardExtension. Adaptive Card Extension specific manifests will extend this interface to add properties required by that component type.",
5
5
  "definitions": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "any-value.schema.json",
2
+ "$id": "any-value.schema.json",
3
3
 
4
4
  "type": ["array", "boolean", "integer", "number", "object", "string"],
5
5
  "items": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-application-manifest.schema.json",
2
+ "$id": "client-side-application-manifest.schema.json",
3
3
  "title": "Client-side application manifest",
4
4
  "description": "A client-side application is the architectural component that manages the appearance and behavior of an entire web page.",
5
5
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-assembly-manifest.schema.json",
2
+ "$id": "client-side-assembly-manifest.schema.json",
3
3
  "title": "Client-side assembly manifest",
4
4
  "description": "A client-side assembly is a standalone-executable bundle containing a component, the loader, and all of their dependencies.",
5
5
 
@@ -1,11 +1,10 @@
1
1
  {
2
- "id": "client-side-component-loader-configuration.schema.json",
2
+ "$id": "client-side-component-loader-configuration.schema.json",
3
3
  "title": "Client-side component manifest",
4
4
  "description": "All client side components built on the SharePoint framework need a valid component manifest. This interface represents properties that are required by all types of client side components like Applications and Web Parts. Component specific manifests will extend this interface to add properties required by that component type.",
5
5
 
6
6
  "definitions": {
7
7
  "moduleConfiguration": {
8
- "id": "moduleConfiguration",
9
8
  "type": "object",
10
9
  "title": "Module Configuration",
11
10
  "description": "This is the base interface for a script module's definition.",
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-component-manifest.schema.json",
2
+ "$id": "client-side-component-manifest.schema.json",
3
3
  "title": "Client-side component manifest",
4
4
  "description": "All client side components built on the SharePoint framework need a valid component manifest. This interface represents properties that are required by all types of client side components like Applications and Web Parts. Component specific manifests will extend this interface to add properties required by that component type.",
5
5
  "definitions": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-extension-manifest.schema.json",
2
+ "$id": "client-side-extension-manifest.schema.json",
3
3
  "title": "Client-side extension manifest",
4
4
  "description": "A client-side extension is a plug-in component that customizes or augments the functionality of a client-side application.",
5
5
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-library-manifest.schema.json",
2
+ "$id": "client-side-library-manifest.schema.json",
3
3
  "title": "Client-side library manifest",
4
4
  "description": "A client-side library is a library containing reusable JavaScript code and/or resources.",
5
5
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-manifest-base.schema.json",
2
+ "$id": "client-side-manifest-base.schema.json",
3
3
  "title": "Client-side component manifest base",
4
4
  "description": "Properties common to all deployable manifests.",
5
5
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-multi-version-manifest.schema.json",
2
+ "$id": "client-side-multi-version-manifest.schema.json",
3
3
  "title": "Client-side multi-version manifest",
4
4
  "description": "Multi-version manifests are defined by this schema.",
5
5
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "client-side-web-part-manifest.schema.json",
2
+ "$id": "client-side-web-part-manifest.schema.json",
3
3
  "title": "Client-side webpart manifest",
4
4
  "description": "A client-side webpart is a drop-in control that is part of the end user page authoring experience.",
5
5
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "command-set-extension-manifest.schema.json",
2
+ "$id": "command-set-extension-manifest.schema.json",
3
3
  "title": "Command set extension manifest",
4
4
  "description": "A client-side extension that defines a set of custom commands that can be shown in a menu, tool bar, etc.",
5
5
 
@@ -58,9 +58,9 @@
58
58
  },
59
59
  "type": {
60
60
  "type": "string",
61
- "enum": ["command"],
61
+ "enum": ["command", "group"],
62
62
  "title": "Type",
63
- "description": "Type of the item. Currently only \"command\" is allowed."
63
+ "description": "Type of the item. Use 'command' for executable commands, or 'group' for containers that organize commands into submenus."
64
64
  },
65
65
  "ariaLabel": {
66
66
  "title": "ARIA Label",
@@ -72,6 +72,12 @@
72
72
  "minLength": 1,
73
73
  "title": "Icon Image URL",
74
74
  "description": "An optional URL for an image to be displayed next to the item. The requirements for this image are defined by the type of extension; some extension types may not display the image at all."
75
+ },
76
+ "group": {
77
+ "type": "string",
78
+ "pattern": "^[A-Z0-9_]+$",
79
+ "title": "Group",
80
+ "description": "Optional ID of a parent group item this command/group belongs to. The parent must be defined in the same manifest with type 'group'. Maximum nesting depth is 2 levels."
75
81
  }
76
82
  },
77
83
  "additionalProperties": false