Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

better-jsonp

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

better-jsonp - npm Package Compare versions

Comparing version 1.1.1 to 1.1.2

lib/utils/types.ts

14

CHANGELOG.md

@@ -0,1 +1,11 @@

<a name="1.1.1"></a>
## [1.1.1](https://github.com/lbwa/jsonp/compare/v1.1.0...v1.1.1) (2018-08-17)
### Bug Fixes
* avoid global function named jsonp to reset unexpectedly ([98bf8a6](https://github.com/lbwa/jsonp/commit/98bf8a6))
<a name="1.1.0"></a>

@@ -23,3 +33,3 @@ # [1.1.0](https://github.com/lbwa/jsonp/compare/v1.0.0...v1.1.0) (2018-06-20)

* **lib/core/Jsonp.js lib/json.js samples/ publish:** implement Promise API, deprecate `prefix` ([090bbf3](https://github.com/lbwa/jsonp/commit/090bbf3))
* **lib/core/Jsonp.js lib/json.js samples/* publish.sh:** implement Promise API, deprecate `prefix` ([090bbf3](https://github.com/lbwa/jsonp/commit/090bbf3))

@@ -29,5 +39,5 @@

* **lib/core/Jsonp.js lib/json.js samples/ publish:** implement Promise API, deprecate `prefix` option and `callback` option
* **lib/core/Jsonp.js lib/json.js samples/* publish.sh:** implement Promise API, deprecate `prefix` option and `callback` option

149

dist/better-jsonp.js
/*!
* better-jsonp v1.1.0 Copyrights (c) 2018 Bowen (lbwa)
* better-jsonp v1.1.2 Copyrights (c) 2018 Bowen (lbwa)
* Released under the MIT License.

@@ -12,9 +12,2 @@ */

function noop() {}
function defineEnumerable(target, key, value) {
Reflect.defineProperty(target, key, {
enumerable: false,
writable: true,
value: value
});
}
function euc(value) {

@@ -24,43 +17,62 @@ return encodeURIComponent(value);

var defaultOptions = {
timeout: 6000,
prefix: 'callback',
callbackParams: 'jsonpCallback',
urlParams: {}
};
var PREFIX = 'callback';
var Jsonp = /** @class */function () {
function Jsonp(options) {
this.checkOptions(options);
this.initState(options);
this.encodeURL(options.url);
this.insertToElement(this._request);
function Jsonp(_a) {
var url = _a.url,
_b = _a.timeout,
timeout = _b === void 0 ? 6000 : _b,
_c = _a.jsonpCallback,
jsonpCallback = _c === void 0 ? "" + PREFIX + Date.now() : _c,
_d = _a.callbackParams,
callbackParams = _d === void 0 ? 'jsonpCallback' : _d,
_e = _a.urlParams,
urlParams = _e === void 0 ? {} : _e;
this.checkOptions({
url: url,
jsonpCallback: jsonpCallback
});
this.initState({
timeout: timeout,
jsonpCallback: jsonpCallback
});
this.encodeURL({
url: url,
callbackParams: callbackParams,
urlParams: urlParams
});
this.insert(this._url);
}
Jsonp.prototype.checkOptions = function (options) {
if (!options || !options.url) throw new Error('Please check your request url.');
Jsonp.prototype.checkOptions = function (_a) {
var url = _a.url,
jsonpCallback = _a.jsonpCallback;
if (!url) throw new Error('Please check your request url.');
// Every jsonp request will reset global request function named value of
// jsonpCallback, so this value MUST NOT be `jsonp`.
if (options.jsonpCallback === 'jsonp') throw new Error('Don\'t name jsonpCallback to `jsonp` for unexpected reset. Please use any non-jsonp value');
this.options = options;
// This checking only works in CDN installing, not as a dependency using
if (jsonpCallback === 'jsonp') throw new Error('Don\'t name jsonpCallback to `jsonp` for unexpected reset. Please use any non-jsonp value');
};
Jsonp.prototype.genJsonpCallback = function (options) {
if (options.jsonpCallback) {
this._jsonpCallback = options.jsonpCallback;
} else {
// prefix for callback name in global env
var prefix = defaultOptions.prefix;
// unique global callback name in global env
this._jsonpCallback = prefix + Date.now();
}
Jsonp.prototype.initState = function (_a) {
var timeout = _a.timeout,
jsonpCallback = _a.jsonpCallback;
this.createScript();
// unique response handler
this._jsonpCallback = jsonpCallback;
// keep behind setting this._jsonpCallback
this.handler = this.createHandler();
// set timer for limit request time
this.createTimer(timeout);
};
Jsonp.prototype.defineGlobalCallback = function () {
Jsonp.prototype.createScript = function () {
this._reference = document.getElementsByTagName('script')[0] || document.body.lastElementChild;
this._script = document.createElement('script');
};
/**
* 1. Request timer will be cleaned when response handler invoked.
* 2. use arrow function to keep `this` keywords value (Jsonp instance).
*/
Jsonp.prototype.createHandler = function () {
var _this = this;
/**
* 1. Once invoked window[this._jsonpCallback], it will clean timer for limiting
* request period and script element which is used to JSONP.
* 2. use arrow function to define `this` object value (Jsonp instance).
*/
return new Promise(function (resolve, reject) {
// handle 404/500 in response
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
_this._insertScript.onerror = function () {
_this._script.onerror = function () {
_this.cleanScript();

@@ -75,11 +87,9 @@ reject(new Error("Countdown has been clear! JSONP request unsuccessfully due to 404/500"));

};
Jsonp.prototype.genTimer = function (options) {
// create a request timer for limiting request period
Jsonp.prototype.createTimer = function (timeout) {
var _this = this;
// limit request period
var timeout = options.timeout || defaultOptions.timeout;
// use arrow function to define `this` object value (Jsonp instance).
if (timeout) {
this._timer = window.setTimeout(function () {
window[_this._jsonpCallback] = noop;
_this._timer = 0;
_this._timer = null;
_this.cleanScript();

@@ -90,45 +100,30 @@ throw new Error('JSONP request unsuccessfully (eg.timeout or wrong url).');

};
Jsonp.prototype.genScript = function () {
this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild;
this._insertScript = document.createElement('script');
};
Jsonp.prototype.initState = function (options) {
defineEnumerable(this, '_timer', null);
defineEnumerable(this, '_request', null);
defineEnumerable(this, '_jsonpCallback', null);
defineEnumerable(this, '_insertScript', null);
defineEnumerable(this, '_target', null);
this.genScript();
// set this._jsonpCallback
this.genJsonpCallback(options);
// invoke defineGlobalCallback after setting this._jsonpCallback
defineEnumerable(this, '_globalCallback', this.defineGlobalCallback());
// set timer for limit request time
this.genTimer(options);
};
Jsonp.prototype.encodeURL = function (url) {
Jsonp.prototype.encodeURL = function (_a) {
var url = _a.url,
callbackParams = _a.callbackParams,
urlParams = _a.urlParams;
// name of query parameter to specify the callback name
// eg. ?callback=...
var callbackParams = this.options.callbackParams || defaultOptions.callbackParams;
var id = euc(this._jsonpCallback);
url += "" + (url.indexOf('?') < 0 ? '?' : '&') + callbackParams + "=" + id;
// add other parameter to url excluding callback parameter
var params = this.options.urlParams || defaultOptions.urlParams;
var keys = Object.keys(params);
// add other parameters to url ending excluding callback name parameter
var keys = Object.keys(urlParams);
keys.forEach(function (key) {
var value = params[key] !== undefined ? params[key] : '';
var value = urlParams[key] !== undefined ? urlParams[key] : '';
url += "&" + key + "=" + euc(value);
});
this._request = url;
// converted request url
this._url = url;
};
// activate JSONP
Jsonp.prototype.insertToElement = function (url) {
this._insertScript.src = url;
this._target.parentNode.insertBefore(this._insertScript, this._target);
Jsonp.prototype.insert = function (url) {
this._script.src = url;
this._reference.parentNode.insertBefore(this._script, this._reference);
};
Jsonp.prototype.cleanScript = function () {
if (this._insertScript.parentNode) {
this._target.parentNode.removeChild(this._insertScript);
this._insertScript = null;
if (this._script.parentNode) {
this._reference.parentNode.removeChild(this._script);
this._script = null;
}
// reset response handler
window[this._jsonpCallback] = noop;

@@ -145,3 +140,3 @@ if (this._timer) window.clearTimeout(this._timer);

// from initState(options)
return jsonp._globalCallback;
return jsonp.handler;
}

@@ -148,0 +143,0 @@

/*!
* better-jsonp v1.1.0 Copyrights (c) 2018 Bowen (lbwa)
* better-jsonp v1.1.2 Copyrights (c) 2018 Bowen (lbwa)
* Released under the MIT License.
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.jsonp=e()}(this,function(){"use strict";function t(){}function e(t,e,n){Reflect.defineProperty(t,e,{enumerable:!1,writable:!0,value:n})}function n(t){return encodeURIComponent(t)}var i={timeout:6e3,prefix:"callback",callbackParams:"jsonpCallback",urlParams:{}},o=function(){function o(t){this.checkOptions(t),this.initState(t),this.encodeURL(t.url),this.insertToElement(this._request)}return o.prototype.checkOptions=function(t){if(!t||!t.url)throw new Error("Please check your request url.");if("jsonp"===t.jsonpCallback)throw new Error("Don't name jsonpCallback to `jsonp` for unexpected reset. Please use any non-jsonp value");this.options=t},o.prototype.genJsonpCallback=function(t){if(t.jsonpCallback)this._jsonpCallback=t.jsonpCallback;else{var e=i.prefix;this._jsonpCallback=e+Date.now()}},o.prototype.defineGlobalCallback=function(){var t=this;return new Promise(function(e,n){t._insertScript.onerror=function(){t.cleanScript(),n(new Error("Countdown has been clear! JSONP request unsuccessfully due to 404/500"))},window[t._jsonpCallback]=function(n){t.cleanScript(),e(n)}})},o.prototype.genTimer=function(e){var n=this,o=e.timeout||i.timeout;o&&(this._timer=window.setTimeout(function(){throw window[n._jsonpCallback]=t,n._timer=0,n.cleanScript(),new Error("JSONP request unsuccessfully (eg.timeout or wrong url).")},o))},o.prototype.genScript=function(){this._target=document.getElementsByTagName("script")[0]||document.body.lastElementChild,this._insertScript=document.createElement("script")},o.prototype.initState=function(t){e(this,"_timer",null),e(this,"_request",null),e(this,"_jsonpCallback",null),e(this,"_insertScript",null),e(this,"_target",null),this.genScript(),this.genJsonpCallback(t),e(this,"_globalCallback",this.defineGlobalCallback()),this.genTimer(t)},o.prototype.encodeURL=function(t){var e=this.options.callbackParams||i.callbackParams,o=n(this._jsonpCallback);t+=(t.indexOf("?")<0?"?":"&")+e+"="+o;var r=this.options.urlParams||i.urlParams;Object.keys(r).forEach(function(e){var i=void 0!==r[e]?r[e]:"";t+="&"+e+"="+n(i)}),this._request=t},o.prototype.insertToElement=function(t){this._insertScript.src=t,this._target.parentNode.insertBefore(this._insertScript,this._target)},o.prototype.cleanScript=function(){this._insertScript.parentNode&&(this._target.parentNode.removeChild(this._insertScript),this._insertScript=null),window[this._jsonpCallback]=t,this._timer&&window.clearTimeout(this._timer)},o}();return function(t){return new o(t)._globalCallback}});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.jsonp=t()}(this,function(){"use strict";function e(){}function t(e){return encodeURIComponent(e)}var n="callback",r=function(){function r(e){var t=e.url,r=e.timeout,o=void 0===r?6e3:r,i=e.jsonpCallback,c=void 0===i?""+n+Date.now():i,s=e.callbackParams,a=void 0===s?"jsonpCallback":s,l=e.urlParams,u=void 0===l?{}:l;this.checkOptions({url:t,jsonpCallback:c}),this.initState({timeout:o,jsonpCallback:c}),this.encodeURL({url:t,callbackParams:a,urlParams:u}),this.insert(this._url)}return r.prototype.checkOptions=function(e){var t=e.url,n=e.jsonpCallback;if(!t)throw new Error("Please check your request url.");if("jsonp"===n)throw new Error("Don't name jsonpCallback to `jsonp` for unexpected reset. Please use any non-jsonp value")},r.prototype.initState=function(e){var t=e.timeout,n=e.jsonpCallback;this.createScript(),this._jsonpCallback=n,this.handler=this.createHandler(),this.createTimer(t)},r.prototype.createScript=function(){this._reference=document.getElementsByTagName("script")[0]||document.body.lastElementChild,this._script=document.createElement("script")},r.prototype.createHandler=function(){var e=this;return new Promise(function(t,n){e._script.onerror=function(){e.cleanScript(),n(new Error("Countdown has been clear! JSONP request unsuccessfully due to 404/500"))},window[e._jsonpCallback]=function(n){e.cleanScript(),t(n)}})},r.prototype.createTimer=function(t){var n=this;t&&(this._timer=window.setTimeout(function(){throw window[n._jsonpCallback]=e,n._timer=null,n.cleanScript(),new Error("JSONP request unsuccessfully (eg.timeout or wrong url).")},t))},r.prototype.encodeURL=function(e){var n=e.url,r=e.callbackParams,o=e.urlParams,i=t(this._jsonpCallback);n+=(n.indexOf("?")<0?"?":"&")+r+"="+i,Object.keys(o).forEach(function(e){var r=void 0!==o[e]?o[e]:"";n+="&"+e+"="+t(r)}),this._url=n},r.prototype.insert=function(e){this._script.src=e,this._reference.parentNode.insertBefore(this._script,this._reference)},r.prototype.cleanScript=function(){this._script.parentNode&&(this._reference.parentNode.removeChild(this._script),this._script=null),window[this._jsonpCallback]=e,this._timer&&window.clearTimeout(this._timer)},r}();return function(e){return new r(e).handler}});

@@ -1,59 +0,84 @@

import { defaultOptions, options } from '../types/types.js'
import { noop, defineEnumerable, euc } from '../utils/index.js'
import { options } from '../utils/types'
import { noop, euc } from '../utils/index'
const defaultOptions: defaultOptions = {
timeout: 6000,
prefix: 'callback',
callbackParams: 'jsonpCallback',
urlParams: {}
}
const PREFIX = 'callback'
export default class Jsonp {
options: options
_url: string
_request: string
_jsonpCallback: string
_target: Element
_insertScript: HTMLScriptElement | null
_timer: number
_globalCallback: Promise<object>
constructor (options: options) {
this.checkOptions(options)
this.initState(options)
this.encodeURL(options.url)
this.insertToElement(this._request)
handler: Promise<object> // facade API based on error handler and response handler
private _url: string // converted url based on basic url and other params
private _jsonpCallback: string // response handler
private _reference: Element // reference element
private _script: HTMLScriptElement | null // trigger element
private _timer: number // timer ID
constructor ({
url,
timeout = 6000,
jsonpCallback = `${PREFIX}${Date.now()}`,
callbackParams = 'jsonpCallback',
urlParams = {}
}: options) {
this.checkOptions({
url,
jsonpCallback
})
this.initState({
timeout,
jsonpCallback
})
this.encodeURL({
url,
callbackParams,
urlParams
})
this.insert(this._url)
}
checkOptions (options: options) {
if (!options || !options.url) throw new Error('Please check your request url.')
checkOptions ({
url,
jsonpCallback
}: options) {
if (!url) throw new Error('Please check your request url.')
// Every jsonp request will reset global request function named value of
// jsonpCallback, so this value MUST NOT be `jsonp`.
if (options.jsonpCallback === 'jsonp') throw new Error('Don\'t name jsonpCallback to `jsonp` for unexpected reset. Please use any non-jsonp value')
this.options = options
// This checking only works in CDN installing, not as a dependency using
if (jsonpCallback === 'jsonp') throw new Error('Don\'t name jsonpCallback to `jsonp` for unexpected reset. Please use any non-jsonp value')
}
genJsonpCallback (options: options) {
if (options.jsonpCallback) {
this._jsonpCallback = options.jsonpCallback
} else {
// prefix for callback name in global env
const prefix = defaultOptions.prefix
initState ({
timeout,
jsonpCallback
}: {
timeout: options['timeout']
jsonpCallback: options['jsonpCallback']
}) {
this.createScript()
// unique global callback name in global env
this._jsonpCallback = prefix + Date.now()
}
// unique response handler
this._jsonpCallback = jsonpCallback
// keep behind setting this._jsonpCallback
this.handler = this.createHandler()
// set timer for limit request time
this.createTimer(timeout)
}
defineGlobalCallback () {
/**
* 1. Once invoked window[this._jsonpCallback], it will clean timer for limiting
* request period and script element which is used to JSONP.
* 2. use arrow function to define `this` object value (Jsonp instance).
*/
createScript () {
this._reference = document.getElementsByTagName('script')[0]
|| document.body.lastElementChild
this._script = document.createElement('script')
}
/**
* 1. Request timer will be cleaned when response handler invoked.
* 2. use arrow function to keep `this` keywords value (Jsonp instance).
*/
createHandler () {
return new Promise((resolve, reject) => {
// handle 404/500 in response
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
this._insertScript.onerror = () => {
this._script.onerror = () => {
this.cleanScript()

@@ -70,11 +95,8 @@ reject(new Error(`Countdown has been clear! JSONP request unsuccessfully due to 404/500`))

genTimer (options: options) {
// limit request period
const timeout = options.timeout || defaultOptions.timeout
// use arrow function to define `this` object value (Jsonp instance).
// create a request timer for limiting request period
createTimer (timeout: options['timeout']) {
if (timeout) {
this._timer = window.setTimeout(() => {
(<any>window)[this._jsonpCallback] = noop
this._timer = 0
this._timer = null
this.cleanScript()

@@ -86,56 +108,36 @@ throw new Error('JSONP request unsuccessfully (eg.timeout or wrong url).')

genScript () {
this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild
this._insertScript = document.createElement('script')
}
initState (options: options) {
defineEnumerable(this, '_timer', null)
defineEnumerable(this, '_request', null)
defineEnumerable(this, '_jsonpCallback', null)
defineEnumerable(this, '_insertScript', null)
defineEnumerable(this, '_target', null)
this.genScript()
// set this._jsonpCallback
this.genJsonpCallback(options)
// invoke defineGlobalCallback after setting this._jsonpCallback
defineEnumerable(this, '_globalCallback', this.defineGlobalCallback())
// set timer for limit request time
this.genTimer(options)
}
encodeURL (url: string) {
encodeURL ({
url,
callbackParams,
urlParams
}: options) {
// name of query parameter to specify the callback name
// eg. ?callback=...
const callbackParams = this.options.callbackParams || defaultOptions.callbackParams
const id = euc(this._jsonpCallback)
url += `${url.indexOf('?') < 0 ? '?' : '&'}${callbackParams}=${id}`
// add other parameter to url excluding callback parameter
const params = this.options.urlParams || defaultOptions.urlParams
const keys = Object.keys(params)
// add other parameters to url ending excluding callback name parameter
const keys = Object.keys(urlParams)
keys.forEach(key => {
const value = params[key] !== undefined ? params[key] : ''
const value = urlParams[key] !== undefined ? urlParams[key] : ''
url += `&${key}=${euc(value)}`
})
this._request = url
// converted request url
this._url = url
}
// activate JSONP
insertToElement (url: string) {
this._insertScript.src = url
this._target.parentNode.insertBefore(this._insertScript, this._target)
insert (url: string) {
this._script.src = url
this._reference.parentNode.insertBefore(this._script, this._reference)
}
cleanScript () {
if (this._insertScript.parentNode) {
this._target.parentNode.removeChild(this._insertScript)
this._insertScript = null
if (this._script.parentNode) {
this._reference.parentNode.removeChild(this._script)
this._script = null
}
// reset response handler
(<any>window)[this._jsonpCallback] = noop

@@ -142,0 +144,0 @@ if (this._timer) window.clearTimeout(this._timer)

import Jsonp from './core/Jsonp'
import { options } from './types/types'
import { options } from './utils/types'

@@ -10,5 +10,5 @@ // facade in facade pattern

// from initState(options)
return jsonp._globalCallback
return jsonp.handler
}
export default createInstance
export function noop () {}
export function defineEnumerable (target: object, key: string, value: any) {
Reflect.defineProperty(target, key, {
enumerable: false,
writable: true,
value
})
}
export function euc (value: string): string {
return encodeURIComponent(value)
}
{
"name": "better-jsonp",
"version": "1.1.1",
"version": "1.1.2",
"description": "A simple JSONP implementation",

@@ -23,3 +23,3 @@ "main": "dist/better-jsonp.min.js",

"commit": "yarn run lint && yarn run build && git add . && git-cz",
"changelog": "npx conventional-changelog -p angular -i CHANGELOG.md -s -v"
"changelog": "npx conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
},

@@ -26,0 +26,0 @@ "repository": {

@@ -54,10 +54,14 @@ # Better JSONP [![npm](https://img.shields.io/npm/v/better-jsonp.svg)](https://www.npmjs.com/package/better-jsonp) [![Build Status](https://travis-ci.org/lbwa/jsonp.svg?branch=master)](https://travis-ci.org/lbwa/jsonp) [![npm](https://img.shields.io/npm/dt/better-jsonp.svg)](https://github.com/lbwa/jsonp)

- The code below show you how to use package as a dependency
```js
// as a dependency
// as a request dependency named jsonp
import jsonp from 'better-jsonp'
```
```js
jsonp({
url: 'http://localhost',
// global function named `${jsonpCallback}` will be invoked when JSONP response
jsonpCallback: 'jsonpCallback', // any non-jsonp value
jsonpCallback: 'jsonpCallback', // any different name from request module
timeout: 5000,

@@ -76,4 +80,17 @@ // eg. ?customCallbackParams=...

⚠️ ***Notice***: Parameter `jsonpCallback` ***MUST NOT*** be `'jsonp'`, otherwise `jsonp` module only work once and function named value of parameter `jsonpCallback` will be reset to `null` which means global function `jsonp` will be reset unexpectedly.
⚠️ ***Notice***: Parameter `jsonpCallback` value ***MUST NOT*** be same as request module name (eg. dependency named `jsonp` above code), otherwise request module only works once and function named value of parameter `jsonpCallback` will be reset to `null` (internal implementation) which means the same name request module will be also reset unexpectedly.
- You can also invoke function named `jsonp` directly in global environment if you have installed package from CDN.
```js
jsonp({
// custom configuration
})
```
⚠️ ***Notice***: For same reason, parameter `jsonpCallback` value ***MUST NOT*** be `jsonp`.
## Parameters
| options parameter | type | required | description |

@@ -87,3 +104,3 @@ | ----------------- | ---- | -------- | ----------- |

## Notice
## Notice ⚠️

@@ -90,0 +107,0 @@ - `Uncaught SyntaxError: Unexpected token :`error

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc