diff --git a/common/changes/@adobe/ccweb-add-on-analytics/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/ccweb-add-on-analytics/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..4e9be1d --- /dev/null +++ b/common/changes/@adobe/ccweb-add-on-analytics/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/ccweb-add-on-analytics", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/ccweb-add-on-analytics" +} \ No newline at end of file diff --git a/common/changes/@adobe/ccweb-add-on-core/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/ccweb-add-on-core/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..a692a13 --- /dev/null +++ b/common/changes/@adobe/ccweb-add-on-core/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/ccweb-add-on-core", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/ccweb-add-on-core" +} \ No newline at end of file diff --git a/common/changes/@adobe/ccweb-add-on-manifest/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/ccweb-add-on-manifest/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..54c1d6f --- /dev/null +++ b/common/changes/@adobe/ccweb-add-on-manifest/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/ccweb-add-on-manifest", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/ccweb-add-on-manifest" +} \ No newline at end of file diff --git a/common/changes/@adobe/ccweb-add-on-scaffolder/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/ccweb-add-on-scaffolder/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..0a1c12e --- /dev/null +++ b/common/changes/@adobe/ccweb-add-on-scaffolder/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/ccweb-add-on-scaffolder", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/ccweb-add-on-scaffolder" +} \ No newline at end of file diff --git a/common/changes/@adobe/ccweb-add-on-scripts/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/ccweb-add-on-scripts/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..53d6c47 --- /dev/null +++ b/common/changes/@adobe/ccweb-add-on-scripts/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/ccweb-add-on-scripts", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/ccweb-add-on-scripts" +} \ No newline at end of file diff --git a/common/changes/@adobe/ccweb-add-on-ssl/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/ccweb-add-on-ssl/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..1259416 --- /dev/null +++ b/common/changes/@adobe/ccweb-add-on-ssl/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/ccweb-add-on-ssl", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/ccweb-add-on-ssl" +} \ No newline at end of file diff --git a/common/changes/@adobe/create-ccweb-add-on/release-20250320_2025-03-20-08-53.json b/common/changes/@adobe/create-ccweb-add-on/release-20250320_2025-03-20-08-53.json new file mode 100644 index 0000000..ecb3765 --- /dev/null +++ b/common/changes/@adobe/create-ccweb-add-on/release-20250320_2025-03-20-08-53.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@adobe/create-ccweb-add-on", + "comment": "Manifest update", + "type": "minor" + } + ], + "packageName": "@adobe/create-ccweb-add-on" +} \ No newline at end of file diff --git a/packages/add-on-manifest/.mocharc.json b/packages/add-on-manifest/.mocharc.json index b85c06f..118fcce 100644 --- a/packages/add-on-manifest/.mocharc.json +++ b/packages/add-on-manifest/.mocharc.json @@ -1,5 +1,10 @@ { "extension": ["ts"], - "node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm", "no-warnings"], + "node-option": [ + "experimental-specifier-resolution=node", + "loader=ts-node/esm", + "enable-source-maps", + "no-warnings" + ], "spec": ["src/test/**/*.spec.ts"] } diff --git a/packages/add-on-manifest/package.json b/packages/add-on-manifest/package.json index dfb558a..6401078 100644 --- a/packages/add-on-manifest/package.json +++ b/packages/add-on-manifest/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/ccweb-add-on-manifest", - "version": "2.4.1", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "Manifest models and validation rules for Adobe Creative Cloud Web Add-on.", diff --git a/packages/add-on-manifest/scripts/AddOnManifestSchemaTypes.js b/packages/add-on-manifest/scripts/AddOnManifestSchemaTypes.js index 10abe8a..e75111d 100644 --- a/packages/add-on-manifest/scripts/AddOnManifestSchemaTypes.js +++ b/packages/add-on-manifest/scripts/AddOnManifestSchemaTypes.js @@ -22,7 +22,8 @@ * SOFTWARE. ********************************************************************************/ -const typePattern = "^(panel|share|content-hub|mobile.your-stuff.files|mobile.media.audio|mobile.more)$"; +const typePattern = + "^(panel|command|share|content-hub|mobile.your-stuff.files|mobile.media.audio|mobile.more|schedule|contextual.replace|contextual.upload|contextual.bulk-create)$"; const sandboxPattern = "^(allow-popups|allow-presentation|allow-downloads|allow-popups-to-escape-sandbox|allow-forms)$"; const clipboardPattern = "^(clipboard-write|clipboard-read)$"; const iconPattern = "^(lightest|light|medium|dark|darkest|all)$"; @@ -62,6 +63,17 @@ export const AuthorInfoSchema = { additionalProperties: false }; +export const CommandSchema = { + type: "object", + properties: { + name: { type: "string" }, + supportedMimeTypes: { type: "array", items: { type: "string" } }, + discoverable: { type: "boolean" } + }, + required: ["name"], + additionalProperties: false +}; + export const EntrypointSchemaV1 = { type: "object", properties: { @@ -103,6 +115,7 @@ export const EntrypointSchemaV2 = { script: { type: "string" }, documentSandbox: { type: "string" }, hostDomain: { type: "string" }, + commands: { type: "array", items: CommandSchema }, permissions: { type: "object", properties: { diff --git a/packages/add-on-manifest/src/AddOnManifest.ts b/packages/add-on-manifest/src/AddOnManifest.ts index 15f6fe8..041bbbe 100644 --- a/packages/add-on-manifest/src/AddOnManifest.ts +++ b/packages/add-on-manifest/src/AddOnManifest.ts @@ -189,7 +189,7 @@ export class AddOnManifest { } } - get entryPoints(): Readonly { + get entryPoints(): readonly AddOnManifestEntrypoint[] { if (!this._entrypoints.length) { this._manifest.entryPoints.forEach(entrypoint => { this._entrypoints.push(new AddOnManifestEntrypoint(this._manifest.manifestVersion, entrypoint)); diff --git a/packages/add-on-manifest/src/AddOnManifestTypes.ts b/packages/add-on-manifest/src/AddOnManifestTypes.ts index 0f552b0..776e5af 100644 --- a/packages/add-on-manifest/src/AddOnManifestTypes.ts +++ b/packages/add-on-manifest/src/AddOnManifestTypes.ts @@ -99,6 +99,12 @@ export type Permissions = { readonly clipboard?: string[]; }; +export type Command = { + readonly name: string; + readonly supportedMimeTypes?: string[]; + readonly discoverable?: boolean; +}; + export type EntrypointV1 = { readonly type: string; readonly id: string; @@ -118,7 +124,11 @@ export type EntrypointV2 = Omit & { readonly hostDomain?: string; }; -export type ManifestEntrypoint = EntrypointV1 | EntrypointV2; +export type CommandEntrypoint = EntrypointV2 & { + readonly commands: Command[]; +}; + +export type ManifestEntrypoint = EntrypointV1 | EntrypointV2 | CommandEntrypoint; export type ManifestRequirements = RequirementsV1 | RequirementsV2; /** @@ -138,7 +148,11 @@ export enum EntrypointType { CONTENT_HUB = "content-hub", MOBILE_MEDIA_AUDIO = "mobile.media.audio", MOBILE_YOUR_STUFF_FILES = "mobile.your-stuff.files", - MOBILE_MORE = "mobile.more" + MOBILE_MORE = "mobile.more", + SCHEDULE = "schedule", + CONTEXTUAL_REPLACE = "contextual.replace", + CONTEXTUAL_UPLOAD = "contextual.upload", + CONTEXTUAL_BULK_CREATE = "contextual.bulk-create" } export type AuthorInfo = { diff --git a/packages/add-on-manifest/src/manifest-field/AddOnManifestApp.ts b/packages/add-on-manifest/src/manifest-field/AddOnManifestApp.ts index 3163cd0..d76994e 100644 --- a/packages/add-on-manifest/src/manifest-field/AddOnManifestApp.ts +++ b/packages/add-on-manifest/src/manifest-field/AddOnManifestApp.ts @@ -40,7 +40,7 @@ export class AddOnManifestApp { return this._app.apiVersion; } - get supportedDeviceClass(): Readonly { + get supportedDeviceClass(): readonly string[] { return this._app.supportedDeviceClass || DEFAULT_SUPPORTED_DEVICE_CLASS; } } diff --git a/packages/add-on-manifest/src/manifest-field/AddOnManifestEntrypoint.ts b/packages/add-on-manifest/src/manifest-field/AddOnManifestEntrypoint.ts index c986fc5..1153892 100644 --- a/packages/add-on-manifest/src/manifest-field/AddOnManifestEntrypoint.ts +++ b/packages/add-on-manifest/src/manifest-field/AddOnManifestEntrypoint.ts @@ -24,8 +24,10 @@ import { ManifestVersion } from "../AddOnManifest.js"; import { + Command, EntrypointV1, EntrypointV2, + CommandEntrypoint, LocalisedStrings, ManifestEntrypoint, Permissions, @@ -34,7 +36,7 @@ import { interface ManifestEntrypointTypeMap { [ManifestVersion.V1]: EntrypointV1; - [ManifestVersion.V2]: EntrypointV2; + [ManifestVersion.V2]: EntrypointV2 | CommandEntrypoint; } export type ManifestEntrypointType = ManifestEntrypointTypeMap[T]; @@ -124,4 +126,15 @@ export class AddOnManifestEntrypoint { } } } + + get commands(): Command[] | undefined { + switch (this._manifestVersion) { + case ManifestVersion.V1: { + return undefined; + } + default: { + return (this._entrypoint as ManifestEntrypointType as CommandEntrypoint)?.commands; + } + } + } } diff --git a/packages/add-on-manifest/src/test/AddOnManifest.spec.ts b/packages/add-on-manifest/src/test/AddOnManifest.spec.ts index 392ae88..0c562d1 100644 --- a/packages/add-on-manifest/src/test/AddOnManifest.spec.ts +++ b/packages/add-on-manifest/src/test/AddOnManifest.spec.ts @@ -23,6 +23,7 @@ ********************************************************************************/ import { assert } from "chai"; +import "mocha"; import sinon from "sinon"; import { AddOnManifest, ManifestVersion } from "../AddOnManifest.js"; import { AddOnLogAction, AddOnLogLevel, OTHER_MANIFEST_ERRORS } from "../AddOnManifestTypes.js"; @@ -90,6 +91,7 @@ describe("AddOnManifest", () => { assert.equal(manifest.entryPoints[0].label, testManifest.entryPoints[0].label); assert.equal(manifest.entryPoints[0].defaultSize, testManifest.entryPoints[0].defaultSize); + assert.equal(manifest.entryPoints[0].commands, undefined); assert.equal(manifest.requirements.apps, testManifest.requirements.apps); assert.equal(manifest.requirements.privilegedApis, false); assert.equal(false, manifest.requirements.supportsTouch); @@ -114,6 +116,7 @@ describe("AddOnManifest", () => { assert.equal(manifest.entryPoints[0].label, undefined); assert.equal(manifest.entryPoints[0].defaultSize, testManifest.entryPoints[0].defaultSize); + assert.deepEqual(manifest.entryPoints[1].commands, testManifest.entryPoints[1].commands); const apps = manifest.requirements.apps as AddOnManifestApp[]; assert.equal(testManifest.requirements.supportsTouch, manifest.requirements.supportsTouch); @@ -129,7 +132,7 @@ describe("AddOnManifest", () => { assert.equal(apps[1].supportedDeviceClass, DEFAULT_SUPPORTED_DEVICE_CLASS); }); - it("should return deafult manifestVersion for dev AddOn", () => { + it("should return default manifestVersion for dev AddOn", () => { const devManifest = getTestDeveloperManifestV1() as ReturnType; delete devManifest.manifestVersion; const { manifest } = AddOnManifest.createManifest( diff --git a/packages/add-on-manifest/src/test/ManifestSchemaDeveloper.spec.ts b/packages/add-on-manifest/src/test/ManifestSchemaDeveloper.spec.ts index 9159339..efdb502 100644 --- a/packages/add-on-manifest/src/test/ManifestSchemaDeveloper.spec.ts +++ b/packages/add-on-manifest/src/test/ManifestSchemaDeveloper.spec.ts @@ -23,6 +23,7 @@ ********************************************************************************/ import { assert } from "chai"; +import "mocha"; import { OTHER_MANIFEST_ERRORS } from "../AddOnManifestTypes.js"; import { AddOnManifestValidator } from "../AddOnManifestValidator.js"; import { diff --git a/packages/add-on-manifest/src/test/ManifestSchemaTests.spec.ts b/packages/add-on-manifest/src/test/ManifestSchemaTests.spec.ts index 79adc23..f9b1100 100644 --- a/packages/add-on-manifest/src/test/ManifestSchemaTests.spec.ts +++ b/packages/add-on-manifest/src/test/ManifestSchemaTests.spec.ts @@ -23,6 +23,7 @@ ********************************************************************************/ import { assert } from "chai"; +import "mocha"; import sinon from "sinon"; import { AddOnManifestType, ManifestVersion } from "../AddOnManifest.js"; import { @@ -213,8 +214,15 @@ describe("ManifestSchema Validations - Version 1", () => { }); it("should have a valid entry point type", () => { - const validTypePatterns = ["panel", "mobile.media.audio", "mobile.your-stuff.files"]; - const invalidTypePatterns = ["widgets", "panels", "mobile.media", "mobile.your-stuff"]; + const validTypePatterns = [ + "panel", + "mobile.media.audio", + "mobile.your-stuff.files", + "contextual.replace", + "contextual.upload", + "contextual.bulk-create" + ]; + const invalidTypePatterns = ["widgets", "panels", "mobile.media", "mobile.your-stuff", "contextual.insert"]; const testFn = (manifest: ReturnType, value: string) => { (manifest.entryPoints[0] as MutableObject).type = value; @@ -704,8 +712,15 @@ describe("ManifestSchema Validations - Version 2", () => { }); it("should have a valid entry point type", () => { - const validTypePatterns = ["panel", "mobile.media.audio", "mobile.your-stuff.files"]; - const invalidTypePatterns = ["widgets", "panels", "mobile.media", "mobile.your-stuff"]; + const validTypePatterns = [ + "panel", + "mobile.media.audio", + "mobile.your-stuff.files", + "contextual.replace", + "contextual.upload", + "contextual.bulk-create" + ]; + const invalidTypePatterns = ["widgets", "panels", "mobile.media", "mobile.your-stuff", "contextual.insert"]; const testFn = (manifest: ReturnType, value: string) => { (manifest.entryPoints[0] as MutableObject).type = value; diff --git a/packages/add-on-manifest/src/test/utils/TestManifests.ts b/packages/add-on-manifest/src/test/utils/TestManifests.ts index 71ba1a6..d1a9ec6 100644 --- a/packages/add-on-manifest/src/test/utils/TestManifests.ts +++ b/packages/add-on-manifest/src/test/utils/TestManifests.ts @@ -126,6 +126,21 @@ export function getTestManifestV1(privileged?: boolean): AddOnManifestV1 { type: EntrypointType.MOBILE_YOUR_STUFF_FILES, id: `mobile-your-stuff-files-${count}`, ...entryPointDetails + }, + { + type: EntrypointType.CONTEXTUAL_REPLACE, + id: `contextual-replace-${count}`, + ...entryPointDetails + }, + { + type: EntrypointType.CONTEXTUAL_UPLOAD, + id: `contextual-upload-${count}`, + ...entryPointDetails + }, + { + type: EntrypointType.CONTEXTUAL_BULK_CREATE, + id: `contextual-bulk-create-${count}`, + ...entryPointDetails } ], icon: [ @@ -199,6 +214,21 @@ export function getTestManifestV2(privileged?: boolean): AddOnManifestV2 { discoverable: true, hostDomain: "https://localhost.adobe.com" }, + { + type: EntrypointType.COMMAND, + id: "assetProvider", + main: "command.html", + commands: [ + { + name: "assetProvider.getAssets", + supportedMimeTypes: ["image/jpeg", "image/png", "image/bmp"], + discoverable: true + } + ], + permissions: { + oauth: ["accounts.google.com"] + } + }, { type: EntrypointType.MOBILE_MEDIA_AUDIO, id: `mobile-media-audio-${count}`, @@ -208,6 +238,21 @@ export function getTestManifestV2(privileged?: boolean): AddOnManifestV2 { type: EntrypointType.MOBILE_YOUR_STUFF_FILES, id: `mobile-your-stuff-files-${count}`, main: "index.html" + }, + { + type: EntrypointType.CONTEXTUAL_REPLACE, + id: `contextual-replace-${count}`, + main: "index.html" + }, + { + type: EntrypointType.CONTEXTUAL_UPLOAD, + id: `contextual-upload-${count}`, + main: "index.html" + }, + { + type: EntrypointType.CONTEXTUAL_BULK_CREATE, + id: `contextual-bulk-create-${count}`, + main: "index.html" } ] }; diff --git a/packages/create-ccweb-add-on/package.json b/packages/create-ccweb-add-on/package.json index 6d25bbf..1c286a9 100644 --- a/packages/create-ccweb-add-on/package.json +++ b/packages/create-ccweb-add-on/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/create-ccweb-add-on", - "version": "2.4.2", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "Create an Adobe Creative Cloud Web Add-on.", diff --git a/packages/wxp-add-on-scaffolder/package.json b/packages/wxp-add-on-scaffolder/package.json index 270e976..e76996d 100644 --- a/packages/wxp-add-on-scaffolder/package.json +++ b/packages/wxp-add-on-scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/ccweb-add-on-scaffolder", - "version": "2.4.1", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "Scaffolding libraries for Adobe Creative Cloud Web Add-on.", diff --git a/packages/wxp-analytics/package.json b/packages/wxp-analytics/package.json index 26951b1..5836c58 100644 --- a/packages/wxp-analytics/package.json +++ b/packages/wxp-analytics/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/ccweb-add-on-analytics", - "version": "2.4.1", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "Analytics libraries for Adobe Creative Cloud Web Add-on.", diff --git a/packages/wxp-core/package.json b/packages/wxp-core/package.json index 6a803c6..cd2540a 100644 --- a/packages/wxp-core/package.json +++ b/packages/wxp-core/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/ccweb-add-on-core", - "version": "2.4.1", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "Core libraries for Adobe Creative Cloud Web Add-on.", diff --git a/packages/wxp-scripts/package.json b/packages/wxp-scripts/package.json index 30a798d..00678f5 100644 --- a/packages/wxp-scripts/package.json +++ b/packages/wxp-scripts/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/ccweb-add-on-scripts", - "version": "2.4.3", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "Scripts for Adobe Creative Cloud Web Add-on.", diff --git a/packages/wxp-ssl/package.json b/packages/wxp-ssl/package.json index fc665b9..02df955 100644 --- a/packages/wxp-ssl/package.json +++ b/packages/wxp-ssl/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/ccweb-add-on-ssl", - "version": "2.4.1", + "version": "2.5.0", "author": "Adobe", "license": "MIT", "description": "SSL scripts for Adobe Creative Cloud Web Add-on.", diff --git a/rush.json b/rush.json index f7684c6..c6bcd97 100644 --- a/rush.json +++ b/rush.json @@ -19,13 +19,13 @@ "packageName": "@adobe/ccweb-add-on-manifest", "projectFolder": "packages/add-on-manifest", "reviewCategory": "production", - "shouldPublish": false + "shouldPublish": true }, { "packageName": "@adobe/ccweb-add-on-core", "projectFolder": "packages/wxp-core", "reviewCategory": "production", - "shouldPublish": false + "shouldPublish": true }, { "packageName": "@adobe/create-ccweb-add-on", @@ -37,25 +37,25 @@ "packageName": "@adobe/ccweb-add-on-scaffolder", "projectFolder": "packages/wxp-add-on-scaffolder", "reviewCategory": "production", - "shouldPublish": false + "shouldPublish": true }, { "packageName": "@adobe/ccweb-add-on-scripts", "projectFolder": "packages/wxp-scripts", "reviewCategory": "production", - "shouldPublish": false + "shouldPublish": true }, { "packageName": "@adobe/ccweb-add-on-ssl", "projectFolder": "packages/wxp-ssl", "reviewCategory": "production", - "shouldPublish": false + "shouldPublish": true }, { "packageName": "@adobe/ccweb-add-on-analytics", "projectFolder": "packages/wxp-analytics", "reviewCategory": "production", - "shouldPublish": false + "shouldPublish": true }, { "packageName": "@adobe/ccweb-add-on-sdk-types",