执行过npm install命令的vue-element-admin源码
康凯
2022-05-20 aa4c235a8ca67ea8b731f90c951a465e92c0a865
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
import forEachArray from '../collection/forEachArray';
import forEachOwnProperties from '../collection/forEachOwnProperties';
import extend from '../object/extend';
import isArray from '../type/isArray';
import isEmpty from '../type/isEmpty';
import isFunction from '../type/isFunction';
import isNull from '../type/isNull';
import isObject from '../type/isObject';
import isUndefined from '../type/isUndefined';
 
function encodePairs(key, value) {
  return `${encodeURIComponent(key)}=${encodeURIComponent(
    isNull(value) || isUndefined(value) ? '' : value
  )}`;
}
 
function serializeParams(key, value, serializedList) {
  if (isArray(value)) {
    forEachArray(value, (arrVal, index) => {
      serializeParams(`${key}[${isObject(arrVal) ? index : ''}]`, arrVal, serializedList);
    });
  } else if (isObject(value)) {
    forEachOwnProperties(value, (objValue, objKey) => {
      serializeParams(`${key}[${objKey}]`, objValue, serializedList);
    });
  } else {
    serializedList.push(encodePairs(key, value));
  }
}
 
/**
 * Serializer to serialize parameters
 * @callback ajax/serializer
 * @param {*} params - parameter to serialize
 * @returns {string} - serialized strings
 */
 
/**
 * Serializer
 *
 * 1. Array format
 *
 * The default array format to serialize is 'bracket'.
 * However in case of nested array, only the deepest format follows the 'bracket', the rest follow 'indice' format.
 *
 * - basic
 *   { a: [1, 2, 3] } => a[]=1&a[]=2&a[]=3
 * - nested
 *   { a: [1, 2, [3]] } => a[]=1&a[]=2&a[2][]=3
 *
 * 2. Object format
 *
 * The default object format to serialize is 'bracket' notation and doesn't allow the 'dot' notation.
 *
 * - basic
 *   { a: { b: 1, c: 2 } } => a[b]=1&a[c]=2
 *
 * @param {*} params - parameters to serialize
 * @returns {string}
 * @private
 */
function serialize(params) {
  if (!params || isEmpty(params)) {
    return '';
  }
  const serializedList = [];
  forEachOwnProperties(params, (value, key) => {
    serializeParams(key, value, serializedList);
  });
 
  return serializedList.join('&');
}
 
const getDefaultOptions = () => ({
  baseURL: '',
  headers: {
    common: {},
    get: {},
    post: {},
    put: {},
    delete: {},
    patch: {},
    options: {},
    head: {}
  },
  serializer: serialize
});
 
const HTTP_PROTOCOL_REGEXP = /^(http|https):\/\//i;
 
/**
 * Combine an absolute URL string (baseURL) and a relative URL string (url).
 * @param {string} baseURL - An absolute URL string
 * @param {string} url - An relative URL string
 * @returns {string}
 * @private
 */
function combineURL(baseURL, url) {
  if (HTTP_PROTOCOL_REGEXP.test(url)) {
    return url;
  }
 
  if (baseURL.slice(-1) === '/' && url.slice(0, 1) === '/') {
    url = url.slice(1);
  }
 
  return baseURL + url;
}
 
/**
 * Get merged options by its priorities.
 * defaults.common < defaults[method] < custom options
 * @param {Object} defaultOptions - The default options
 * @param {Object} customOptions - The custom options
 * @returns {Object}
 * @private
 */
function getComputedOptions(defaultOptions, customOptions) {
  const {
    baseURL,
    headers: defaultHeaders,
    serializer: defaultSerializer,
    beforeRequest: defaultBeforeRequest,
    success: defaultSuccess,
    error: defaultError,
    complete: defaultComplete
  } = defaultOptions;
  const {
    url,
    contentType,
    method,
    params,
    headers,
    serializer,
    beforeRequest,
    success,
    error,
    complete,
    withCredentials,
    mimeType
  } = customOptions;
 
  const options = {
    url: combineURL(baseURL, url),
    method,
    params,
    headers: extend(defaultHeaders.common, defaultHeaders[method.toLowerCase()], headers),
    serializer: serializer || defaultSerializer || serialize,
    beforeRequest: [defaultBeforeRequest, beforeRequest],
    success: [defaultSuccess, success],
    error: [defaultError, error],
    complete: [defaultComplete, complete],
    withCredentials,
    mimeType
  };
 
  options.contentType = contentType || options.headers['Content-Type'];
  delete options.headers['Content-Type'];
 
  return options;
}
 
