diff --git a/src/cdn/ck/createCKCdnBaseBundlePack.ts b/src/cdn/ck/createCKCdnBaseBundlePack.ts index eb29381..94b5616 100644 --- a/src/cdn/ck/createCKCdnBaseBundlePack.ts +++ b/src/cdn/ck/createCKCdnBaseBundlePack.ts @@ -12,7 +12,8 @@ import { without } from '../../utils/without.js'; import { getCKBaseBundleInstallationInfo } from '../../installation-info/getCKBaseBundleInstallationInfo.js'; import { createCKDocsUrl } from '../../docs/createCKDocsUrl.js'; -import { createCKCdnUrl, type CKCdnVersion } from './createCKCdnUrl.js'; +import { createCKCdnUrl, type CKCdnUrlCreator } from './createCKCdnUrl.js'; +import type { CKCdnVersion } from './isCKCdnVersion.js'; import './globals.js'; @@ -118,5 +119,5 @@ export type CKCdnBaseBundlePackConfig = { /** * The function that creates custom CDN URLs. */ - createCustomCdnUrl?: typeof createCKCdnUrl; + createCustomCdnUrl?: CKCdnUrlCreator; }; diff --git a/src/cdn/ck/createCKCdnUrl.ts b/src/cdn/ck/createCKCdnUrl.ts index 0e78171..4f86345 100644 --- a/src/cdn/ck/createCKCdnUrl.ts +++ b/src/cdn/ck/createCKCdnUrl.ts @@ -3,18 +3,13 @@ * For licensing, see LICENSE.md. */ -import type { SemanticVersion } from '../../utils/version/isSemanticVersion.js'; +import type { CKCdnVersion } from './isCKCdnVersion.js'; /** * The URL of the CKEditor CDN. */ export const CK_CDN_URL = 'https://cdn.ckeditor.com'; -/** - * A version of a file on the CKEditor CDN. - */ -export type CKCdnVersion = SemanticVersion; - /** * Creates a URL to a file on the CKEditor CDN. * @@ -32,3 +27,8 @@ export type CKCdnVersion = SemanticVersion; export function createCKCdnUrl( bundle: string, file: string, version: CKCdnVersion ): string { return `${ CK_CDN_URL }/${ bundle }/${ version }/${ file }`; } + +/** + * A function that creates a URL to a file on the CKEditor CDN. + */ +export type CKCdnUrlCreator = typeof createCKCdnUrl; diff --git a/src/cdn/ck/isCKCdnVersion.ts b/src/cdn/ck/isCKCdnVersion.ts new file mode 100644 index 0000000..537723c --- /dev/null +++ b/src/cdn/ck/isCKCdnVersion.ts @@ -0,0 +1,60 @@ +/** + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { isSemanticVersion, type SemanticVersion } from '../../utils/version/isSemanticVersion.js'; + +/** + * A version of the CKEditor that is used for testing purposes. + */ +export type CKCdnTestingVersion = + | 'nightly' + | 'alpha' + | 'internal'; + +/** + * A version of a file on the CKEditor CDN. + */ +export type CKCdnVersion = + | SemanticVersion + | CKCdnTestingVersion; + +/** + * Checks if the given string is a version of a file on the CKEditor CDN. + * + * @param version - The string to check. + * @returns `true` if the string is a version of a file on the CKEditor CDN, `false` otherwise. + * @example + * ```ts + * isCKCdnTestingVersion( '1.2.3-nightly-abc' ); // -> true + * isCKCdnTestingVersion( '1.2.3-internal-abc' ); // -> true + * isCKCdnTestingVersion( '1.2.3-alpha.1' ); // -> true + * isCKCdnTestingVersion( '1.2.3' ); // -> false + * isCKCdnTestingVersion( 'nightly' ); // -> true + * ``` + */ +export function isCKCdnTestingVersion( version: string | undefined ): version is CKCdnTestingVersion { + if ( !version ) { + return false; + } + + return [ 'nightly', 'alpha', 'internal' ].some( testVersion => version.includes( testVersion ) ); +} + +/** + * Checks if the given string is a version of a file on the CKEditor CDN. + * + * @param version - The string to check. + * @returns `true` if the string is a version of a file on the CKEditor CDN, `false` otherwise. + * @example + * ```ts + * isCKCdnVersion( 'nightly' ); // -> true + * isCKCdnVersion( 'alpha' ); // -> true + * isCKCdnVersion( 'rc-1.2.3' ); // -> true + * isCKCdnVersion( '1.2.3' ); // -> true + * ``` + */ +export function isCKCdnVersion( version: string | undefined ): version is CKCdnVersion { + return isSemanticVersion( version ) || isCKCdnTestingVersion( version ); +} diff --git a/src/cdn/loadCKEditorCloud.ts b/src/cdn/loadCKEditorCloud.ts index 8984325..168db55 100644 --- a/src/cdn/loadCKEditorCloud.ts +++ b/src/cdn/loadCKEditorCloud.ts @@ -12,8 +12,10 @@ import { type CKBoxCdnBundlePackConfig } from './ckbox/createCKBoxCdnBundlePack.js'; +import type { CKCdnUrlCreator } from './ck/createCKCdnUrl.js'; import type { ConditionalBlank } from '../types/ConditionalBlank.js'; -import type { CKCdnVersion, createCKCdnUrl } from './ck/createCKCdnUrl.js'; + +import { isCKCdnTestingVersion, type CKCdnVersion } from './ck/isCKCdnVersion.js'; import { loadCKCdnResourcesPack, @@ -83,6 +85,12 @@ export function loadCKEditorCloud( } } = config; + if ( isCKCdnTestingVersion( version ) ) { + console.warn( + 'You are using a testing version of CKEditor 5. Please remember that it is not suitable for production environments.' + ); + } + const pack = combineCKCdnBundlesPacks( { CKEditor: createCKCdnBaseBundlePack( { version, @@ -187,5 +195,5 @@ export type CKEditorCloudConfig | null { const { CKEDITOR_VERSION, CKEDITOR } = window; - if ( !isSemanticVersion( CKEDITOR_VERSION ) ) { + if ( !isCKCdnVersion( CKEDITOR_VERSION ) ) { return null; } diff --git a/src/installation-info/getSupportedLicenseVersionInstallationInfo.ts b/src/installation-info/getSupportedLicenseVersionInstallationInfo.ts index 9d7482d..f91a2a1 100644 --- a/src/installation-info/getSupportedLicenseVersionInstallationInfo.ts +++ b/src/installation-info/getSupportedLicenseVersionInstallationInfo.ts @@ -3,6 +3,7 @@ * For licensing, see LICENSE.md. */ +import { isCKCdnTestingVersion } from '../cdn/ck/isCKCdnVersion.js'; import type { LicenseKeyVersion } from '../license/LicenseKey.js'; import { destructureSemanticVersion } from '../utils/version/destructureSemanticVersion.js'; @@ -22,6 +23,13 @@ export function getSupportedLicenseVersionInstallationInfo(): LicenseKeyVersion } const { version } = installationInfo; + + // Assume that the testing version is always the newest one + // so we can return the highest supported license version. + if ( isCKCdnTestingVersion( version ) ) { + return 3; + } + const { major } = destructureSemanticVersion( version ); // License V3 was released in CKEditor 44.0.0. diff --git a/src/installation-info/types.ts b/src/installation-info/types.ts index 3442dbf..7e878b7 100644 --- a/src/installation-info/types.ts +++ b/src/installation-info/types.ts @@ -13,7 +13,7 @@ type BundleInstallationSource = 'npm' | 'cdn'; /** * Information about the currently installed CKEditor. */ -export type BundleInstallationInfo = { +export type BundleInstallationInfo = { /** * The source from which CKEditor was installed. @@ -23,5 +23,5 @@ export type BundleInstallationInfo = { /** * The version of CKEditor. */ - version: SemanticVersion; + version: V; }; diff --git a/tests/cdn/ck/createCKCdnBaseBundlePack.test.ts b/tests/cdn/ck/createCKCdnBaseBundlePack.test.ts index 7b11d6d..39ac2fa 100644 --- a/tests/cdn/ck/createCKCdnBaseBundlePack.test.ts +++ b/tests/cdn/ck/createCKCdnBaseBundlePack.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import type { CKCdnVersion } from '@/cdn/ck/createCKCdnUrl.js'; +import type { CKCdnVersion } from '@/cdn/ck/isCKCdnVersion.js'; import { createCKCdnBaseBundlePack, diff --git a/tests/cdn/ck/createCKCdnPremiumBundlePack.test.ts b/tests/cdn/ck/createCKCdnPremiumBundlePack.test.ts index ee19f06..b5aca16 100644 --- a/tests/cdn/ck/createCKCdnPremiumBundlePack.test.ts +++ b/tests/cdn/ck/createCKCdnPremiumBundlePack.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import type { CKCdnVersion } from '@/cdn/ck/createCKCdnUrl.js'; +import type { CKCdnVersion } from '@/cdn/ck/isCKCdnVersion.js'; import { loadCKCdnResourcesPack } from '@/cdn/utils/loadCKCdnResourcesPack.js'; import { removeAllCkCdnResources } from '@/test-utils/cdn/removeAllCkCdnResources.js'; diff --git a/tests/cdn/ck/isCKCdnVersion.test.ts b/tests/cdn/ck/isCKCdnVersion.test.ts new file mode 100644 index 0000000..29c457b --- /dev/null +++ b/tests/cdn/ck/isCKCdnVersion.test.ts @@ -0,0 +1,35 @@ +/** + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { describe, it, expect } from 'vitest'; +import { isCKCdnVersion, isCKCdnTestingVersion } from '@/cdn/ck/isCKCdnVersion.js'; + +const testCases = [ + { version: 'alpha', isTesting: true, isVersion: true }, + { version: 'nightly', isTesting: true, isVersion: true }, + { version: 'rc-1.2.3', isTesting: false, isVersion: false }, + { version: '1.2.3', isTesting: false, isVersion: true }, + { version: 'beta', isTesting: false, isVersion: false }, + { version: '1.2', isTesting: false, isVersion: false }, + { version: '0.0.0-nightly-20241104.0', isTesting: true, isVersion: true }, + { version: '0.0.0-internal-20241104.0', isTesting: true, isVersion: true }, + { version: '43.3.0-alpha.12 ', isTesting: true, isVersion: true } +]; + +describe( 'isCKCdnTestingVersion', () => { + for ( const { version, isTesting } of testCases ) { + it( `should return ${ isTesting } for "${ version }"`, () => { + expect( isCKCdnTestingVersion( version ) ).toBe( isTesting ); + } ); + } +} ); + +describe( 'isCKCdnVersion', () => { + for ( const { version, isVersion } of testCases ) { + it( `should return ${ isVersion } for "${ version }"`, () => { + expect( isCKCdnVersion( version ) ).toBe( isVersion ); + } ); + } +} ); diff --git a/tests/cdn/loadCKEditorCloud.test.ts b/tests/cdn/loadCKEditorCloud.test.ts index f8e8463..04d6f63 100644 --- a/tests/cdn/loadCKEditorCloud.test.ts +++ b/tests/cdn/loadCKEditorCloud.test.ts @@ -27,6 +27,8 @@ describe( 'loadCKEditorCloud', () => { removeAllCkCdnResources(); vi.spyOn( console, 'error' ).mockImplementation( () => undefined ); + vi.spyOn( console, 'warn' ).mockImplementation( () => undefined ); + window.FakePlugin = { fake: 'fake' }; } ); @@ -34,6 +36,28 @@ describe( 'loadCKEditorCloud', () => { vi.restoreAllMocks(); } ); + for ( const version of [ 'alpha', 'internal' ] as const ) { + it( `should raise warning if ${ version } version is used`, async () => { + const { CKEditor } = await loadCKEditorCloud( { + version + } ); + + expect( CKEditor.ClassicEditor ).toBeDefined(); + expect( console.warn ).toBeCalledWith( + 'You are using a testing version of CKEditor 5. Please remember that it is not suitable for production environments.' + ); + } ); + } + + it( 'should not raise a warning if non-testing version is passed', async () => { + const { CKEditor } = await loadCKEditorCloud( { + version: '43.0.0' + } ); + + expect( CKEditor.ClassicEditor ).toBeDefined(); + expect( console.warn ).not.toBeCalled(); + } ); + it( 'should be possible to load base ckeditor with base features', async () => { const { CKEditor, CKBox, CKEditorPremiumFeatures } = await loadCKEditorCloud( { version: '43.0.0' diff --git a/tests/installation-info/getSupportedLicenseVersionInstallationInfo.test.ts b/tests/installation-info/getSupportedLicenseVersionInstallationInfo.test.ts index 158f5a1..4046f26 100644 --- a/tests/installation-info/getSupportedLicenseVersionInstallationInfo.test.ts +++ b/tests/installation-info/getSupportedLicenseVersionInstallationInfo.test.ts @@ -51,6 +51,13 @@ describe( 'getSupportedLicenseVersionInstallationInfo', () => { mockEditorVersion( '37.0.0' ); expect( getSupportedLicenseVersionInstallationInfo() ).toEqual( 1 ); } ); + + it( 'should return license V3 for test versions', () => { + for ( const version of [ 'alpha', 'nightly', 'internal' ] ) { + mockEditorVersion( version ); + expect( getSupportedLicenseVersionInstallationInfo() ).toEqual( 3 ); + } + } ); } ); function mockEditorVersion( version: string ): void {