diff --git a/README.md b/README.md index 98d2717..f8fea21 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ This is a JavaScript library to easily configure the loading of the [hCaptcha](h 1. [Installation](#installation) 2. [Implementation](#implementation) 3. [Props](#props) +3. [Legacy Support](#legacy-support) ### Installation ``` @@ -30,21 +31,83 @@ const { response } = await hcaptcha.execute({ async: true }); ``` ### Props -| Name | Values/Type | Required | Default | Description | -|-------------------|-------------|----------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| -| `loadAsync` | Boolean | No | `true` | Set if the script should be loaded asynchronously. | -| `cleanup` | Boolean | No | `true` | Remove script tag after setup. | -| `crossOrigin` | String | No | `-` | Set script cross origin attribute such as "anonymous". | -| `scriptSource` | String | No | `https://js.hcaptcha.com/1/api.js` | Set script source URI. Takes precedence over `secureApi`. | -| `scriptLocation` | HTMLElement | No | `document.head` | Location of where to append the script tag. Make sure to add it to an area that will persist to prevent loading multiple times in the same document view. | -| `secureApi` | Boolean | No | `false` | See enterprise docs. | -| `apihost` | String | No | `-` | See enterprise docs. | -| `assethost` | String | No | `-` | See enterprise docs. | -| `endpoint` | String | No | `-` | See enterprise docs. | -| `hl` | String | No | `-` | See enterprise docs. | -| `host` | String | No | `-` | See enterprise docs. | -| `imghost` | String | No | `-` | See enterprise docs. | -| `recaptchacompat` | String | No | `-` | See enterprise docs. | -| `reportapi` | String | No | `-` | See enterprise docs. | -| `sentry` | Boolean | No | `-` | See enterprise docs. | -| `custom` | Boolean | No | `-` | See enterprise docs. | +| Name | Values/Type | Required | Default | Description | +|-------------------|-------------|----------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| `loadAsync` | Boolean | No | `true` | Set if the script should be loaded asynchronously. | +| `cleanup` | Boolean | No | `true` | Remove script tag after setup. | +| `crossOrigin` | String | No | `-` | Set script cross origin attribute such as "anonymous". | +| `scriptSource` | String | No | `https://js.hcaptcha.com/1/api.js` | Set script source URI. Takes precedence over `secureApi`. | +| `scriptLocation` | HTMLElement | No | `document.head` | Location of where to append the script tag. Make sure to add it to an area that will persist to prevent loading multiple times in the same document view. | +| `secureApi` | Boolean | No | `false` | See enterprise docs. | +| `apihost` | String | No | `-` | See enterprise docs. | +| `assethost` | String | No | `-` | See enterprise docs. | +| `endpoint` | String | No | `-` | See enterprise docs. | +| `hl` | String | No | `-` | See enterprise docs. | +| `host` | String | No | `-` | See enterprise docs. | +| `imghost` | String | No | `-` | See enterprise docs. | +| `recaptchacompat` | String | No | `-` | See enterprise docs. | +| `reportapi` | String | No | `-` | See enterprise docs. | +| `sentry` | Boolean | No | `-` | See enterprise docs. | +| `custom` | Boolean | No | `-` | See enterprise docs. | + + + +## Legacy Support +In order to support older browsers, a separate bundle is generated in which all ES6 code is compiled down to ES5 along with an optional polyfill bundle. + +- `polyfills.js`: Provides polyfills for features not supported in older browsers. +- `index.es5.js`: **@hcaptcha/loader** package compiled for ES5 environments. + +### Import Bundle(s) +Both bundles generated use IIFE format rather than a more modern import syntax such as `require` or `esm`. + +```js +// Optional polyfill import +import '@hCaptcha/loader/dist/polyfills.js'; +// ES5 version of hCaptcha Loader +import '@hCaptcha/loader/dist/index.es5.js'; + +hCaptchaLoader().then(function(hcaptcha) { + var element = document.createElement('div'); + // hCaptcha API is ready + hcaptcha.render(element, { + sitekey: 'YOUR_SITE_KEY', + // Additional options here + }); +}); + +``` +### TypeScript +To handle typescript with ES5 version, use the following statement. +```ts +declare global { + interface Window { + hCaptchaLoader: any; + } +} +``` + +### CDN +The hCaptcha Loader targeted for older browsers can also be imported via CDN by using UNPKG](https://www.unpkg.com/), see example below. + + +```html + + + + + + +
+ + + +``` diff --git a/lib/esbuild.config.js b/lib/esbuild.config.js index 571b433..3f06f13 100644 --- a/lib/esbuild.config.js +++ b/lib/esbuild.config.js @@ -3,6 +3,7 @@ import { fileURLToPath } from 'url'; import { build, context, analyzeMetafile } from 'esbuild'; import * as dotenv from 'dotenv'; +import swc from '@swc/core'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -44,6 +45,14 @@ const config = { sourcemap: BUILD === 'development', }; +const swcOptions = { + minify: true, + sourceMaps: BUILD === 'development', + jsc: { + target: 'es5', + }, +}; + if (WATCH) { const ctx = await context({ @@ -57,6 +66,7 @@ if (WATCH) { }); await ctx.watch(); } else { + // Transpile TypeScript to ESM const resultESM = await build({ ...config, format: 'esm', @@ -67,11 +77,46 @@ if (WATCH) { ] }); + // Transpile TypeScript to CommonJS const resultCJS = await build({ ...config, format: 'cjs', outfile: resolve(DIST, 'index.cjs'), - treeShaking: true + treeShaking: true, + }); + + // Transform to ES5 + const transformedESM = await swc.transformFile(resolve(DIST, 'index.mjs'), swcOptions); + + // Build ES5 bundle + const resultES5 = await build({ + ...config, + entryPoints: undefined, + globalName: 'hCaptchaLoaderPkg', + stdin: { + contents: transformedESM.code, + resolveDir: DIST, + sourcefile: 'index.es5.js', + }, + outfile: resolve(DIST, 'index.es5.js'), + footer: { + js: 'window.hCaptchaLoader = hCaptchaLoaderPkg.hCaptchaLoader;', + }, + treeShaking: true, + target: [ + 'es5', + ] + }); + + // Add Polyfills + await build({ + ...config, + entryPoints: [resolve(SRC, 'polyfills.ts')], + outfile: resolve(DIST, 'polyfills.js'), + treeShaking: true, + target: [ + 'es5', + ] }); if (DEBUG) { @@ -81,7 +126,12 @@ if (WATCH) { const analyzeCJS = await analyzeMetafile(resultCJS.metafile, { verbose: false }); + const analyzeES5 = await analyzeMetafile(resultES5.metafile, { + verbose: false + }); + console.log(analyzeESM); console.log(analyzeCJS); + console.log(analyzeES5); } } diff --git a/lib/package.json b/lib/package.json index 8cef576..baea3df 100644 --- a/lib/package.json +++ b/lib/package.json @@ -12,7 +12,8 @@ "test:unit": "jest" }, "dependencies": { - "@sentry/browser": "^7.73.0" + "@sentry/browser": "^7.73.0", + "core-js": "^3.35.1" }, "devDependencies": { "@hcaptcha/types": "^1.0.3", diff --git a/lib/src/loader.ts b/lib/src/loader.ts index 0e4b02f..83bad76 100644 --- a/lib/src/loader.ts +++ b/lib/src/loader.ts @@ -125,6 +125,6 @@ export async function loadScript(params, retries = 0) { } -export async function hCaptchaLoader(params) { +export async function hCaptchaLoader(params = {}) { return await loadScript(params); } diff --git a/lib/src/polyfills.ts b/lib/src/polyfills.ts new file mode 100644 index 0000000..b46d37b --- /dev/null +++ b/lib/src/polyfills.ts @@ -0,0 +1,4 @@ +import 'core-js/es/array/find'; +import 'core-js/es/object/assign'; +import 'core-js/es/object/entries'; +import 'core-js/es/object/get-own-property-descriptors'; diff --git a/lib/tsconfig.types.json b/lib/tsconfig.types.json index 35f4d01..8cf2a7b 100644 --- a/lib/tsconfig.types.json +++ b/lib/tsconfig.types.json @@ -13,5 +13,8 @@ "include": [ "src/**/*" + ], + "exclude": [ + "src/polyfills.ts" ] } diff --git a/package.json b/package.json index e84012b..89b6320 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@hcaptcha/loader", "description": "This is a JavaScript library to easily configure the loading of the hCaptcha JS client SDK with built-in error handling.", - "version": "1.2.1", + "version": "1.2.2", "author": "hCaptcha team and contributors", "license": "MIT", "keywords": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2433bb8..5065438 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + importers: .: @@ -43,6 +47,9 @@ importers: '@sentry/browser': specifier: ^7.73.0 version: 7.73.0 + core-js: + specifier: ^3.35.1 + version: 3.35.1 devDependencies: '@hcaptcha/types': specifier: ^1.0.3 @@ -2171,6 +2178,11 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true + /core-js@3.35.1: + resolution: {integrity: sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==} + requiresBuild: true + dev: false + /corser@2.0.1: resolution: {integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==} engines: {node: '>= 0.4.0'}