function validateStatus(status) {
  return status >= 200 && status < 300;
}
 
function hasRequestBody(method) {
  return /^(?:POST|PUT|PATCH)$/.test(method.toUpperCase());
}
 
function executeCallback(callback, param) {
  if (isArray(callback)) {
    forEachArray(callback, fn => executeCallback(fn, param));
  } else if (isFunction(callback)) {
    callback(param);
  }
}
 
function parseHeaders(text) {
  const headers = {};
 
  forEachArray(text.split('\r\n'), header => {
    const [key, value] = header.split(': ');
 
    if (key !== '' && !isUndefined(value)) {
      headers[key] = value;
    }
  });
 
  return headers;
}
 
function parseJSONData(data) {
  let result = '';
  try {
    result = JSON.parse(data);
  } catch (_) {
    result = data;
  }
 
  return result;
}
 
const REQUEST_DONE = 4;
 
function handleReadyStateChange(xhr, options) {
  const { readyState } = xhr;
 
  // eslint-disable-next-line eqeqeq
  if (readyState != REQUEST_DONE) {
    return;
  }
 
  const { status, statusText, responseText } = xhr;
  const { success, resolve, error, reject, complete } = options;
 
  if (validateStatus(status)) {
    const contentType = xhr.getResponseHeader('Content-Type');
    let data = responseText;
 
    if (contentType && contentType.indexOf('application/json') > -1) {
      data = parseJSONData(data);
    }
 
    /**
     * successCallback is executed when the response is received successfully
     * @callback ajax/successCallback
     * @param {Object} response - success response wrapper
     * @param {number} response.status - response status code
     * @param {string} response.statusText - response status text
     * @param {*} response.data - response data. If its Content-Type is 'application/json', the parsed object will be passed.
     * @param {Object.<string,string>} response.headers - response headers
     */
    executeCallback([success, resolve], {
      status,
      statusText,
      data,
      headers: parseHeaders(xhr.getAllResponseHeaders())
    });
  } else {
    /**
     * errorCallback executed when the request failed
     * @callback ajax/errorCallback
     * @param {Object} response - error response wrapper
     * @param {number} response.status - response status code
     * @param {string} response.statusText - response status text
     */
    executeCallback([error, reject], { status, statusText });
  }
 
  /**
   * completeCallback executed when the request is completed after success or error callbacks are executed
   * @callback ajax/completeCallback
   * @param {Object} response - error response wrapper
   * @param {number} response.status - response status code
   * @param {string} response.statusText - response status text
   */
  executeCallback(complete, { status, statusText });
}
 
const QS_DELIM_REGEXP = /\?/;
 
function open(xhr, options) {
  const { url, method, serializer, params } = options;
 
  let requestUrl = url;
 
  if (!hasRequestBody(method) && params) {
    // serialize query string
    const qs = (QS_DELIM_REGEXP.test(url) ? '&' : '?') + serializer(params);
    requestUrl = `${url}${qs}`;
  }
 
  xhr.open(method, requestUrl);
}
 
function applyConfig(xhr, options) {
  const { method, contentType, mimeType, headers, withCredentials = false } = options;
 
  // set withCredentials (IE10+)
  if (withCredentials) {
    xhr.withCredentials = withCredentials;
  }
 
  // override MIME type (IE11+)
  if (mimeType) {
    xhr.overrideMimeType(mimeType);
  }
 
  forEachOwnProperties(headers, (value, header) => {
    if (!isObject(value)) {
      xhr.setRequestHeader(header, value);
    }
  });
 
  if (hasRequestBody(method)) {
    xhr.setRequestHeader('Content-Type', `${contentType}; charset=UTF-8`);
  }
 
  // set 'x-requested-with' header to prevent CSRF in old browser
  xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');
}
 
const ENCODED_SPACE_REGEXP = /%20/g;
 
function send(xhr, options) {
  const {
    method,
    serializer,
    beforeRequest,
    params = {},
    contentType = 'application/x-www-form-urlencoded'
  } = options;
 
  let body = null;
 
  if (hasRequestBody(method)) {
    // The space character '%20' is replaced to '+', because application/x-www-form-urlencoded follows rfc-1866
    body =
      contentType.indexOf('application/x-www-form-urlencoded') > -1
        ? serializer(params).replace(ENCODED_SPACE_REGEXP, '+')
        : JSON.stringify(params);
  }
 
  xhr.onreadystatechange = () => handleReadyStateChange(xhr, options);
 
  /**
   * beforeRequestCallback is executed before the Ajax request is sent
   * @callback ajax/beforeRequestCallback
   * @param {XMLHttpRequest} xhr - XMLHttpRequest object
   */
  executeCallback(beforeRequest, xhr);
  xhr.send(body);
}
 
