-
Notifications
You must be signed in to change notification settings - Fork 2
Add schema support for Adobe Express Add-on Manifest #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
prasanta352
wants to merge
2
commits into
adobe:main
Choose a base branch
from
prasanta352:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| import { writeFile, mkdir, readFile } from 'fs/promises'; | ||
| import path from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
| import { existsSync } from 'fs'; | ||
|
|
||
| const __filename = fileURLToPath(import.meta.url); | ||
| const __dirname = path.dirname(__filename); | ||
|
|
||
| /** | ||
| * Get all template directories | ||
| * @returns {string[]} Array of template directory paths | ||
| */ | ||
| function getTemplatePaths() { | ||
| const baseDir = path.resolve(__dirname, '../../create-ccweb-add-on/templates'); | ||
| const templateNames = [ | ||
| 'javascript-with-document-sandbox', | ||
| 'javascript', | ||
| 'react-javascript-with-document-sandbox', | ||
| 'react-javascript', | ||
| 'react-typescript-with-document-sandbox', | ||
| 'react-typescript', | ||
| 'swc-javascript-with-document-sandbox', | ||
| 'swc-javascript', | ||
| 'swc-typescript-with-document-sandbox', | ||
| 'swc-typescript' | ||
| ]; | ||
|
|
||
| return templateNames.map(name => path.join(baseDir, name, 'template')); | ||
| } | ||
|
|
||
| /** | ||
| * Update VSCode settings.json with schema configuration | ||
| * @param {string} vscodeDir - The .vscode directory path | ||
| * @returns {Promise<void>} | ||
| */ | ||
| async function updateVSCodeSettings(vscodeDir) { | ||
| const settingsPath = path.join(vscodeDir, 'settings.json'); | ||
| let settings = {}; | ||
|
|
||
| // Try to read existing settings | ||
| if (existsSync(settingsPath)) { | ||
| try { | ||
| const existingContent = await readFile(settingsPath, 'utf8'); | ||
| settings = JSON.parse(existingContent); | ||
| } catch (error) { | ||
| console.warn(`Warning: Could not parse existing settings.json at ${settingsPath}`); | ||
| } | ||
| } | ||
|
|
||
| // Update json.schemas | ||
| if (!settings['json.schemas']) { | ||
| settings['json.schemas'] = []; | ||
| } | ||
|
|
||
| // Remove existing express-add-on-manifest schema if present | ||
| settings['json.schemas'] = settings['json.schemas'].filter(schema => | ||
| !schema.url || !schema.url.includes('express-add-on-manifest.schema.json') | ||
| ); | ||
|
|
||
| // Add new schema configuration | ||
| settings['json.schemas'].push({ | ||
| "fileMatch": ["manifest.json"], | ||
| "url": ".vscode/express-add-on-manifest.schema.json" | ||
| }); | ||
|
|
||
| await writeFile(settingsPath, JSON.stringify(settings, null, 2)); | ||
| } | ||
|
|
||
| /** | ||
| * Main function to copy schema to templates | ||
| * @returns {Promise<void>} | ||
| */ | ||
| async function main() { | ||
| // Check if schema file exists | ||
| const schemaSourcePath = path.join(__dirname, 'express-add-on-manifest.schema.json'); | ||
| if (!existsSync(schemaSourcePath)) { | ||
| console.error('Schema file not found at:', schemaSourcePath); | ||
| console.log('Please run "npm run generate-schema" first to create the schema file.'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| console.log("Reading existing schema file..."); | ||
| const schemaContent = await readFile(schemaSourcePath, 'utf8'); | ||
|
|
||
| console.log("Copying schema to all template .vscode folders..."); | ||
| const templatePaths = getTemplatePaths(); | ||
|
|
||
| for (const templatePath of templatePaths) { | ||
| const vscodeDir = path.join(templatePath, '.vscode'); | ||
|
|
||
| // Create .vscode directory if it doesn't exist | ||
| if (!existsSync(vscodeDir)) { | ||
| await mkdir(vscodeDir, { recursive: true }); | ||
| } | ||
|
|
||
| // Write schema file | ||
| const schemaPath = path.join(vscodeDir, 'express-add-on-manifest.schema.json'); | ||
| await writeFile(schemaPath, schemaContent); | ||
|
|
||
| // Update settings.json | ||
| await updateVSCodeSettings(vscodeDir); | ||
|
|
||
| console.log(`✓ Updated ${path.relative(process.cwd(), templatePath)}`); | ||
| } | ||
|
|
||
| console.log("Schema copied to all templates successfully!"); | ||
| } | ||
|
|
||
| main().catch(console.error); |
152 changes: 152 additions & 0 deletions
152
packages/add-on-manifest/scripts/express-add-on-manifest.schema.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "title": "Adobe Express Add-on Manifest", | ||
| "description": "Manifest file that defines the metadata for your add-on and how it should behave", | ||
| "type": "object", | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "testId": { | ||
| "type": "string", | ||
| "description": "Used to uniquely identify an add-on among other add-ons during development workflows only. This is auto-generated and inserted into the manifest by the CLI when an add-on is created. This is mandatory in the development workflow and ignored in add-ons submitted to the marketplace." | ||
| }, | ||
| "name": { | ||
| "type": "string", | ||
| "description": "Add-on name for development workflow only. The name provided in the UI during submission is used in all other workflows." | ||
| }, | ||
| "version": { | ||
| "type": "string", | ||
| "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$", | ||
| "description": "Add-on version in 'major.minor.patch' format (e.g. '1.2.0')" | ||
| }, | ||
| "manifestVersion": { | ||
| "type": "number", | ||
| "description": "Version of the manifest schema (e.g. 2)" | ||
| }, | ||
| "requirements": { | ||
| "type": "object", | ||
| "description": "Specify the apps the add-on is applicable for", | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "apps": { | ||
| "type": "array", | ||
| "description": "Add-on authors can specify the apps that the add-on is intended for", | ||
| "minItems": 1, | ||
| "items": { | ||
| "type": "object", | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "enum": ["Express"], | ||
| "description": "Currently supported values: 'Express'" | ||
| }, | ||
| "apiVersion": { | ||
| "type": "number", | ||
| "enum": [1], | ||
| "description": "API version that the add-on uses. Currently supported values: 1" | ||
| }, | ||
| "supportedDeviceClass": { | ||
| "type": "array", | ||
| "description": "Supported platforms by the add-on. If not specified, the default value assumed is: ['desktop']", | ||
| "items": { | ||
| "type": "string", | ||
| "enum": ["desktop"], | ||
| "description": "Browser on desktop" | ||
| } | ||
| } | ||
| }, | ||
| "required": ["name", "apiVersion"] | ||
| } | ||
| }, | ||
| "experimentalApis": { | ||
| "type": "boolean", | ||
| "description": "Add-ons can opt to use experimental apis by specifying this flag. This flag is only allowed during development and needs to be removed during submission." | ||
| }, | ||
| "supportsTouch": { | ||
| "type": "boolean", | ||
| "description": "Whether the add-on supports touch-only devices. If not specified, the default value assumed is false." | ||
| }, | ||
| "renditionPreview": { | ||
| "type": "boolean", | ||
| "description": "Ensure premium content preview is properly handled for free users when add-ons create renditions." | ||
| } | ||
| }, | ||
| "required": ["apps"] | ||
| }, | ||
| "entryPoints": { | ||
| "type": "array", | ||
| "description": "An entry point for your add-on. At least one is required.", | ||
| "minItems": 1, | ||
| "items": { | ||
| "type": "object", | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["panel"], | ||
| "description": "The type of the entry point. Currently supported values: 'panel'" | ||
| }, | ||
| "id": { | ||
| "type": "string", | ||
| "description": "Identifier for the entry point. Must be unique within the add-on." | ||
| }, | ||
| "main": { | ||
| "type": "string", | ||
| "description": "Main file for this entry point when launched." | ||
| }, | ||
| "documentSandbox": { | ||
| "type": "string", | ||
| "description": "File containing the JavaScript code to use with the document sandbox SDK and Adobe Express Document APIs." | ||
| }, | ||
| "permissions": { | ||
| "type": "object", | ||
| "description": "The permissions defined for this entry point", | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "sandbox": { | ||
| "type": "array", | ||
| "description": "List of iframe sandbox permissions", | ||
| "items": { | ||
| "type": "string", | ||
| "enum": [ | ||
| "allow-popups", | ||
| "allow-popups-to-escape-sandbox", | ||
| "allow-presentation", | ||
| "allow-downloads" | ||
| ], | ||
| "description": "allow-popups: Allows popups (such as window.open(), target='_blank', or showModalDialog()). Note: If this permission is not set and you're using popups, the popup will silently fail to open. \n allow-popups-to-escape-sandbox: Allows a sandboxed document to open new windows without forcing the sandboxing flags upon them \n allow-presentation: Lets the add-on start a presentation session \n allow-downloads: Allows downloading files through an <a> or <area> element with the download attribute, as well as through the navigation that leads to a download of a file" | ||
| } | ||
| }, | ||
| "oauth": { | ||
| "type": "array", | ||
| "description": "List of 3rd party auth server domains for which OAuth workflow may be requested. eg. [\"www.dropbox.com\"]", | ||
| "items": { | ||
| "type": "string", | ||
| "format": "hostname" | ||
| } | ||
| }, | ||
| "clipboard": { | ||
| "type": "array", | ||
| "description": "The allowed values for the list of clipboard permissions. Currently, clipboard-write is supported and allows an add-on to write arbitrary data to the clipboard", | ||
| "items": { | ||
| "type": "string", | ||
| "enum": ["clipboard-write"] | ||
| } | ||
| }, | ||
| "microphone": { | ||
| "type": ["string", "boolean"], | ||
| "description": "The allowlists value used in iframe 'allow' attribute. Enables the add-on to access the user's microphone for audio input." | ||
| }, | ||
| "camera": { | ||
| "type": ["string", "boolean"], | ||
| "description": "The allowlists value used in iframe 'allow' attribute. Enables the add-on to access the user's camera for video input." | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "required": ["type", "id", "main"] | ||
| } | ||
| } | ||
| }, | ||
| "required": ["version", "manifestVersion", "requirements", "entryPoints"] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates a logical cycle. The
@adobe/ccweb-add-on-manifestpackage sits at the very bottom of the dependency graph, where the other packages like@adobe/create-ccweb-add-ondepend on it.So, the
copy-schema.jsscript fromadd-on-manifestwriting tocreate-ccweb-add-oncreates this cycle.Please remove the changes made in the
add-on-manifestpackage, skipping the copy-schema step.It would be great, though if we could automatically generate
express-add-on-manifest.schema.json. Could be a follow-up.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, thanks @xerxovksi As you mentioned, I have reverted the changes in
@adobe/ccweb-add-on-manifestand skip thecopy-schemastep to avoid the cycle.I also agree it would be good to auto-generate
express-add-on-manifest.schema.json. Updating the docs to include optional types would be the prerequisite, otherwise the schema wouldn’t be accurate.On which step do you think the auto-generation should happen once the docs are updated?