diff --git a/packages/ckeditor5-core/src/editor/editor.ts b/packages/ckeditor5-core/src/editor/editor.ts index c385de96fae..6f0a5620429 100644 --- a/packages/ckeditor5-core/src/editor/editor.ts +++ b/packages/ckeditor5-core/src/editor/editor.ts @@ -469,13 +469,13 @@ export default abstract class Editor extends /* #__PURE__ */ ObservableMixin() { if ( licensePayload.usageEndpoint ) { editor.once( 'ready', () => { - const telemetry = editor._getTelemetryData(); + const usage = editor._getUsageData(); const request = { requestId: uid(), requestTime: Math.round( Date.now() / 1000 ), license: licenseKey, - telemetry + usage }; editor._sendUsageRequest( licensePayload.usageEndpoint, request ).then( response => { @@ -877,10 +877,10 @@ export default abstract class Editor extends /* #__PURE__ */ ObservableMixin() { */ public static ContextWatchdog = ContextWatchdog; - private _getTelemetryData() { + private _getUsageData(): EditorUsageData { return { - editorVersion: globalThis.CKEDITOR_VERSION - }; + version: globalThis.CKEDITOR_VERSION + } /* TODO: Remove */ as unknown as EditorUsageData; } private _showLicenseError( reason: LicenseErrorReason, pluginName?: string ) { @@ -1015,6 +1015,187 @@ type LicenseErrorReason = 'usageLimit' | 'distributionChannel'; +type EditorUsageData = { + + /** + * The editor version. + */ + version: string; + + /** + * The editor type. + */ + type: `${ 'Classic' | 'Inline' | 'Decoupled' | 'MultiRoot' }Editor`; + + /** + * The list of plugins used in the editor. + */ + plugins: Array; + + /** + * The configuration of the toolbars used in the editor. + */ + toolbar: { + + /** + * The normal toolbar configuration used in the editor (if present). + */ + normal?: ToolbarUsageData; + + /** + * The block toolbar configuration used in the editor (if present). + */ + block?: ToolbarUsageData; + + /** + * The balloon toolbar configuration used in the editor (if present). + */ + balloon?: ToolbarUsageData; + }; + + /** + * The configuration of the context menus used in the editor. + */ + menuBar: { + + /** + * Check if the editor menu is enabled. + */ + isVisible: boolean; + }; + + /** + * The configuration of the language used in the editor. + */ + language: { + + /** + * The language used in the editor UI. + */ + ui: string; + + /** + * The language used in the editor content. + */ + content: string; + }; + + distribution: { + + /** + * The distribution channel of the editor. It can be for example `sh` or `cloud`. + */ + channel: string; + }; + + /** + * Environment and browser information. + */ + env: EnvUsageData; + + /** + * The configuration of the editor integrations. + */ + integrations: { + [integrationName: string]: IntegrationUsageData; + }; +}; + +type IntegrationUsageData = { + + /** + * The version of the CKEditor integration. e.g. it might be `43.0.0`. + */ + version: string; + + /** + * The version of the CKEditor framework used in the integration. e.g. for React integration might be `18.0.0`. + */ + frameworkVersion?: string; + + /** + * Additional data specific to the integration. e.g. for the React integration it might be: + * + * * The list of React components or Hooks used in the integration. + * * Check if the editor was loaded using CDN injector helpers or was placed as head script manually. + */ + additionalData?: Record; +}; + +type EnvUsageData = { + + /** + * Indicates that the application is running on Macintosh. + */ + isMac: boolean; + + /** + * Indicates that the application is running on Windows. + */ + isWindows: boolean; + + /** + * Indicates that the application is running in Firefox (Gecko). + */ + isGecko: boolean; + + /** + * Indicates that the application is running in Safari. + */ + isSafari: boolean; + + /** + * Indicates that the application is running in iOS. + */ + isiOS: boolean; + + /** + * Indicates that the application is running on Android mobile device. + */ + isAndroid: boolean; + + /** + * Indicates that the application is running in a browser using the Blink engine. + */ + isBlink: boolean; +}; + +type ToolbarUsageData = { + + /** + * List of toolbar items without separators and new lines. + */ + items: Array; + + /** + * Check if `-` line separator was used in the toolbar. + */ + isMultiline: boolean; + + /** + * Check if toolbar is configured to stop grouping items when it is full. + */ + shouldNotGroupWhenFull: boolean; +}; + +type PluginUsageData = { + + /** + * The name of the plugin. + */ + name: string; + + /** + * Flag indicating whether the plugin is a premium CKEditor 5 plugin or not. + */ + isPremium: boolean; + + /** + * Flag indicating whether the plugin is an official CKEditor 5 plugin or not. + */ + isOfficial: boolean; +}; + /** * Fired when the {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional * editor components are ready. diff --git a/packages/ckeditor5-core/tests/editor/licensecheck.js b/packages/ckeditor5-core/tests/editor/licensecheck.js index 2e29c0c9747..33837d3915a 100644 --- a/packages/ckeditor5-core/tests/editor/licensecheck.js +++ b/packages/ckeditor5-core/tests/editor/licensecheck.js @@ -566,7 +566,7 @@ describe( 'Editor - license check', () => { const sentData = JSON.parse( fetchStub.firstCall.lastArg.body ); expect( sentData.license ).to.equal( licenseKey ); - expect( sentData.telemetry ).to.deep.equal( { editorVersion: globalThis.CKEDITOR_VERSION } ); + expect( sentData.usage ).to.deep.equal( { version: globalThis.CKEDITOR_VERSION } ); } ); it( 'should not send any request if license key does not contain a usage endpoint', () => {