/**
 * @module ajax
 * @description
 * A module for the Ajax request.
 * If the browser supports Promise, return the Promise object. If not, return null.
 * @param {Object} options - Options for the Ajax request
 * @param {string} options.url - URL string
 * @param {('GET'|'POST'|'PUT'|'DELETE'|'PATCH'|'OPTIONS'|'HEAD')} options.method - Method of the Ajax request
 * @param {Object.<string,string>} [options.headers] - Headers for the Ajax request
 * @param {string} [options.contentType] - Content-Type for the Ajax request. It is applied to POST, PUT, and PATCH requests only. Its encoding automatically sets to UTF-8.
 * @param {*} [options.params] - Parameters to send by the Ajax request
 * @param {serializer} [options.serializer] - {@link ajax_serializer Serializer} that determine how to serialize the parameters. Default serializer is {@link https://github.com/nhn/tui.code-snippet/tree/v2.3.0/ajax/index.mjs#L38 serialize()}.
 * @param {beforeRequestCallback} [options.beforeRequest] - {@link ajax_beforeRequestCallback beforeRequest callback} executed before the Ajax request is sent.
 * @param {successCallback} [options.success] - {@link ajax_successCallback success callback} executed when the response is received successfully.
 * @param {errorCallback} [options.error] - {@link ajax_errorCallback error callback} executed when the request failed.
 * @param {completeCallback} [options.complete] - {@link ajax_completeCallback complete callback} executed when the request is completed after success or error callbacks are executed.
 * @param {boolean} [options.withCredentials] - Determine whether cross-site Access-Control requests should be made using credentials or not. This option can be used on IE10+
 * @param {string} [options.mimeType] - Override the MIME type returned by the server. This options can be used on IE11+
 * @returns {?Promise} - If the browser supports Promise, return the Promise object. If not, return null.
 * @example
 * // ES6
 * import ajax from 'tui-code-snippet/ajax';
 *
 * // import transfiled file (IE8+)
 * import ajax from 'tui-code-snippet/ajax/index.js';
 *
 * // CommonJS
 * const ajax = require('tui-code-snippet/ajax/index.js');
 *
 * // If the browser supports Promise, return the Promise object
 * ajax({
 *   url: 'https://nhn.github.io/tui-code-snippet/',
 *   method: 'POST',
 *   contentType: 'application/json',
 *   params: {
 *     version: 'v2.3.0',
 *     author: 'NHN. FE Development Lab <dl_javascript@nhn.com>'
 *   },
 *   success: res => console.log(`success: ${res.status} ${res.statusText}`),
 *   error: res => console.log(`error: ${res.status} ${res.statusText}`)
 * }).then(res => console.log(`resolve: ${res.status} ${res.statusText}`))
 *   .catch(res => console.log(`reject: ${res.status} ${res.statusText}`));
 *
 * // If the request succeeds (200, OK)
 * // success: 200 OK
 * // resolve: 200 OK
 *
 * // If the request failed (503, Service Unavailable)
 * // error: 503 Service Unavailable
 * // reject: 503 Service Unavailable
 *
 * // If the browser does not support Promise, return null
 * ajax({
 *   url: 'https://ui.toast.com/fe-guide/',
 *   method: 'GET',
 *   contentType: 'application/json',
 *   params: {
 *     lang: 'en'
 *     title: 'PERFORMANCE',
 *   },
 *   success: res => console.log(`success: ${res.status} ${res.statusText}`),
 *   error: res => console.log(`error: ${res.status} ${res.statusText}`)
 * });
 *
 * // If the request succeeds (200, OK)
 * // success: 200 OK
 *
 * // If the request failed (503, Service Unavailable)
 * // error: 503 Service Unavailable
 */
function ajax(options) {
  const xhr = new XMLHttpRequest();
  const request = opts => forEachArray([open, applyConfig, send], fn => fn(xhr, opts));
 
  options = getComputedOptions(ajax.defaults, options);
 
  if (typeof Promise !== 'undefined') {
    return new Promise((resolve, reject) => {
      request(extend(options, { resolve, reject }));
    });
  }
 
  request(options);
 
  return null;
}
 
/**
 * Default configuration for the Ajax request.
 * @property {string} baseURL - baseURL appended with url of ajax options. If url is absolute, baseURL is ignored.
 * ex) baseURL = 'https://nhn.github.io', url = '/tui.code-snippet' => request is sent to 'https://nhn.github.io/tui.code-snippet'
 * ex) baseURL = 'https://nhn.github.io', url = 'https://ui.toast.com' => request is sent to 'https://ui.toast.com'
 * @property {Object} headers - request headers. It extends the header object in the following order: headers.common -> headers\[method\] -> headers in ajax options.
 * @property {Object.<string,string>} headers.common - Common headers regardless of the type of request
 * @property {Object.<string,string>} headers.get - Headers for the GET method
 * @property {Object.<string,string>} headers.post - Headers for the POST method
 * @property {Object.<string,string>} headers.put - Headers for the PUT method
 * @property {Object.<string,string>} headers.delete - Headers for the DELETE method
 * @property {Object.<string,string>} headers.patch - Headers for the PATCH method
 * @property {Object.<string,string>} headers.options - Headers for the OPTIONS method
 * @property {Object.<string,string>} headers.head - Headers for the HEAD method
 * @property {serializer} serializer - {@link ajax_serializer Serializer} that determine how to serialize the parameters. If serializer is specified in both default options and ajax options, use serializer in ajax options.
 * @property {beforeRequestCallback} beforeRequest - {@link ajax_beforeRequestCallback beforeRequest callback} executed before the Ajax request is sent. Callbacks in both default options and ajax options are executed, but default callbacks are called first.
 * @property {successCallback} success - {@link ajax_successCallback success callback} executed when the response is received successfully. Callbacks in both default options and ajax options are executed, but default callbacks are called first.
 * @property {errorCallback} error - {@link ajax_errorCallback error callback} executed when the request failed. Callbacks in both default options and ajax options are executed, but default callbacks are called first.
 * @property {completeCallback} complete - {@link ajax_completeCallback complete callback} executed when the request is completed after success or error callbacks are executed. Callbacks in both default options and ajax options are executed, but default callbacks are called first.
 * @example
 * ajax.defaults.baseURL = 'https://nhn.github.io/tui.code-snippet';
 * ajax.defaults.headers.common = {
 *   'Content-Type': 'application/json'
 * };
 * ajax.defaults.beforeRequest = () => showProgressBar();
 * ajax.defaults.complete = () => hideProgressBar();
 */
ajax.defaults = getDefaultOptions();
 
/**
 * Reset the default options
 * @private
 */
ajax._reset = function() {
  ajax.defaults = getDefaultOptions();
};
 
/**
 * Ajax request
 * @private
 */
ajax._request = function(url, method, options = {}) {
  return ajax(extend(options, { url, method }));
};
 
/**
 * Send the Ajax request by GET
 * @memberof module:ajax
 * @function get
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.get('https://nhn.github.io/tui.code-snippet/', {
 *   params: {
 *     version: 'v2.3.0'
 *   }
 * });
 */
 
/**
 * Send the Ajax request by POST
 * @memberof module:ajax
 * @function post
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.post('https://nhn.github.io/tui.code-snippet/', {
 *   contentType: 'application/json',
 *   params: {
 *     version: 'v2.3.0'
 *   }
 * });
 */
 
/**
 * Send the Ajax request by PUT
 * @memberof module:ajax
 * @function put
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.put('https://nhn.github.io/tui.code-snippet/v2.3.0', {
 *   success: ({status, statusText}) => alert(`success: ${status} ${statusText}`),
 *   error: ({status, statusText}) => alert(`error: ${status} ${statusText}`)
 * });
 */
 
/**
 * Send the Ajax request by DELETE
 * @memberof module:ajax
 * @function delete
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.delete('https://nhn.github.io/tui.code-snippet/v2.3.0');
 */
 
/**
 * Send the Ajax request by PATCH
 * @memberof module:ajax
 * @function patch
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.patch('https://nhn.github.io/tui.code-snippet/v2.3.0', {
 *   beforeRequest: () => showProgressBar(),
 *   complete: () => hideProgressBar()
 * });
 */
 
/**
 * Send the Ajax request by OPTIONS
 * @memberof module:ajax
 * @function options
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.head('https://nhn.github.io/tui.code-snippet/v2.3.0');
 */
 
/**
 * Send the Ajax request by HEAD
 * @memberof module:ajax
 * @function head
 * @param {string} url - URL string
 * @param {object} options - Options for the Ajax request. Refer to {@link ajax options of ajax()}.
 * @example
 * ajax.options('https://nhn.github.io/tui.code-snippet/v2.3.0');
 */
forEachArray(['get', 'post', 'put', 'delete', 'patch', 'options', 'head'], type => {
  ajax[type] = (url, options) => ajax._request(url, type.toUpperCase(), options);
});
 
export default ajax;