vite-plugin-php 2.0.3 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +132 -65
  2. package/dist/index.cjs +3589 -378
  3. package/dist/index.mjs +3584 -374
  4. package/package.json +11 -13
package/dist/index.mjs CHANGED
@@ -1,16 +1,17 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { fileURLToPath } from 'url';
2
+ import { fileURLToPath } from 'node:url';
3
3
  import { resolve, dirname, relative } from 'node:path';
4
- import tcpPortUsed from 'tcp-port-used';
5
- import require$$0 from 'os';
6
- import require$$0$1 from 'path';
7
- import require$$0$2 from 'util';
8
- import require$$0$3 from 'stream';
9
- import require$$0$5 from 'events';
10
- import require$$0$4 from 'fs';
4
+ import require$$1 from 'net';
5
+ import require$$0 from 'util';
6
+ import require$$0$1 from 'tty';
7
+ import require$$0$2 from 'os';
8
+ import require$$0$3 from 'path';
9
+ import require$$0$4 from 'stream';
10
+ import require$$0$6 from 'events';
11
+ import require$$0$5 from 'fs';
11
12
  import { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'node:fs';
12
- import http from 'node:http';
13
13
  import { normalizePath } from 'vite';
14
+ import http from 'node:http';
14
15
 
15
16
  const EPHPError = {
16
17
  ERROR: 1,
@@ -33,6 +34,7 @@ const EPHPError = {
33
34
 
34
35
  const internalParam = "__314159265359__";
35
36
  const shared = {
37
+ projectRoot: process.cwd(),
36
38
  viteConfig: void 0,
37
39
  devConfig: {
38
40
  cleanup: true,
@@ -48,6 +50,31 @@ function getDefaultExportFromCjs (x) {
48
50
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
49
51
  }
50
52
 
53
+ function getAugmentedNamespace(n) {
54
+ if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n;
55
+ var f = n.default;
56
+ if (typeof f == "function") {
57
+ var a = function a () {
58
+ if (this instanceof a) {
59
+ return Reflect.construct(f, arguments, this.constructor);
60
+ }
61
+ return f.apply(this, arguments);
62
+ };
63
+ a.prototype = f.prototype;
64
+ } else a = {};
65
+ Object.defineProperty(a, '__esModule', {value: true});
66
+ Object.keys(n).forEach(function (k) {
67
+ var d = Object.getOwnPropertyDescriptor(n, k);
68
+ Object.defineProperty(a, k, d.get ? d : {
69
+ enumerable: true,
70
+ get: function () {
71
+ return n[k];
72
+ }
73
+ });
74
+ });
75
+ return a;
76
+ }
77
+
51
78
  var picocolors = {exports: {}};
52
79
 
53
80
  var hasRequiredPicocolors;
@@ -76,130 +103,3156 @@ function requirePicocolors () {
76
103
  return result + string.substring(cursor)
77
104
  };
78
105
 
79
- let createColors = (enabled = isColorSupported) => {
80
- let f = enabled ? formatter : () => String;
81
- return {
82
- isColorSupported: enabled,
83
- reset: f("\x1b[0m", "\x1b[0m"),
84
- bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"),
85
- dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"),
86
- italic: f("\x1b[3m", "\x1b[23m"),
87
- underline: f("\x1b[4m", "\x1b[24m"),
88
- inverse: f("\x1b[7m", "\x1b[27m"),
89
- hidden: f("\x1b[8m", "\x1b[28m"),
90
- strikethrough: f("\x1b[9m", "\x1b[29m"),
106
+ let createColors = (enabled = isColorSupported) => {
107
+ let f = enabled ? formatter : () => String;
108
+ return {
109
+ isColorSupported: enabled,
110
+ reset: f("\x1b[0m", "\x1b[0m"),
111
+ bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"),
112
+ dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"),
113
+ italic: f("\x1b[3m", "\x1b[23m"),
114
+ underline: f("\x1b[4m", "\x1b[24m"),
115
+ inverse: f("\x1b[7m", "\x1b[27m"),
116
+ hidden: f("\x1b[8m", "\x1b[28m"),
117
+ strikethrough: f("\x1b[9m", "\x1b[29m"),
118
+
119
+ black: f("\x1b[30m", "\x1b[39m"),
120
+ red: f("\x1b[31m", "\x1b[39m"),
121
+ green: f("\x1b[32m", "\x1b[39m"),
122
+ yellow: f("\x1b[33m", "\x1b[39m"),
123
+ blue: f("\x1b[34m", "\x1b[39m"),
124
+ magenta: f("\x1b[35m", "\x1b[39m"),
125
+ cyan: f("\x1b[36m", "\x1b[39m"),
126
+ white: f("\x1b[37m", "\x1b[39m"),
127
+ gray: f("\x1b[90m", "\x1b[39m"),
128
+
129
+ bgBlack: f("\x1b[40m", "\x1b[49m"),
130
+ bgRed: f("\x1b[41m", "\x1b[49m"),
131
+ bgGreen: f("\x1b[42m", "\x1b[49m"),
132
+ bgYellow: f("\x1b[43m", "\x1b[49m"),
133
+ bgBlue: f("\x1b[44m", "\x1b[49m"),
134
+ bgMagenta: f("\x1b[45m", "\x1b[49m"),
135
+ bgCyan: f("\x1b[46m", "\x1b[49m"),
136
+ bgWhite: f("\x1b[47m", "\x1b[49m"),
137
+
138
+ blackBright: f("\x1b[90m", "\x1b[39m"),
139
+ redBright: f("\x1b[91m", "\x1b[39m"),
140
+ greenBright: f("\x1b[92m", "\x1b[39m"),
141
+ yellowBright: f("\x1b[93m", "\x1b[39m"),
142
+ blueBright: f("\x1b[94m", "\x1b[39m"),
143
+ magentaBright: f("\x1b[95m", "\x1b[39m"),
144
+ cyanBright: f("\x1b[96m", "\x1b[39m"),
145
+ whiteBright: f("\x1b[97m", "\x1b[39m"),
146
+
147
+ bgBlackBright: f("\x1b[100m", "\x1b[49m"),
148
+ bgRedBright: f("\x1b[101m", "\x1b[49m"),
149
+ bgGreenBright: f("\x1b[102m", "\x1b[49m"),
150
+ bgYellowBright: f("\x1b[103m", "\x1b[49m"),
151
+ bgBlueBright: f("\x1b[104m", "\x1b[49m"),
152
+ bgMagentaBright: f("\x1b[105m", "\x1b[49m"),
153
+ bgCyanBright: f("\x1b[106m", "\x1b[49m"),
154
+ bgWhiteBright: f("\x1b[107m", "\x1b[49m"),
155
+ }
156
+ };
157
+
158
+ picocolors.exports = createColors();
159
+ picocolors.exports.createColors = createColors;
160
+ return picocolors.exports;
161
+ }
162
+
163
+ var picocolorsExports = /*@__PURE__*/ requirePicocolors();
164
+ const colors = /*@__PURE__*/getDefaultExportFromCjs(picocolorsExports);
165
+
166
+ function hasViteConfig(input) {
167
+ if (!input) {
168
+ throw new Error("Vite config not initialized!");
169
+ }
170
+ }
171
+
172
+ function log(message, { type = "info", prefix = true, ...options } = {}) {
173
+ hasViteConfig(shared.viteConfig);
174
+ let output = "";
175
+ if (prefix) {
176
+ output += colors.bgMagenta(colors.white("\u2009php\u2009")) + " ";
177
+ }
178
+ output += message;
179
+ shared.viteConfig.logger[type](output, options);
180
+ }
181
+ log.error = function(json, options = {}) {
182
+ let output = json;
183
+ let type = "info";
184
+ try {
185
+ const data = JSON.parse(json);
186
+ output = "";
187
+ switch (data.code) {
188
+ case EPHPError.PARSE:
189
+ case EPHPError.ERROR:
190
+ case EPHPError.CORE_ERROR:
191
+ case EPHPError.COMPILE_ERROR:
192
+ case EPHPError.USER_ERROR:
193
+ type = "error";
194
+ output += colors.bgRedBright(colors.white("Fatal Error"));
195
+ break;
196
+ case EPHPError.WARNING:
197
+ case EPHPError.USER_WARNING:
198
+ case EPHPError.COMPILE_WARNING:
199
+ case EPHPError.RECOVERABLE_ERROR:
200
+ type = "warn";
201
+ output += colors.yellowBright("Warning");
202
+ break;
203
+ case EPHPError.NOTICE:
204
+ case EPHPError.USER_NOTICE:
205
+ type = "info";
206
+ output += colors.bgWhite(colors.black("Notice"));
207
+ break;
208
+ case EPHPError.STRICT:
209
+ type = "info";
210
+ output += colors.yellow("Strict");
211
+ break;
212
+ case EPHPError.DEPRECATED:
213
+ case EPHPError.USER_DEPRECATED:
214
+ type = "info";
215
+ output += colors.cyan("Deprecated");
216
+ break;
217
+ default:
218
+ break;
219
+ }
220
+ output += " " + data.message + "\r\n";
221
+ output += " In: " + data.file.replace(
222
+ resolve(shared.tempDir),
223
+ shared.viteConfig?.root
224
+ ) + "\r\n";
225
+ output += " On line: " + data.line;
226
+ } catch (error) {
227
+ }
228
+ log(output, { ...options, type });
229
+ };
230
+
231
+ var tcpPortUsed$1 = {};
232
+
233
+ var is2 = {};
234
+
235
+ var deepIs = {exports: {}};
236
+
237
+ var hasRequiredDeepIs;
238
+
239
+ function requireDeepIs () {
240
+ if (hasRequiredDeepIs) return deepIs.exports;
241
+ hasRequiredDeepIs = 1;
242
+ var pSlice = Array.prototype.slice;
243
+ var Object_keys = typeof Object.keys === 'function'
244
+ ? Object.keys
245
+ : function (obj) {
246
+ var keys = [];
247
+ for (var key in obj) keys.push(key);
248
+ return keys;
249
+ }
250
+ ;
251
+
252
+ var deepEqual = deepIs.exports = function (actual, expected) {
253
+ // enforce Object.is +0 !== -0
254
+ if (actual === 0 && expected === 0) {
255
+ return areZerosEqual(actual, expected);
256
+
257
+ // 7.1. All identical values are equivalent, as determined by ===.
258
+ } else if (actual === expected) {
259
+ return true;
260
+
261
+ } else if (actual instanceof Date && expected instanceof Date) {
262
+ return actual.getTime() === expected.getTime();
263
+
264
+ } else if (isNumberNaN(actual)) {
265
+ return isNumberNaN(expected);
266
+
267
+ // 7.3. Other pairs that do not both pass typeof value == 'object',
268
+ // equivalence is determined by ==.
269
+ } else if (typeof actual != 'object' && typeof expected != 'object') {
270
+ return actual == expected;
271
+
272
+ // 7.4. For all other Object pairs, including Array objects, equivalence is
273
+ // determined by having the same number of owned properties (as verified
274
+ // with Object.prototype.hasOwnProperty.call), the same set of keys
275
+ // (although not necessarily the same order), equivalent values for every
276
+ // corresponding key, and an identical 'prototype' property. Note: this
277
+ // accounts for both named and indexed properties on Arrays.
278
+ } else {
279
+ return objEquiv(actual, expected);
280
+ }
281
+ };
282
+
283
+ function isUndefinedOrNull(value) {
284
+ return value === null || value === undefined;
285
+ }
286
+
287
+ function isArguments(object) {
288
+ return Object.prototype.toString.call(object) == '[object Arguments]';
289
+ }
290
+
291
+ function isNumberNaN(value) {
292
+ // NaN === NaN -> false
293
+ return typeof value == 'number' && value !== value;
294
+ }
295
+
296
+ function areZerosEqual(zeroA, zeroB) {
297
+ // (1 / +0|0) -> Infinity, but (1 / -0) -> -Infinity and (Infinity !== -Infinity)
298
+ return (1 / zeroA) === (1 / zeroB);
299
+ }
300
+
301
+ function objEquiv(a, b) {
302
+ if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
303
+ return false;
304
+
305
+ // an identical 'prototype' property.
306
+ if (a.prototype !== b.prototype) return false;
307
+ //~~~I've managed to break Object.keys through screwy arguments passing.
308
+ // Converting to array solves the problem.
309
+ if (isArguments(a)) {
310
+ if (!isArguments(b)) {
311
+ return false;
312
+ }
313
+ a = pSlice.call(a);
314
+ b = pSlice.call(b);
315
+ return deepEqual(a, b);
316
+ }
317
+ try {
318
+ var ka = Object_keys(a),
319
+ kb = Object_keys(b),
320
+ key, i;
321
+ } catch (e) {//happens when one is a string literal and the other isn't
322
+ return false;
323
+ }
324
+ // having the same number of owned properties (keys incorporates
325
+ // hasOwnProperty)
326
+ if (ka.length != kb.length)
327
+ return false;
328
+ //the same set of keys (although not necessarily the same order),
329
+ ka.sort();
330
+ kb.sort();
331
+ //~~~cheap key test
332
+ for (i = ka.length - 1; i >= 0; i--) {
333
+ if (ka[i] != kb[i])
334
+ return false;
335
+ }
336
+ //equivalent values for every corresponding key, and
337
+ //~~~possibly expensive deep test
338
+ for (i = ka.length - 1; i >= 0; i--) {
339
+ key = ka[i];
340
+ if (!deepEqual(a[key], b[key])) return false;
341
+ }
342
+ return true;
343
+ }
344
+ return deepIs.exports;
345
+ }
346
+
347
+ var ipRegex;
348
+ var hasRequiredIpRegex;
349
+
350
+ function requireIpRegex () {
351
+ if (hasRequiredIpRegex) return ipRegex;
352
+ hasRequiredIpRegex = 1;
353
+
354
+ const word = '[a-fA-F\\d:]';
355
+ const b = options => options && options.includeBoundaries ?
356
+ `(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))` :
357
+ '';
358
+
359
+ const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}';
360
+
361
+ const v6seg = '[a-fA-F\\d]{1,4}';
362
+ const v6 = `
363
+ (?:
364
+ (?:${v6seg}:){7}(?:${v6seg}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8
365
+ (?:${v6seg}:){6}(?:${v4}|:${v6seg}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4
366
+ (?:${v6seg}:){5}(?::${v4}|(?::${v6seg}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4
367
+ (?:${v6seg}:){4}(?:(?::${v6seg}){0,1}:${v4}|(?::${v6seg}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4
368
+ (?:${v6seg}:){3}(?:(?::${v6seg}){0,2}:${v4}|(?::${v6seg}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4
369
+ (?:${v6seg}:){2}(?:(?::${v6seg}){0,3}:${v4}|(?::${v6seg}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4
370
+ (?:${v6seg}:){1}(?:(?::${v6seg}){0,4}:${v4}|(?::${v6seg}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4
371
+ (?::(?:(?::${v6seg}){0,5}:${v4}|(?::${v6seg}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4
372
+ )(?:%[0-9a-zA-Z]{1,})? // %eth0 %1
373
+ `.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim();
374
+
375
+ // Pre-compile only the exact regexes because adding a global flag make regexes stateful
376
+ const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`);
377
+ const v4exact = new RegExp(`^${v4}$`);
378
+ const v6exact = new RegExp(`^${v6}$`);
379
+
380
+ const ip = options => options && options.exact ?
381
+ v46Exact :
382
+ new RegExp(`(?:${b(options)}${v4}${b(options)})|(?:${b(options)}${v6}${b(options)})`, 'g');
383
+
384
+ ip.v4 = options => options && options.exact ? v4exact : new RegExp(`${b(options)}${v4}${b(options)}`, 'g');
385
+ ip.v6 = options => options && options.exact ? v6exact : new RegExp(`${b(options)}${v6}${b(options)}`, 'g');
386
+
387
+ ipRegex = ip;
388
+ return ipRegex;
389
+ }
390
+
391
+ const name = "is2";
392
+ const version = "2.0.9";
393
+ const description = "A type checking library where each exported function returns either true or false and does not throw. Also added tests.";
394
+ const license = "MIT";
395
+ const tags = [
396
+ "type",
397
+ "check",
398
+ "checker",
399
+ "checking",
400
+ "utilities",
401
+ "network",
402
+ "networking",
403
+ "credit",
404
+ "card",
405
+ "validation"
406
+ ];
407
+ const keywords = [
408
+ "type",
409
+ "check",
410
+ "checker",
411
+ "checking",
412
+ "utilities",
413
+ "network",
414
+ "networking",
415
+ "credit",
416
+ "card",
417
+ "validation"
418
+ ];
419
+ const author = "Enrico Marino <enrico.marino@email.com>";
420
+ const maintainers = "Edmond Meinfelder <edmond@stdarg.com>, Chris Oyler <christopher.oyler@gmail.com>";
421
+ const homepage = "http://github.com/stdarg/is2";
422
+ const repository = {
423
+ type: "git",
424
+ url: "git@github.com:stdarg/is2.git"
425
+ };
426
+ const bugs = {
427
+ url: "http://github.com/stdarg/is/issues"
428
+ };
429
+ const main = "./index.js";
430
+ const scripts = {
431
+ test: "./node_modules/.bin/mocha -C --reporter list tests.js"
432
+ };
433
+ const engines = {
434
+ node: ">=v0.10.0"
435
+ };
436
+ const dependencies = {
437
+ "deep-is": "^0.1.3",
438
+ "ip-regex": "^4.1.0",
439
+ "is-url": "^1.2.4"
440
+ };
441
+ const devDependencies = {
442
+ mocha: "6.2.3",
443
+ mongodb: "3.2.4"
444
+ };
445
+ const _package = {
446
+ name: name,
447
+ version: version,
448
+ description: description,
449
+ license: license,
450
+ tags: tags,
451
+ keywords: keywords,
452
+ author: author,
453
+ maintainers: maintainers,
454
+ homepage: homepage,
455
+ repository: repository,
456
+ bugs: bugs,
457
+ main: main,
458
+ scripts: scripts,
459
+ engines: engines,
460
+ dependencies: dependencies,
461
+ devDependencies: devDependencies
462
+ };
463
+
464
+ const _package$1 = {
465
+ __proto__: null,
466
+ author: author,
467
+ bugs: bugs,
468
+ default: _package,
469
+ dependencies: dependencies,
470
+ description: description,
471
+ devDependencies: devDependencies,
472
+ engines: engines,
473
+ homepage: homepage,
474
+ keywords: keywords,
475
+ license: license,
476
+ main: main,
477
+ maintainers: maintainers,
478
+ name: name,
479
+ repository: repository,
480
+ scripts: scripts,
481
+ tags: tags,
482
+ version: version
483
+ };
484
+
485
+ const require$$2 = /*@__PURE__*/getAugmentedNamespace(_package$1);
486
+
487
+ var isUrl_1;
488
+ var hasRequiredIsUrl;
489
+
490
+ function requireIsUrl () {
491
+ if (hasRequiredIsUrl) return isUrl_1;
492
+ hasRequiredIsUrl = 1;
493
+ /**
494
+ * Expose `isUrl`.
495
+ */
496
+
497
+ isUrl_1 = isUrl;
498
+
499
+ /**
500
+ * RegExps.
501
+ * A URL must match #1 and then at least one of #2/#3.
502
+ * Use two levels of REs to avoid REDOS.
503
+ */
504
+
505
+ var protocolAndDomainRE = /^(?:\w+:)?\/\/(\S+)$/;
506
+
507
+ var localhostDomainRE = /^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/;
508
+ var nonLocalhostDomainRE = /^[^\s\.]+\.\S{2,}$/;
509
+
510
+ /**
511
+ * Loosely validate a URL `string`.
512
+ *
513
+ * @param {String} string
514
+ * @return {Boolean}
515
+ */
516
+
517
+ function isUrl(string){
518
+ if (typeof string !== 'string') {
519
+ return false;
520
+ }
521
+
522
+ var match = string.match(protocolAndDomainRE);
523
+ if (!match) {
524
+ return false;
525
+ }
526
+
527
+ var everythingAfterProtocol = match[1];
528
+ if (!everythingAfterProtocol) {
529
+ return false;
530
+ }
531
+
532
+ if (localhostDomainRE.test(everythingAfterProtocol) ||
533
+ nonLocalhostDomainRE.test(everythingAfterProtocol)) {
534
+ return true;
535
+ }
536
+
537
+ return false;
538
+ }
539
+ return isUrl_1;
540
+ }
541
+
542
+ /**
543
+ * @fileOverview
544
+ * is2 derived from is by Enrico Marino, adapted for Node.js.
545
+ * Slightly modified by Edmond Meinfelder
546
+ *
547
+ * is
548
+ * the definitive JavaScript type testing library
549
+ * Copyright(c) 2013,2014 Edmond Meinfelder <edmond@stdarg.com>
550
+ * Copyright(c) 2011 Enrico Marino <enrico.marino@email.com>
551
+ * MIT license
552
+ */
553
+
554
+ var hasRequiredIs2;
555
+
556
+ function requireIs2 () {
557
+ if (hasRequiredIs2) return is2;
558
+ hasRequiredIs2 = 1;
559
+ (function (exports) {
560
+ const owns = {}.hasOwnProperty;
561
+ const toString = {}.toString;
562
+ const is = exports;
563
+ const deepIs = requireDeepIs();
564
+ const ipRegEx = requireIpRegex();
565
+ is.version = require$$2.version;
566
+
567
+ ////////////////////////////////////////////////////////////////////////////////
568
+ // Environment
569
+
570
+ /**
571
+ * Tests if is is running under a browser.
572
+ * @return {Boolean} true if the environment has process, process.version and process.versions.
573
+ */
574
+ is.browser = function() {
575
+ return (!is.node() && typeof window !== 'undefined' && toString.call(window) === '[object global]');
576
+ };
577
+
578
+ /**
579
+ * Test if 'value' is defined.
580
+ * Alias: def
581
+ * @param {Any} value The value to test.
582
+ * @return {Boolean} true if 'value' is defined, false otherwise.
583
+ */
584
+ is.defined = function(value) {
585
+ return typeof value !== 'undefined';
586
+ };
587
+ is.def = is.defined;
588
+
589
+ /**
590
+ * Tests if is is running under node.js
591
+ * @return {Boolean} true if the environment has process, process.version and process.versions.
592
+ */
593
+ is.nodejs = function() {
594
+ return (process && process.hasOwnProperty('version') &&
595
+ process.hasOwnProperty('versions'));
596
+ };
597
+ is.node = is.nodejs;
598
+
599
+ /**
600
+ * Test if 'value' is undefined.
601
+ * Aliases: undef, udef
602
+ * @param {Any} value value to test.
603
+ * @return {Boolean} true if 'value' is undefined, false otherwise.
604
+ */
605
+ is.undefined = function(value) {
606
+ return value === undefined;
607
+ };
608
+ is.udef = is.undef = is.undefined;
609
+
610
+
611
+ ////////////////////////////////////////////////////////////////////////////////
612
+ // Types
613
+
614
+ /**
615
+ * Test if 'value' is an array.
616
+ * Alias: ary, arry
617
+ * @param {Any} value value to test.
618
+ * @return {Boolean} true if 'value' is an array, false otherwise.
619
+ */
620
+ is.array = function(value) {
621
+ return '[object Array]' === toString.call(value);
622
+ };
623
+ is.arr = is.ary = is.arry = is.array;
624
+
625
+ /**
626
+ * Test if 'value' is an arraylike object (i.e. it has a length property with a valid value)
627
+ * Aliases: arraylike, arryLike, aryLike
628
+ * @param {Any} value value to test.
629
+ * @return {Boolean} true if 'value' is an arguments object, false otherwise.
630
+ */
631
+ is.arrayLike = function(value) {
632
+ if (is.nullOrUndef(value))
633
+ return false;
634
+ return value !== undefined &&
635
+ owns.call(value, 'length') &&
636
+ isFinite(value.length);
637
+ };
638
+ is.arrLike = is.arryLike = is.aryLike = is.arraylike = is.arrayLike;
639
+
640
+ /**
641
+ * Test if 'value' is an arguments object.
642
+ * Alias: args
643
+ * @param {Any} value value to test
644
+ * @return {Boolean} true if 'value' is an arguments object, false otherwise
645
+ */
646
+ is.arguments = function(value) {
647
+ return '[object Arguments]' === toString.call(value);
648
+ };
649
+ is.args = is.arguments;
650
+
651
+ /**
652
+ * Test if 'value' is a boolean.
653
+ * Alias: bool
654
+ * @param {Any} value value to test.
655
+ * @return {Boolean} true if 'value' is a boolean, false otherwise.
656
+ */
657
+ is.boolean = function(value) {
658
+ return '[object Boolean]' === toString.call(value);
659
+ };
660
+ is.bool = is.boolean;
661
+
662
+ /**
663
+ * Test if 'value' is an instance of Buffer.
664
+ * Aliases: instOf, instanceof
665
+ * @param {Any} value value to test.
666
+ * @return {Boolean} true if 'value' is an instance of 'constructor'.
667
+ */
668
+ is.buffer = function(value) {
669
+ return is.nodejs() && Buffer && Buffer.hasOwnProperty('isBuffer') && Buffer.isBuffer(value);
670
+ };
671
+ is.buff = is.buf = is.buffer;
672
+
673
+ /**
674
+ * Test if 'value' is a date.
675
+ * @param {Any} value value to test.
676
+ * @return {Boolean} true if 'value' is a date, false otherwise.
677
+ */
678
+ is.date = function(value) {
679
+ return '[object Date]' === toString.call(value);
680
+ };
681
+
682
+ /**
683
+ * Test if 'value' is an error object.
684
+ * Alias: err
685
+ * @param value value to test.
686
+ * @return {Boolean} true if 'value' is an error object, false otherwise.
687
+ */
688
+ is.error = function(value) {
689
+ return '[object Error]' === toString.call(value);
690
+ };
691
+ is.err = is.error;
692
+
693
+ /**
694
+ * Test if 'value' is false.
695
+ * @param {Any} value value to test.
696
+ * @return {Boolean} true if 'value' is false, false otherwise
697
+ */
698
+ is.false = function(value) {
699
+ return value === false;
700
+ };
701
+
702
+ /**
703
+ * Test if 'value' is a function or async function.
704
+ * Alias: func
705
+ * @param {Any} value value to test.
706
+ * @return {Boolean} true if 'value' is a function, false otherwise.
707
+ */
708
+ is.function = function(value) {
709
+ return is.syncFunction(value) || is.asyncFunction(value)
710
+ };
711
+ is.fun = is.func = is.function;
712
+
713
+ /**
714
+ * Test if 'value' is an async function using `async () => {}` or `async function () {}`.
715
+ * Alias: func
716
+ * @param {Any} value value to test.
717
+ * @return {Boolean} true if 'value' is a function, false otherwise.
718
+ */
719
+ is.asyncFunction = function(value) {
720
+ return '[object AsyncFunction]' === toString.call(value);
721
+ };
722
+ is.asyncFun = is.asyncFunc = is.asyncFunction;
723
+
724
+ /**
725
+ * Test if 'value' is a synchronous function.
726
+ * Alias: syncFunc
727
+ * @param {Any} value value to test.
728
+ * @return {Boolean} true if 'value' is a function, false otherwise.
729
+ */
730
+ is.syncFunction = function (value) {
731
+ return '[object Function]' === toString.call(value);
732
+ };
733
+ is.syncFun = is.syncFunc = is.syncFunction;
734
+ /**
735
+ * Test if 'value' is null.
736
+ * @param {Any} value to test.
737
+ * @return {Boolean} true if 'value' is null, false otherwise.
738
+ */
739
+ is.null = function(value) {
740
+ return value === null;
741
+ };
742
+
743
+ /**
744
+ * Test is 'value' is either null or undefined.
745
+ * Alias: nullOrUndef
746
+ * @param {Any} value value to test.
747
+ * @return {Boolean} True if value is null or undefined, false otherwise.
748
+ */
749
+ is.nullOrUndefined = function(value) {
750
+ return value === null || typeof value === 'undefined';
751
+ };
752
+ is.nullOrUndef = is.nullOrUndefined;
753
+
754
+ /**
755
+ * Test if 'value' is a number.
756
+ * Alias: num
757
+ * @param {Any} value to test.
758
+ * @return {Boolean} true if 'value' is a number, false otherwise.
759
+ */
760
+ is.number = function(value) {
761
+ return '[object Number]' === toString.call(value);
762
+ };
763
+ is.num = is.number;
764
+
765
+ /**
766
+ * Test if 'value' is an object. Note: Arrays, RegExps, Date, Error, etc all return false.
767
+ * Alias: obj
768
+ * @param {Any} value to test.
769
+ * @return {Boolean} true if 'value' is an object, false otherwise.
770
+ */
771
+ is.object = function(value) {
772
+ return '[object Object]' === toString.call(value);
773
+ };
774
+ is.obj = is.object;
775
+
776
+ /**
777
+ * Test if 'value' is a regular expression.
778
+ * Alias: regexp
779
+ * @param {Any} value to test.
780
+ * @return {Boolean} true if 'value' is a regexp, false otherwise.
781
+ */
782
+ is.regExp = function(value) {
783
+ return '[object RegExp]' === toString.call(value);
784
+ };
785
+ is.re = is.regexp = is.regExp;
786
+
787
+ /**
788
+ * Test if 'value' is a string.
789
+ * Alias: str
790
+ * @param {Any} value to test.
791
+ * @return {Boolean} true if 'value' is a string, false otherwise.
792
+ */
793
+ is.string = function(value) {
794
+ return '[object String]' === toString.call(value);
795
+ };
796
+ is.str = is.string;
797
+
798
+ /**
799
+ * Test if 'value' is true.
800
+ * @param {Any} value to test.
801
+ * @return {Boolean} true if 'value' is true, false otherwise.
802
+ */
803
+ is.true = function(value) {
804
+ return value === true;
805
+ };
806
+
807
+ /**
808
+ * Test if 'value' is a uuid (v1-v5)
809
+ * @param {Any} value to test.
810
+ * @return {Boolean} true if 'value is a valid RFC4122 UUID. Case non-specific.
811
+ */
812
+ var uuidRegExp = new RegExp('[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab]'+
813
+ '[0-9a-f]{3}-[0-9a-f]{12}', 'i');
814
+ is.uuid = function(value) {
815
+ return uuidRegExp.test(value);
816
+ };
817
+
818
+ ////////////////////////////////////////////////////////////////////////////////
819
+ // Object Relationships
820
+
821
+ /**
822
+ * Test if 'value' is equal to 'other'. Works for objects and arrays and will do deep comparisions,
823
+ * using recursion.
824
+ * Alias: eq
825
+ * @param {Any} value value.
826
+ * @param {Any} other value to compare with.
827
+ * @return {Boolean} true if 'value' is equal to 'other', false otherwise
828
+ */
829
+ is.equal = function(value, other) {
830
+ var type = toString.call(value);
831
+
832
+ if (typeof value !== typeof other) {
833
+ return false;
834
+ }
835
+
836
+ if (type !== toString.call(other)) {
837
+ return false;
838
+ }
839
+
840
+ if ('[object Object]' === type || '[object Array]' === type) {
841
+ return deepIs(value, other);
842
+ } else if ('[object Function]' === type) {
843
+ return value.prototype === other.prototype;
844
+ } else if ('[object Date]' === type) {
845
+ return value.getTime() === other.getTime();
846
+ }
847
+
848
+ return value === other;
849
+ };
850
+ is.objEquals = is.eq = is.equal;
851
+
852
+ /**
853
+ * JS Type definitions which cannot host values.
854
+ * @api private
855
+ */
856
+ var NON_HOST_TYPES = {
857
+ 'boolean': 1,
858
+ 'number': 1,
859
+ 'string': 1,
860
+ 'undefined': 1
861
+ };
862
+
863
+ /**
864
+ * Test if 'key' in host is an object. To be hosted means host[value] is an object.
865
+ * @param {Any} value The value to test.
866
+ * @param {Any} host Host that may contain value.
867
+ * @return {Boolean} true if 'value' is hosted by 'host', false otherwise.
868
+ */
869
+ is.hosted = function(value, host) {
870
+ if (is.nullOrUndef(value))
871
+ return false;
872
+ var type = typeof host[value];
873
+ return type === 'object' ? !!host[value] : !NON_HOST_TYPES[type];
874
+ };
875
+
876
+ /**
877
+ * Test if 'value' is an instance of 'constructor'.
878
+ * Aliases: instOf, instanceof
879
+ * @param {Any} value value to test.
880
+ * @return {Boolean} true if 'value' is an instance of 'constructor'.
881
+ */
882
+ is.instanceOf = function(value, constructor) {
883
+ if (is.nullOrUndef(value) || is.nullOrUndef(constructor))
884
+ return false;
885
+ return (value instanceof constructor);
886
+ };
887
+ is.instOf = is.instanceof = is.instanceOf;
888
+
889
+ /**
890
+ * Test if 'value' is an instance type objType.
891
+ * Aliases: objInstOf, objectinstanceof, instOf, instanceOf
892
+ * @param {object} objInst an object to testfor type.
893
+ * @param {object} objType an object type to compare.
894
+ * @return {Boolean} true if 'value' is an object, false otherwise.
895
+ */
896
+ is.objectInstanceOf = function(objInst, objType) {
897
+ try {
898
+ return '[object Object]' === toString.call(objInst) && (objInst instanceof objType);
899
+ } catch(err) {
900
+ return false;
901
+ }
902
+ };
903
+ is.instOf = is.instanceOf = is.objInstOf = is.objectInstanceOf;
904
+
905
+ /**
906
+ * Test if 'value' is a type of 'type'.
907
+ * Alias: a
908
+ * @param value value to test.
909
+ * @param {String} type The name of the type.
910
+ * @return {Boolean} true if 'value' is an arguments object, false otherwise.
911
+ */
912
+ is.type = function(value, type) {
913
+ return typeof value === type;
914
+ };
915
+ is.a = is.type;
916
+
917
+ ////////////////////////////////////////////////////////////////////////////////
918
+ // Object State
919
+
920
+ /**
921
+ * Test if 'value' is empty. To be empty means to be an array, object or string with nothing contained.
922
+ * @param {Any} value value to test.
923
+ * @return {Boolean} true if 'value' is empty, false otherwise.
924
+ */
925
+ is.empty = function(value) {
926
+ var type = toString.call(value);
927
+
928
+ if ('[object Array]' === type || '[object Arguments]' === type) {
929
+ return value.length === 0;
930
+ }
931
+
932
+ if ('[object Object]' === type) {
933
+ for (var key in value) if (owns.call(value, key)) return false;
934
+ return true;
935
+ }
936
+
937
+ if ('[object String]' === type) {
938
+ return value === '';
939
+ }
940
+
941
+ return false;
942
+ };
943
+
944
+ /**
945
+ * Test if 'value' is an arguments object that is empty.
946
+ * Alias: args
947
+ * @param {Any} value value to test
948
+ * @return {Boolean} true if 'value' is an arguments object with no args, false otherwise
949
+ */
950
+ is.emptyArguments = function(value) {
951
+ return '[object Arguments]' === toString.call(value) && value.length === 0;
952
+ };
953
+ is.noArgs = is.emptyArgs = is.emptyArguments;
954
+
955
+ /**
956
+ * Test if 'value' is an array containing no entries.
957
+ * Aliases: emptyArry, emptyAry
958
+ * @param {Any} value The value to test.
959
+ * @return {Boolean} true if 'value' is an array with no elemnets.
960
+ */
961
+ is.emptyArray = function(value) {
962
+ return '[object Array]' === toString.call(value) && value.length === 0;
963
+ };
964
+ is.emptyArry = is.emptyAry = is.emptyArray;
965
+
966
+ /**
967
+ * Test if 'value' is an empty array(like) object.
968
+ * Aliases: arguents.empty, args.empty, ary.empty, arry.empty
969
+ * @param {Any} value value to test.
970
+ * @return {Boolean} true if 'value' is an empty array(like), false otherwise.
971
+ */
972
+ is.emptyArrayLike = function(value) {
973
+ return value.length === 0;
974
+ };
975
+ is.emptyArrLike = is.emptyArrayLike;
976
+
977
+ /**
978
+ * Test if 'value' is an empty string.
979
+ * Alias: emptyStr
980
+ * @param {Any} value to test.
981
+ * @return {Boolean} true if 'value' is am empty string, false otherwise.
982
+ */
983
+ is.emptyString = function(value) {
984
+ return is.string(value) && value.length === 0;
985
+ };
986
+ is.emptyStr = is.emptyString;
987
+
988
+ /**
989
+ * Test if 'value' is an array containing at least 1 entry.
990
+ * Aliases: nonEmptyArry, nonEmptyAry
991
+ * @param {Any} value The value to test.
992
+ * @return {Boolean} true if 'value' is an array with at least 1 value, false otherwise.
993
+ */
994
+ is.nonEmptyArray = function(value) {
995
+ return '[object Array]' === toString.call(value) && value.length > 0;
996
+ };
997
+ is.nonEmptyArr = is.nonEmptyArry = is.nonEmptyAry = is.nonEmptyArray;
998
+
999
+ /**
1000
+ * Test if 'value' is an object with properties. Note: Arrays are objects.
1001
+ * Alias: nonEmptyObj
1002
+ * @param {Any} value to test.
1003
+ * @return {Boolean} true if 'value' is an object, false otherwise.
1004
+ */
1005
+ is.nonEmptyObject = function(value) {
1006
+ return '[object Object]' === toString.call(value) && Object.keys(value).length > 0;
1007
+ };
1008
+ is.nonEmptyObj = is.nonEmptyObject;
1009
+
1010
+ /**
1011
+ * Test if 'value' is an object with no properties. Note: Arrays are objects.
1012
+ * Alias: nonEmptyObj
1013
+ * @param {Any} value to test.
1014
+ * @return {Boolean} true if 'value' is an object, false otherwise.
1015
+ */
1016
+ is.emptyObject = function(value) {
1017
+ return '[object Object]' === toString.call(value) && Object.keys(value).length === 0;
1018
+ };
1019
+ is.emptyObj = is.emptyObject;
1020
+
1021
+ /**
1022
+ * Test if 'value' is a non-empty string.
1023
+ * Alias: nonEmptyStr
1024
+ * @param {Any} value to test.
1025
+ * @return {Boolean} true if 'value' is a non-empty string, false otherwise.
1026
+ */
1027
+ is.nonEmptyString = function(value) {
1028
+ return is.string(value) && value.length > 0;
1029
+ };
1030
+ is.nonEmptyStr = is.nonEmptyString;
1031
+
1032
+ ////////////////////////////////////////////////////////////////////////////////
1033
+ // Numeric Types within Number
1034
+
1035
+ /**
1036
+ * Test if 'value' is an even number.
1037
+ * @param {Number} value to test.
1038
+ * @return {Boolean} true if 'value' is an even number, false otherwise.
1039
+ */
1040
+ is.even = function(value) {
1041
+ return '[object Number]' === toString.call(value) && value % 2 === 0;
1042
+ };
1043
+
1044
+ /**
1045
+ * Test if 'value' is a decimal number.
1046
+ * Aliases: decimalNumber, decNum
1047
+ * @param {Any} value value to test.
1048
+ * @return {Boolean} true if 'value' is a decimal number, false otherwise.
1049
+ */
1050
+ is.decimal = function(value) {
1051
+ return '[object Number]' === toString.call(value) && value % 1 !== 0;
1052
+ };
1053
+ is.dec = is.decNum = is.decimal;
1054
+
1055
+ /**
1056
+ * Test if 'value' is an integer.
1057
+ * Alias: integer
1058
+ * @param {Any} value to test.
1059
+ * @return {Boolean} true if 'value' is an integer, false otherwise.
1060
+ */
1061
+ is.integer = function(value) {
1062
+ return '[object Number]' === toString.call(value) && value % 1 === 0;
1063
+ };
1064
+ is.int = is.integer;
1065
+
1066
+ /**
1067
+ * is.nan
1068
+ * Test if `value` is not a number.
1069
+ *
1070
+ * @param {Mixed} value value to test
1071
+ * @return {Boolean} true if `value` is not a number, false otherwise
1072
+ * @api public
1073
+ */
1074
+ is.notANumber = function(value) {
1075
+ return !is.num(value) || value !== value;
1076
+ };
1077
+ is.nan = is.notANum = is.notANumber;
1078
+
1079
+ /**
1080
+ * Test if 'value' is an odd number.
1081
+ * @param {Number} value to test.
1082
+ * @return {Boolean} true if 'value' is an odd number, false otherwise.
1083
+ */
1084
+ is.odd = function(value) {
1085
+ return !is.decimal(value) && '[object Number]' === toString.call(value) && value % 2 !== 0;
1086
+ };
1087
+ is.oddNumber = is.oddNum = is.odd;
1088
+
1089
+ ////////////////////////////////////////////////////////////////////////////////
1090
+ // Numeric Type & State
1091
+
1092
+ /**
1093
+ * Test if 'value' is a positive number.
1094
+ * Alias: positiveNum, posNum
1095
+ * @param {Any} value to test.
1096
+ * @return {Boolean} true if 'value' is a number, false otherwise.
1097
+ */
1098
+ is.positiveNumber = function(value) {
1099
+ return '[object Number]' === toString.call(value) && value > 0;
1100
+ };
1101
+ is.pos = is.positive = is.posNum = is.positiveNum = is.positiveNumber;
1102
+
1103
+ /**
1104
+ * Test if 'value' is a negative number.
1105
+ * Aliases: negNum, negativeNum
1106
+ * @param {Any} value to test.
1107
+ * @return {Boolean} true if 'value' is a number, false otherwise.
1108
+ */
1109
+ is.negativeNumber = function(value) {
1110
+ return '[object Number]' === toString.call(value) && value < 0;
1111
+ };
1112
+ is.neg = is.negNum = is.negativeNum = is.negativeNumber;
1113
+
1114
+ /**
1115
+ * Test if 'value' is a negative integer.
1116
+ * Aliases: negInt, negativeInteger
1117
+ * @param {Any} value to test.
1118
+ * @return {Boolean} true if 'value' is a negative integer, false otherwise.
1119
+ */
1120
+ is.negativeInteger = function(value) {
1121
+ return '[object Number]' === toString.call(value) && value % 1 === 0 && value < 0;
1122
+ };
1123
+ is.negativeInt = is.negInt = is.negativeInteger;
1124
+
1125
+ /**
1126
+ * Test if 'value' is a positive integer.
1127
+ * Alias: posInt
1128
+ * @param {Any} value to test.
1129
+ * @return {Boolean} true if 'value' is a positive integer, false otherwise.
1130
+ */
1131
+ is.positiveInteger = function(value) {
1132
+ return '[object Number]' === toString.call(value) && value % 1 === 0 && value > 0;
1133
+ };
1134
+ is.posInt = is.positiveInt = is.positiveInteger;
1135
+
1136
+ ////////////////////////////////////////////////////////////////////////////////
1137
+ // Numeric Relationships
1138
+
1139
+ /**
1140
+ * Test if 'value' is divisible by 'n'.
1141
+ * Alias: divisBy
1142
+ * @param {Number} value value to test.
1143
+ * @param {Number} n dividend.
1144
+ * @return {Boolean} true if 'value' is divisible by 'n', false otherwise.
1145
+ */
1146
+ is.divisibleBy = function(value, n) {
1147
+ if (value === 0)
1148
+ return false;
1149
+ return '[object Number]' === toString.call(value) &&
1150
+ n !== 0 &&
1151
+ value % n === 0;
1152
+ };
1153
+ is.divBy = is.divisBy = is.divisibleBy;
1154
+
1155
+ /**
1156
+ * Test if 'value' is greater than or equal to 'other'.
1157
+ * Aliases: greaterOrEq, greaterOrEqual
1158
+ * @param {Number} value value to test.
1159
+ * @param {Number} other value to compare with.
1160
+ * @return {Boolean} true, if value is greater than or equal to other, false otherwise.
1161
+ */
1162
+ is.greaterOrEqualTo = function(value, other) {
1163
+ return value >= other;
1164
+ };
1165
+ is.greaterOrEqual = is.ge = is.greaterOrEqualTo;
1166
+
1167
+ /**
1168
+ * Test if 'value' is greater than 'other'.
1169
+ * Aliases: greaterThan
1170
+ * @param {Number} value value to test.
1171
+ * @param {Number} other value to compare with.
1172
+ * @return {Boolean} true, if value is greater than other, false otherwise.
1173
+ */
1174
+ is.greaterThan = function(value, other) {
1175
+ return value > other;
1176
+ };
1177
+ is.gt = is.greaterThan;
1178
+
1179
+ /**
1180
+ * Test if 'value' is less than or equal to 'other'.
1181
+ * Alias: lessThanOrEq, lessThanOrEqual
1182
+ * @param {Number} value value to test
1183
+ * @param {Number} other value to compare with
1184
+ * @return {Boolean} true, if 'value' is less than or equal to 'other', false otherwise.
1185
+ */
1186
+ is.lessThanOrEqualTo = function(value, other) {
1187
+ return value <= other;
1188
+ };
1189
+ is.lessThanOrEq = is.lessThanOrEqual = is.le = is.lessThanOrEqualTo;
1190
+
1191
+ /**
1192
+ * Test if 'value' is less than 'other'.
1193
+ * Alias: lessThan
1194
+ * @param {Number} value value to test
1195
+ * @param {Number} other value to compare with
1196
+ * @return {Boolean} true, if 'value' is less than 'other', false otherwise.
1197
+ */
1198
+ is.lessThan = function(value, other) {
1199
+ return value < other;
1200
+ };
1201
+ is.lt = is.lessThan;
1202
+
1203
+ /**
1204
+ * Test if 'value' is greater than 'others' values.
1205
+ * Alias: max
1206
+ * @param {Number} value value to test.
1207
+ * @param {Array} others values to compare with.
1208
+ * @return {Boolean} true if 'value' is greater than 'others' values.
1209
+ */
1210
+ is.maximum = function(value, others) {
1211
+ if (!is.arrayLike(others) || !is.number(value))
1212
+ return false;
1213
+
1214
+ var len = others.length;
1215
+ while (--len > -1) {
1216
+ if (value < others[len]) {
1217
+ return false;
1218
+ }
1219
+ }
1220
+
1221
+ return true;
1222
+ };
1223
+ is.max = is.maximum;
1224
+
1225
+ /**
1226
+ * Test if 'value' is less than 'others' values.
1227
+ * Alias: min
1228
+ * @param {Number} value value to test.
1229
+ * @param {Array} others values to compare with.
1230
+ * @return {Boolean} true if 'value' is less than 'others' values.
1231
+ */
1232
+ is.minimum = function(value, others) {
1233
+ if (!is.arrayLike(others) || !is.number(value))
1234
+ return false;
1235
+
1236
+ var len = others.length;
1237
+ while (--len > -1) {
1238
+ if (value > others[len]) {
1239
+ return false;
1240
+ }
1241
+ }
1242
+
1243
+ return true;
1244
+ };
1245
+ is.min = is.minimum;
1246
+
1247
+ /**
1248
+ * Test if 'value' is within 'start' and 'finish'.
1249
+ * Alias: withIn
1250
+ * @param {Number} value value to test.
1251
+ * @param {Number} start lower bound.
1252
+ * @param {Number} finish upper bound.
1253
+ * @return {Boolean} true if 'value' is is within 'start' and 'finish', false otherwise.
1254
+ */
1255
+ is.within = function(value, start, finish) {
1256
+ return value >= start && value <= finish;
1257
+ };
1258
+ is.withIn = is.within;
1259
+
1260
+ /**
1261
+ * Test if 'value' is within 'precision' decimal places from 'comparitor'.
1262
+ * Alias: closish, near.
1263
+ * @param {Number} value value to test
1264
+ * @param {Number} comparitor value to test 'value' against
1265
+ * @param {Number} precision number of decimals to compare floating points, defaults to 2
1266
+ * @return {Boolean} true if 'value' is within 'precision' decimal places from 'comparitor', false otherwise.
1267
+ */
1268
+ is.prettyClose = function(value, comparitor, precision) {
1269
+ if (!is.number(value) || !is.number(comparitor)) return false;
1270
+ if (is.defined(precision) && !is.posInt(precision)) return false;
1271
+ if (is.undefined(precision)) precision = 2;
1272
+
1273
+ return value.toFixed(precision) === comparitor.toFixed(precision);
1274
+ };
1275
+ is.closish = is.near = is.prettyClose;
1276
+ ////////////////////////////////////////////////////////////////////////////////
1277
+ // Networking
1278
+
1279
+ /**
1280
+ * Test if a value is a valid DNS address. eg www.stdarg.com is true while
1281
+ * 127.0.0.1 is false.
1282
+ * @param {Any} value to test if a DNS address.
1283
+ * @return {Boolean} true if a DNS address, false otherwise.
1284
+ * DNS Address is made up of labels separated by '.'
1285
+ * Each label must be between 1 and 63 characters long
1286
+ * The entire hostname (including the delimiting dots) has a maximum of 255 characters.
1287
+ * Hostname may not contain other characters, such as the underscore character (_)
1288
+ * other DNS names may contain the underscore.
1289
+ */
1290
+ is.dnsAddress = function(value) {
1291
+ if (!is.nonEmptyStr(value)) return false;
1292
+ if (value.length > 255) return false;
1293
+ if (numbersLabel.test(value)) return false;
1294
+ if (!dnsLabel.test(value)) return false;
1295
+ return true;
1296
+ //var names = value.split('.');
1297
+ //if (!is.array(names) || !names.length) return false;
1298
+ //if (names[0].indexOf('_') > -1) return false;
1299
+ //for (var i=0; i<names.length; i++) {
1300
+ //if (!dnsLabel.test(names[i])) return false;
1301
+ //}
1302
+ //return true;
1303
+ };
1304
+ is.dnsAddr = is.dns = is.dnsAddress;
1305
+ var dnsLabel = /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/;
1306
+ var numbersLabel = /^([0-9]|[0-9][0-9\-]{0,61}[0-9])(\.([0-9]|[0-9][0-9\-]{0,61}[0-9]))*$/;
1307
+
1308
+ /**
1309
+ * Test if value is a valid email address.
1310
+ * @param {Any} value to test if an email address.
1311
+ * @return {Boolean} true if an email address, false otherwise.
1312
+ */
1313
+ is.emailAddress = function(value) {
1314
+ if (!is.nonEmptyStr(value))
1315
+ return false;
1316
+ return emailRegexp.test(value);
1317
+ };
1318
+ is.email = is.emailAddr = is.emailAddress;
1319
+ var emailRegexp = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/;
1320
+
1321
+ /**
1322
+ * Test if a value is either an IPv4 numeric IP address.
1323
+ * The rules are:
1324
+ * must be a string
1325
+ * length must be 15 characters or less
1326
+ * There must be four octets separated by a '.'
1327
+ * No octet can be less than 0 or greater than 255.
1328
+ * @param {Any} value to test if an ip address.
1329
+ * @return {Boolean} true if an ip address, false otherwise.
1330
+ */
1331
+ is.ipv4Address = function(value) {
1332
+ if (!is.nonEmptyStr(value)) return false;
1333
+ if (value.length > 15) return false;
1334
+ var octets = value.split('.');
1335
+ if (!is.array(octets) || octets.length !== 4) return false;
1336
+ for (var i=0; i<octets.length; i++) {
1337
+ var val = parseInt(octets[i], 10);
1338
+ if (isNaN(val)) return false;
1339
+ if (val < 0 || val > 255) return false;
1340
+ }
1341
+ return true;
1342
+ };
1343
+ is.ipv4 = is.ipv4Addr = is.ipv4Address;
1344
+
1345
+ /**
1346
+ * Test if a value is either an IPv6 numeric IP address.
1347
+ * @param {Any} value to test if an ip address.
1348
+ * @return {Boolean} true if an ip address, false otherwise.
1349
+ */
1350
+ is.ipv6Address = function(value) {
1351
+ if (!is.nonEmptyStr(value)) return false;
1352
+ return ipRegEx.v6({extract: true}).test(value);
1353
+ };
1354
+ is.ipv6 = is.ipv6Addr = is.ipv6Address;
1355
+
1356
+ /**
1357
+ * Test if a value is either an IPv4 or IPv6 numeric IP address.
1358
+ * @param {Any} value to test if an ip address.
1359
+ * @return {Boolean} true if an ip address, false otherwise.
1360
+ */
1361
+ is.ipAddress = function(value) {
1362
+ if (!is.nonEmptyStr(value)) return false;
1363
+ return is.ipv4Address(value) || is.ipv6Address(value)
1364
+ };
1365
+ is.ip = is.ipAddr = is.ipAddress;
1366
+
1367
+ /**
1368
+ * Test is a value is a valid ipv4, ipv6 or DNS name.
1369
+ * Aliases: host, hostAddr, hostAddress.
1370
+ * @param {Any} value to test if a host address.
1371
+ * @return {Boolean} true if a host address, false otherwise.
1372
+ */
1373
+ is.hostAddress = function(value) {
1374
+ if (!is.nonEmptyStr(value)) return false;
1375
+ return is.dns(value) || is.ipv4(value) || is.ipv6(value);
1376
+ };
1377
+ is.host = is.hostIp = is.hostAddr = is.hostAddress;
1378
+
1379
+ /**
1380
+ * Test if a number is a valid TCP port
1381
+ * @param {Any} value to test if its a valid TCP port
1382
+ */
1383
+ is.port = function(value) {
1384
+ if (!is.num(value) || is.negativeInt(value) || value > 65535)
1385
+ return false;
1386
+ return true;
1387
+ };
1388
+
1389
+ /**
1390
+ * Test if a number is a valid TCP port in the range 0-1023.
1391
+ * Alias: is.sysPort.
1392
+ * @param {Any} value to test if its a valid TCP port
1393
+ */
1394
+ is.systemPort = function(value) {
1395
+ if (is.port(value) && value < 1024)
1396
+ return true;
1397
+ return false;
1398
+ };
1399
+ is.sysPort = is.systemPort;
1400
+
1401
+ /**
1402
+ * Test if a number is a valid TCP port in the range 1024-65535.
1403
+ * @param {Any} value to test if its a valid TCP port
1404
+ */
1405
+ is.userPort = function(value) {
1406
+ if (is.port(value) && value > 1023)
1407
+ return true;
1408
+ return false;
1409
+ };
1410
+
1411
+ /*
1412
+ function sumDigits(num) {
1413
+ var str = num.toString();
1414
+ var sum = 0;
1415
+ for (var i = 0; i < str.length; i++)
1416
+ sum += (str[i]-0);
1417
+ return sum;
1418
+ }
1419
+ */
1420
+
1421
+ /**
1422
+ * Test if a string is a credit card.
1423
+ * From http://en.wikipedia.org/wiki/Luhn_algorithm
1424
+ * @param {String} value to test if a credit card.
1425
+ * @return true if the string is the correct format, false otherwise
1426
+ */
1427
+ is.creditCardNumber = function(str) {
1428
+ if (!is.str(str))
1429
+ return false;
1430
+
1431
+ var ary = str.split('');
1432
+ var i, cnt;
1433
+ // From the rightmost digit, which is the check digit, moving left, double
1434
+ // the value of every second digit;
1435
+ for (i=ary.length-1, cnt=1; i>-1; i--, cnt++) {
1436
+ if (cnt%2 === 0)
1437
+ ary[i] *= 2;
1438
+ }
1439
+
1440
+ str = ary.join('');
1441
+ var sum = 0;
1442
+ // if the product of the previous doubling operation is greater than 9
1443
+ // (e.g., 7 * 2 = 14), then sum the digits of the products (e.g., 10: 1 + 0
1444
+ // = 1, 14: 1 + 4 = 5). We do the this by joining the array of numbers and
1445
+ // add adding the int value of all the characters in the string.
1446
+ for (i=0; i<str.length; i++)
1447
+ sum += Math.floor(str[i]);
1448
+
1449
+ // If the total (sum) modulo 10 is equal to 0 (if the total ends in zero)
1450
+ // then the number is valid according to the Luhn formula; else it is not
1451
+ // valid.
1452
+ return sum % 10 === 0;
1453
+ };
1454
+ is.creditCard = is.creditCardNum = is.creditCardNumber;
1455
+
1456
+
1457
+ ////////////////////////////////////////////////////////////////////////////////
1458
+ // The following credit card info is from:
1459
+ // http://en.wikipedia.org/wiki/Bank_card_number#Issuer_identification_number_.28IIN.29
1460
+
1461
+ /**
1462
+ * Test if card number is an American Express card.
1463
+ * @param {String} the credit card number string to test.
1464
+ * @return true if the string is the correct format, false otherwise
1465
+ */
1466
+ is.americanExpressCardNumber = function(str) {
1467
+ if (!is.str(str) || str.length !== 15)
1468
+ return false;
1469
+
1470
+ var prefix = Math.floor(str.slice(0,2));
1471
+ if (prefix !== 34 && prefix !== 37)
1472
+ return false;
1473
+
1474
+ if (!is.creditCardNumber(str))
1475
+ return false;
1476
+
1477
+ return true;
1478
+ };
1479
+ is.amexCard = is.amexCardNum = is.americanExpressCardNumber;
1480
+
1481
+ /**
1482
+ * Test if card number is a China UnionPay card.
1483
+ * @param {String} the credit card number string to test.
1484
+ * @return true if the string is the correct format, false otherwise
1485
+ */
1486
+ is.chinaUnionPayCardNumber = function(str) {
1487
+ if (!is.str(str) || (str.length < 16 && str.length > 19))
1488
+ return false;
1489
+
1490
+ var prefix = Math.floor(str.slice(0,2));
1491
+ if (prefix !== 62 && prefix !== 88)
1492
+ return false;
1493
+
1494
+ // no validation for this card
1495
+ return true;
1496
+ };
1497
+ is.chinaUnion = is.chinaUnionPayCard = is.chinaUnionPayCardNumber;
1498
+
1499
+ /**
1500
+ * Test if card number is a Diner's Club Carte Blance card.
1501
+ * @param {String} the credit card number string to test.
1502
+ * @return true if the string is the correct format, false otherwise
1503
+ */
1504
+ is.dinersClubCarteBlancheCardNumber = function(str) {
1505
+ if (!is.str(str) || str.length !== 14)
1506
+ return false;
1507
+
1508
+ var prefix = Math.floor(str.slice(0,3));
1509
+ if (prefix < 300 || prefix > 305)
1510
+ return false;
1511
+
1512
+ if (!is.creditCardNumber(str))
1513
+ return false;
1514
+
1515
+ return true;
1516
+ };
1517
+ is.dinersClubCB = is.dinersClubCarteBlancheCard =
1518
+ is.dinersClubCarteBlancheCardNumber;
1519
+
1520
+ /**
1521
+ * Test if card number is a Diner's Club International card.
1522
+ * @param {String} the credit card number string to test.
1523
+ * @return true if the string is the correct format, false otherwise
1524
+ */
1525
+ is.dinersClubInternationalCardNumber = function(str) {
1526
+ if (!is.str(str) || str.length !== 14)
1527
+ return false;
1528
+ var prefix = Math.floor(str.slice(0,3));
1529
+ var prefix2 = Math.floor(str.slice(0,2));
1530
+
1531
+ // 300-305, 309, 36, 38-39
1532
+ if ((prefix < 300 || prefix > 305) && prefix !== 309 && prefix2 !== 36 &&
1533
+ (prefix2 < 38 || prefix2 > 39)) {
1534
+ return false;
1535
+ }
1536
+
1537
+ if (!is.creditCardNumber(str))
1538
+ return false;
1539
+
1540
+ return true;
1541
+ };
1542
+ is.dinersClubInt = is.dinersClubInternationalCard =
1543
+ is.dinersClubInternationalCardNumber;
1544
+
1545
+ /**
1546
+ * Test if card number is a Diner's Club USA & CA card.
1547
+ * @param {String} the credit card number string to test.
1548
+ * @return true if the string is the correct format, false otherwise
1549
+ */
1550
+ is.dinersClubUSACanadaCardNumber = function(str) {
1551
+ if (!is.str(str) || str.length !== 16)
1552
+ return false;
1553
+ var prefix = Math.floor(str.slice(0,2));
1554
+
1555
+ if (prefix !== 54 && prefix !== 55)
1556
+ return false;
1557
+
1558
+ if (!is.creditCardNumber(str))
1559
+ return false;
1560
+
1561
+ return true;
1562
+ };
1563
+ is.dinersClub = is.dinersClubUSACanCard = is.dinersClubUSACanadaCardNumber;
1564
+
1565
+ /**
1566
+ * Test if card number is a Diner's Club USA/CA card.
1567
+ * @param {String} the credit card number string to test.
1568
+ * @return true if the string is the correct format, false otherwise
1569
+ */
1570
+ is.discoverCardNumber = function(str) {
1571
+ if (!is.str(str) || str.length !== 16)
1572
+ return false;
1573
+
1574
+ var prefix = Math.floor(str.slice(0,6));
1575
+ var prefix2 = Math.floor(str.slice(0,3));
1576
+
1577
+ if (str.slice(0,4) !== '6011' && (prefix < 622126 || prefix > 622925) &&
1578
+ (prefix2 < 644 || prefix2 > 649) && str.slice(0,2) !== '65') {
1579
+ return false;
1580
+ }
1581
+
1582
+ if (!is.creditCardNumber(str))
1583
+ return false;
1584
+
1585
+ return true;
1586
+ };
1587
+ is.discover = is.discoverCard = is.discoverCardNumber;
1588
+
1589
+ /**
1590
+ * Test if card number is an InstaPayment card number
1591
+ * @param {String} the credit card number string to test.
1592
+ * @return true if the string is the correct format, false otherwise
1593
+ */
1594
+ is.instaPaymentCardNumber = function(str) {
1595
+ if (!is.str(str) || str.length !== 16)
1596
+ return false;
1597
+
1598
+ var prefix = Math.floor(str.slice(0,3));
1599
+ if (prefix < 637 || prefix > 639)
1600
+ return false;
1601
+
1602
+ if (!is.creditCardNumber(str))
1603
+ return false;
1604
+
1605
+ return true;
1606
+ };
1607
+ is.instaPayment = is.instaPaymentCardNumber;
1608
+
1609
+ /**
1610
+ * Test if card number is a JCB card number
1611
+ * @param {String} the credit card number string to test.
1612
+ * @return true if the string is the correct format, false otherwise
1613
+ */
1614
+ is.jcbCardNumber = function(str) {
1615
+ if (!is.str(str) || str.length !== 16)
1616
+ return false;
1617
+
1618
+ var prefix = Math.floor(str.slice(0,4));
1619
+ if (prefix < 3528 || prefix > 3589)
1620
+ return false;
1621
+
1622
+ if (!is.creditCardNumber(str))
1623
+ return false;
1624
+
1625
+ return true;
1626
+ };
1627
+ is.jcb = is.jcbCard = is.jcbCardNumber;
1628
+
1629
+ /**
1630
+ * Test if card number is a Laser card number
1631
+ * @param {String} the credit card number string to test.
1632
+ * @return true if the string is the correct format, false otherwise
1633
+ */
1634
+ is.laserCardNumber = function(str) {
1635
+ if (!is.str(str) || (str.length < 16 && str.length > 19))
1636
+ return false;
1637
+
1638
+ var prefix = Math.floor(str.slice(0,4));
1639
+ var valid = [ 6304, 6706, 6771, 6709 ];
1640
+ if (valid.indexOf(prefix) === -1)
1641
+ return false;
1642
+
1643
+ if (!is.creditCardNumber(str))
1644
+ return false;
1645
+
1646
+ return true;
1647
+ };
1648
+ is.laser = is.laserCard = is.laserCardNumber;
1649
+
1650
+ /**
1651
+ * Test if card number is a Maestro card number
1652
+ * @param {String} the credit card number string to test.
1653
+ * @return true if the string is the correct format, false otherwise
1654
+ */
1655
+ is.maestroCardNumber = function(str) {
1656
+ if (!is.str(str) || str.length < 12 || str.length > 19)
1657
+ return false;
1658
+
1659
+ var prefix = str.slice(0,4);
1660
+ var valid = [ '5018', '5020', '5038', '5612', '5893', '6304', '6759',
1661
+ '6761', '6762', '6763', '0604', '6390' ];
1662
+
1663
+ if (valid.indexOf(prefix) === -1)
1664
+ return false;
1665
+
1666
+ if (!is.creditCardNumber(str))
1667
+ return false;
1668
+
1669
+ return true;
1670
+ };
1671
+ is.maestro = is.maestroCard = is.maestroCardNumber;
1672
+
1673
+ /**
1674
+ * Test if card number is a Dankort card number
1675
+ * @param {String} the credit card number string to test.
1676
+ * @return true if the string is the correct format, false otherwise
1677
+ */
1678
+ is.dankortCardNumber = function(str) {
1679
+ if (!is.str(str) || str.length !== 16)
1680
+ return false;
1681
+
1682
+ if (str.slice(0,4) !== '5019')
1683
+ return false;
1684
+
1685
+ if (!is.creditCardNumber(str))
1686
+ return false;
1687
+
1688
+ return true;
1689
+ };
1690
+ is.dankort = is.dankortCard = is.dankortCardNumber;
1691
+
1692
+ /**
1693
+ * Test if card number is a MasterCard card number
1694
+ * @param {String} the credit card number string to test.
1695
+ * @return true if the string is the correct format, false otherwise
1696
+ */
1697
+ is.masterCardCardNumber = function(str) {
1698
+ if (!is.str(str) || str.length !== 16)
1699
+ return false;
1700
+
1701
+ var prefix = Math.floor(str.slice(0,2));
1702
+ if (prefix < 50 || prefix > 55)
1703
+ return false;
1704
+
1705
+ if (!is.creditCardNumber(str))
1706
+ return false;
1707
+
1708
+ return true;
1709
+ };
1710
+ is.masterCard = is.masterCardCard = is.masterCardCardNumber;
1711
+
1712
+ /**
1713
+ * Test if card number is a Visa card number
1714
+ * @param {String} the credit card number string to test.
1715
+ * @return true if the string is the correct format, false otherwise
1716
+ */
1717
+ is.visaCardNumber = function(str) {
1718
+ if (!is.str(str) || (str.length !== 13 && str.length !== 16))
1719
+ return false;
1720
+
1721
+ if ('4' !== str.slice(0,1))
1722
+ return false;
1723
+
1724
+ if (!is.creditCardNumber(str))
1725
+ return false;
1726
+
1727
+ return true;
1728
+ };
1729
+
1730
+ is.visa = is.visaCard = is.visaCardNumber;
1731
+
1732
+ /**
1733
+ * Test if card number is a Visa card number
1734
+ * @param {String} the credit card number string to test.
1735
+ * @return true if the string is the correct format, false otherwise
1736
+ */
1737
+ is.visaElectronCardNumber = function(str) {
1738
+ if (!is.str(str) || str.length !== 16)
1739
+ return false;
1740
+
1741
+ var prefix = Math.floor(str.slice(0,4));
1742
+ var valid = [ 4026, 4405, 4508, 4844, 4913, 4917 ];
1743
+ if ('417500' !== str.slice(0,6) && valid.indexOf(prefix) === -1)
1744
+ return false;
1745
+
1746
+ if (!is.creditCardNumber(str))
1747
+ return false;
1748
+
1749
+ return false;
1750
+ };
1751
+
1752
+ is.visaElectron = is.visaElectronCard = is.visaElectronCardNumber;
1753
+
1754
+ /**
1755
+ * Test if the input is a valid MongoDB id.
1756
+ * @param {String|Object} Either a mongodb object id or a string representation.
1757
+ * @return true if the string is the correct format, false otherwise
1758
+ * Thanks to Jason Denizac (https://github.com/jden) for pointing this out.
1759
+ * https://github.com/jden/objectid/blob/master/index.js#L7-L10
1760
+ */
1761
+ var objIdPattern = /^[0-9a-fA-F]{24}$/;
1762
+ is.mongoId = is.objectId = is.objId = function(id) {
1763
+ return (Boolean(id) && !Array.isArray(id) && objIdPattern.test(String(id)));
1764
+ };
1765
+
1766
+ /**
1767
+ * Test is the first argument is structly equal to any of the subsequent args.
1768
+ * @param Value to test against subsequent arguments.
1769
+ * @return true if the first value matches any of subsequent values.
1770
+ */
1771
+ is.matching = is.match = is.inArgs = function(val) {
1772
+ if (arguments.length < 2)
1773
+ return false;
1774
+ var result = false;
1775
+ for (var i=1; i<arguments.length; i++) {
1776
+ var eq = is.equal(val, arguments[i]);
1777
+ result = result || eq;
1778
+ }
1779
+ return result;
1780
+ };
1781
+
1782
+
1783
+
1784
+ // US Address components
1785
+ /**********************************
1786
+ ***Definitely a work in progress***
1787
+ **********************************/
1788
+ /**
1789
+ * Test if a string contains a US street address
1790
+ * @param {String} the string to search
1791
+ * @return true if an address is present, false otherwise
1792
+ */
1793
+ is.streetAddress = function(str) {
1794
+ if (!is.str(str))
1795
+ return false;
1796
+
1797
+ var regex = /\b\d+[\s](?:[A-Za-z0-9.-]+[\s]+)+\b(ALLEY|ALY|AVENUE|AVE|BEND|BND|BLUFFS?|BLFS?|BOULEVARD|BLVD|BRANCH|BR|CENTERS?|CTRS?|CIRCLES?|CIRS?|CLIFFS?|CLFS?|COURTS?|CTS?|COVES?|CVS?|CREEK|CRK|CRESCENT|CRES|CREST|CRST|CROSSING|XING|DRIVES?|DRS?|EXPRESSWAY|EXPY|FREEWAY|FWY|HEIGHTS|HTS|HIGHWAY|HWY|HILLS?|HLS?|LANE|LN|LOOP|MANORS?|MNRS?|MOTORWAY|MTWY|MOUNT|MT|PARKS?|PARKWAYS?|PKWY|PASS|PLACE|PL|PLAZA|PLZ|POINTS?|PTS?|RIDGES?|RDGS?|ROADS?|RDS?|ROUTE|RTE?|SHOALS?|SHLS?|SHORES?|SHRS?|SPRINGS?|SPGS?|SPURS?|STREETS?|STS?|SUMMIT|SMT|TERRACE|TER|THROUGHWAY|TRWY|TRAFFICWAY|TRFY|TRAIL|TRL|TURNPIKE|TPKE|VALLEYS?|VLYS?|WAYS?)+(?:[\.\-\s\,]?)*((APARTMENT|APT|APPT|#|NUMBER|NUM|FLOOR|FL|\s)?(\d)*)\b/ig;
1798
+
1799
+ return regex.test(str);
1800
+ };
1801
+ is.street = is.address = is.streetAddress;
1802
+
1803
+ /**
1804
+ * Test if a string resembles a US Zip code,
1805
+ * no regular expression will be perfect for this,
1806
+ * as there are many numbers that aren't valid zip codes
1807
+ * @param {String || Number} the string or number literal to test
1808
+ * @return true if zipcode like, false otherwise
1809
+ */
1810
+ is.zipCode = function(str) {
1811
+ if (is.undefined(str) || !(is.string(str) || is.number(str)))
1812
+ return false;
1813
+
1814
+ var zip = /^\d{5}(?:-\d{4})?$/;
1815
+ return zip.test(str);
1816
+ };
1817
+ is.zip = is.zipCode;
1818
+
1819
+ /**
1820
+ * Test if a string contains a US phone number
1821
+ * @param {String} the string to search
1822
+ * @return true if str contains a phone number, false otherwise.
1823
+ */
1824
+ is.phoneNumber = function(str){
1825
+ if (!is.string(str))
1826
+ return false;
1827
+ var nums = /(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\(?)(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]‌​)\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\)?)\s*(?:[.-]\s*)?)?([2-9]1[02-‌​9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})/g;
1828
+ return nums.test(str);
1829
+ };
1830
+ is.phone = is.phoneNumber;
1831
+
1832
+ /**
1833
+ * Test is a string is a valid URL
1834
+ * @param {string} val - the possible url to check
1835
+ * @return true if str contains a phone number, false otherwise.
1836
+ */
1837
+ var isUrl = requireIsUrl();
1838
+ is.url = function(val) {
1839
+ return isUrl(val);
1840
+ };
1841
+ is.uri = is.url;
1842
+
1843
+ is.enumerator = function(val, ary){
1844
+ var value = false;
1845
+
1846
+ if (!is.defined(val) || !is.defined(ary) || !is.arrayLike(ary))
1847
+ return value;
1848
+
1849
+ for (var i = 0, len = ary.length; i < len; i++) {
1850
+ if (is.equal(val, ary[i])) {
1851
+ value = true;
1852
+ break;
1853
+ }
1854
+ }
1855
+ return value;
1856
+ };
1857
+ is.enum = is.inArray = is.enumerator;
1858
+ } (is2));
1859
+ return is2;
1860
+ }
1861
+
1862
+ var src = {exports: {}};
1863
+
1864
+ var browser = {exports: {}};
1865
+
1866
+ /**
1867
+ * Helpers.
1868
+ */
1869
+
1870
+ var ms;
1871
+ var hasRequiredMs;
1872
+
1873
+ function requireMs () {
1874
+ if (hasRequiredMs) return ms;
1875
+ hasRequiredMs = 1;
1876
+ var s = 1000;
1877
+ var m = s * 60;
1878
+ var h = m * 60;
1879
+ var d = h * 24;
1880
+ var w = d * 7;
1881
+ var y = d * 365.25;
1882
+
1883
+ /**
1884
+ * Parse or format the given `val`.
1885
+ *
1886
+ * Options:
1887
+ *
1888
+ * - `long` verbose formatting [false]
1889
+ *
1890
+ * @param {String|Number} val
1891
+ * @param {Object} [options]
1892
+ * @throws {Error} throw an error if val is not a non-empty string or a number
1893
+ * @return {String|Number}
1894
+ * @api public
1895
+ */
1896
+
1897
+ ms = function(val, options) {
1898
+ options = options || {};
1899
+ var type = typeof val;
1900
+ if (type === 'string' && val.length > 0) {
1901
+ return parse(val);
1902
+ } else if (type === 'number' && isFinite(val)) {
1903
+ return options.long ? fmtLong(val) : fmtShort(val);
1904
+ }
1905
+ throw new Error(
1906
+ 'val is not a non-empty string or a valid number. val=' +
1907
+ JSON.stringify(val)
1908
+ );
1909
+ };
1910
+
1911
+ /**
1912
+ * Parse the given `str` and return milliseconds.
1913
+ *
1914
+ * @param {String} str
1915
+ * @return {Number}
1916
+ * @api private
1917
+ */
1918
+
1919
+ function parse(str) {
1920
+ str = String(str);
1921
+ if (str.length > 100) {
1922
+ return;
1923
+ }
1924
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
1925
+ str
1926
+ );
1927
+ if (!match) {
1928
+ return;
1929
+ }
1930
+ var n = parseFloat(match[1]);
1931
+ var type = (match[2] || 'ms').toLowerCase();
1932
+ switch (type) {
1933
+ case 'years':
1934
+ case 'year':
1935
+ case 'yrs':
1936
+ case 'yr':
1937
+ case 'y':
1938
+ return n * y;
1939
+ case 'weeks':
1940
+ case 'week':
1941
+ case 'w':
1942
+ return n * w;
1943
+ case 'days':
1944
+ case 'day':
1945
+ case 'd':
1946
+ return n * d;
1947
+ case 'hours':
1948
+ case 'hour':
1949
+ case 'hrs':
1950
+ case 'hr':
1951
+ case 'h':
1952
+ return n * h;
1953
+ case 'minutes':
1954
+ case 'minute':
1955
+ case 'mins':
1956
+ case 'min':
1957
+ case 'm':
1958
+ return n * m;
1959
+ case 'seconds':
1960
+ case 'second':
1961
+ case 'secs':
1962
+ case 'sec':
1963
+ case 's':
1964
+ return n * s;
1965
+ case 'milliseconds':
1966
+ case 'millisecond':
1967
+ case 'msecs':
1968
+ case 'msec':
1969
+ case 'ms':
1970
+ return n;
1971
+ default:
1972
+ return undefined;
1973
+ }
1974
+ }
1975
+
1976
+ /**
1977
+ * Short format for `ms`.
1978
+ *
1979
+ * @param {Number} ms
1980
+ * @return {String}
1981
+ * @api private
1982
+ */
1983
+
1984
+ function fmtShort(ms) {
1985
+ var msAbs = Math.abs(ms);
1986
+ if (msAbs >= d) {
1987
+ return Math.round(ms / d) + 'd';
1988
+ }
1989
+ if (msAbs >= h) {
1990
+ return Math.round(ms / h) + 'h';
1991
+ }
1992
+ if (msAbs >= m) {
1993
+ return Math.round(ms / m) + 'm';
1994
+ }
1995
+ if (msAbs >= s) {
1996
+ return Math.round(ms / s) + 's';
1997
+ }
1998
+ return ms + 'ms';
1999
+ }
2000
+
2001
+ /**
2002
+ * Long format for `ms`.
2003
+ *
2004
+ * @param {Number} ms
2005
+ * @return {String}
2006
+ * @api private
2007
+ */
2008
+
2009
+ function fmtLong(ms) {
2010
+ var msAbs = Math.abs(ms);
2011
+ if (msAbs >= d) {
2012
+ return plural(ms, msAbs, d, 'day');
2013
+ }
2014
+ if (msAbs >= h) {
2015
+ return plural(ms, msAbs, h, 'hour');
2016
+ }
2017
+ if (msAbs >= m) {
2018
+ return plural(ms, msAbs, m, 'minute');
2019
+ }
2020
+ if (msAbs >= s) {
2021
+ return plural(ms, msAbs, s, 'second');
2022
+ }
2023
+ return ms + ' ms';
2024
+ }
2025
+
2026
+ /**
2027
+ * Pluralization helper.
2028
+ */
2029
+
2030
+ function plural(ms, msAbs, n, name) {
2031
+ var isPlural = msAbs >= n * 1.5;
2032
+ return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
2033
+ }
2034
+ return ms;
2035
+ }
2036
+
2037
+ var common$2;
2038
+ var hasRequiredCommon$2;
2039
+
2040
+ function requireCommon$2 () {
2041
+ if (hasRequiredCommon$2) return common$2;
2042
+ hasRequiredCommon$2 = 1;
2043
+ /**
2044
+ * This is the common logic for both the Node.js and web browser
2045
+ * implementations of `debug()`.
2046
+ */
2047
+
2048
+ function setup(env) {
2049
+ createDebug.debug = createDebug;
2050
+ createDebug.default = createDebug;
2051
+ createDebug.coerce = coerce;
2052
+ createDebug.disable = disable;
2053
+ createDebug.enable = enable;
2054
+ createDebug.enabled = enabled;
2055
+ createDebug.humanize = requireMs();
2056
+ createDebug.destroy = destroy;
2057
+
2058
+ Object.keys(env).forEach(key => {
2059
+ createDebug[key] = env[key];
2060
+ });
2061
+
2062
+ /**
2063
+ * The currently active debug mode names, and names to skip.
2064
+ */
2065
+
2066
+ createDebug.names = [];
2067
+ createDebug.skips = [];
2068
+
2069
+ /**
2070
+ * Map of special "%n" handling functions, for the debug "format" argument.
2071
+ *
2072
+ * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
2073
+ */
2074
+ createDebug.formatters = {};
2075
+
2076
+ /**
2077
+ * Selects a color for a debug namespace
2078
+ * @param {String} namespace The namespace string for the for the debug instance to be colored
2079
+ * @return {Number|String} An ANSI color code for the given namespace
2080
+ * @api private
2081
+ */
2082
+ function selectColor(namespace) {
2083
+ let hash = 0;
2084
+
2085
+ for (let i = 0; i < namespace.length; i++) {
2086
+ hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
2087
+ hash |= 0; // Convert to 32bit integer
2088
+ }
2089
+
2090
+ return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
2091
+ }
2092
+ createDebug.selectColor = selectColor;
2093
+
2094
+ /**
2095
+ * Create a debugger with the given `namespace`.
2096
+ *
2097
+ * @param {String} namespace
2098
+ * @return {Function}
2099
+ * @api public
2100
+ */
2101
+ function createDebug(namespace) {
2102
+ let prevTime;
2103
+ let enableOverride = null;
2104
+
2105
+ function debug(...args) {
2106
+ // Disabled?
2107
+ if (!debug.enabled) {
2108
+ return;
2109
+ }
2110
+
2111
+ const self = debug;
2112
+
2113
+ // Set `diff` timestamp
2114
+ const curr = Number(new Date());
2115
+ const ms = curr - (prevTime || curr);
2116
+ self.diff = ms;
2117
+ self.prev = prevTime;
2118
+ self.curr = curr;
2119
+ prevTime = curr;
2120
+
2121
+ args[0] = createDebug.coerce(args[0]);
2122
+
2123
+ if (typeof args[0] !== 'string') {
2124
+ // Anything else let's inspect with %O
2125
+ args.unshift('%O');
2126
+ }
2127
+
2128
+ // Apply any `formatters` transformations
2129
+ let index = 0;
2130
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
2131
+ // If we encounter an escaped % then don't increase the array index
2132
+ if (match === '%%') {
2133
+ return '%';
2134
+ }
2135
+ index++;
2136
+ const formatter = createDebug.formatters[format];
2137
+ if (typeof formatter === 'function') {
2138
+ const val = args[index];
2139
+ match = formatter.call(self, val);
2140
+
2141
+ // Now we need to remove `args[index]` since it's inlined in the `format`
2142
+ args.splice(index, 1);
2143
+ index--;
2144
+ }
2145
+ return match;
2146
+ });
2147
+
2148
+ // Apply env-specific formatting (colors, etc.)
2149
+ createDebug.formatArgs.call(self, args);
2150
+
2151
+ const logFn = self.log || createDebug.log;
2152
+ logFn.apply(self, args);
2153
+ }
2154
+
2155
+ debug.namespace = namespace;
2156
+ debug.useColors = createDebug.useColors();
2157
+ debug.color = createDebug.selectColor(namespace);
2158
+ debug.extend = extend;
2159
+ debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
2160
+
2161
+ Object.defineProperty(debug, 'enabled', {
2162
+ enumerable: true,
2163
+ configurable: false,
2164
+ get: () => enableOverride === null ? createDebug.enabled(namespace) : enableOverride,
2165
+ set: v => {
2166
+ enableOverride = v;
2167
+ }
2168
+ });
2169
+
2170
+ // Env-specific initialization logic for debug instances
2171
+ if (typeof createDebug.init === 'function') {
2172
+ createDebug.init(debug);
2173
+ }
2174
+
2175
+ return debug;
2176
+ }
2177
+
2178
+ function extend(namespace, delimiter) {
2179
+ const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
2180
+ newDebug.log = this.log;
2181
+ return newDebug;
2182
+ }
2183
+
2184
+ /**
2185
+ * Enables a debug mode by namespaces. This can include modes
2186
+ * separated by a colon and wildcards.
2187
+ *
2188
+ * @param {String} namespaces
2189
+ * @api public
2190
+ */
2191
+ function enable(namespaces) {
2192
+ createDebug.save(namespaces);
2193
+
2194
+ createDebug.names = [];
2195
+ createDebug.skips = [];
2196
+
2197
+ let i;
2198
+ const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
2199
+ const len = split.length;
2200
+
2201
+ for (i = 0; i < len; i++) {
2202
+ if (!split[i]) {
2203
+ // ignore empty strings
2204
+ continue;
2205
+ }
2206
+
2207
+ namespaces = split[i].replace(/\*/g, '.*?');
2208
+
2209
+ if (namespaces[0] === '-') {
2210
+ createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
2211
+ } else {
2212
+ createDebug.names.push(new RegExp('^' + namespaces + '$'));
2213
+ }
2214
+ }
2215
+ }
2216
+
2217
+ /**
2218
+ * Disable debug output.
2219
+ *
2220
+ * @return {String} namespaces
2221
+ * @api public
2222
+ */
2223
+ function disable() {
2224
+ const namespaces = [
2225
+ ...createDebug.names.map(toNamespace),
2226
+ ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
2227
+ ].join(',');
2228
+ createDebug.enable('');
2229
+ return namespaces;
2230
+ }
2231
+
2232
+ /**
2233
+ * Returns true if the given mode name is enabled, false otherwise.
2234
+ *
2235
+ * @param {String} name
2236
+ * @return {Boolean}
2237
+ * @api public
2238
+ */
2239
+ function enabled(name) {
2240
+ if (name[name.length - 1] === '*') {
2241
+ return true;
2242
+ }
2243
+
2244
+ let i;
2245
+ let len;
2246
+
2247
+ for (i = 0, len = createDebug.skips.length; i < len; i++) {
2248
+ if (createDebug.skips[i].test(name)) {
2249
+ return false;
2250
+ }
2251
+ }
2252
+
2253
+ for (i = 0, len = createDebug.names.length; i < len; i++) {
2254
+ if (createDebug.names[i].test(name)) {
2255
+ return true;
2256
+ }
2257
+ }
2258
+
2259
+ return false;
2260
+ }
2261
+
2262
+ /**
2263
+ * Convert regexp to namespace
2264
+ *
2265
+ * @param {RegExp} regxep
2266
+ * @return {String} namespace
2267
+ * @api private
2268
+ */
2269
+ function toNamespace(regexp) {
2270
+ return regexp.toString()
2271
+ .substring(2, regexp.toString().length - 2)
2272
+ .replace(/\.\*\?$/, '*');
2273
+ }
2274
+
2275
+ /**
2276
+ * Coerce `val`.
2277
+ *
2278
+ * @param {Mixed} val
2279
+ * @return {Mixed}
2280
+ * @api private
2281
+ */
2282
+ function coerce(val) {
2283
+ if (val instanceof Error) {
2284
+ return val.stack || val.message;
2285
+ }
2286
+ return val;
2287
+ }
2288
+
2289
+ /**
2290
+ * XXX DO NOT USE. This is a temporary stub function.
2291
+ * XXX It WILL be removed in the next major release.
2292
+ */
2293
+ function destroy() {
2294
+ console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
2295
+ }
2296
+
2297
+ createDebug.enable(createDebug.load());
2298
+
2299
+ return createDebug;
2300
+ }
2301
+
2302
+ common$2 = setup;
2303
+ return common$2;
2304
+ }
2305
+
2306
+ /* eslint-env browser */
2307
+
2308
+ var hasRequiredBrowser;
2309
+
2310
+ function requireBrowser () {
2311
+ if (hasRequiredBrowser) return browser.exports;
2312
+ hasRequiredBrowser = 1;
2313
+ (function (module, exports) {
2314
+ /**
2315
+ * This is the web browser implementation of `debug()`.
2316
+ */
2317
+
2318
+ exports.formatArgs = formatArgs;
2319
+ exports.save = save;
2320
+ exports.load = load;
2321
+ exports.useColors = useColors;
2322
+ exports.storage = localstorage();
2323
+ exports.destroy = (() => {
2324
+ let warned = false;
2325
+
2326
+ return () => {
2327
+ if (!warned) {
2328
+ warned = true;
2329
+ console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
2330
+ }
2331
+ };
2332
+ })();
2333
+
2334
+ /**
2335
+ * Colors.
2336
+ */
2337
+
2338
+ exports.colors = [
2339
+ '#0000CC',
2340
+ '#0000FF',
2341
+ '#0033CC',
2342
+ '#0033FF',
2343
+ '#0066CC',
2344
+ '#0066FF',
2345
+ '#0099CC',
2346
+ '#0099FF',
2347
+ '#00CC00',
2348
+ '#00CC33',
2349
+ '#00CC66',
2350
+ '#00CC99',
2351
+ '#00CCCC',
2352
+ '#00CCFF',
2353
+ '#3300CC',
2354
+ '#3300FF',
2355
+ '#3333CC',
2356
+ '#3333FF',
2357
+ '#3366CC',
2358
+ '#3366FF',
2359
+ '#3399CC',
2360
+ '#3399FF',
2361
+ '#33CC00',
2362
+ '#33CC33',
2363
+ '#33CC66',
2364
+ '#33CC99',
2365
+ '#33CCCC',
2366
+ '#33CCFF',
2367
+ '#6600CC',
2368
+ '#6600FF',
2369
+ '#6633CC',
2370
+ '#6633FF',
2371
+ '#66CC00',
2372
+ '#66CC33',
2373
+ '#9900CC',
2374
+ '#9900FF',
2375
+ '#9933CC',
2376
+ '#9933FF',
2377
+ '#99CC00',
2378
+ '#99CC33',
2379
+ '#CC0000',
2380
+ '#CC0033',
2381
+ '#CC0066',
2382
+ '#CC0099',
2383
+ '#CC00CC',
2384
+ '#CC00FF',
2385
+ '#CC3300',
2386
+ '#CC3333',
2387
+ '#CC3366',
2388
+ '#CC3399',
2389
+ '#CC33CC',
2390
+ '#CC33FF',
2391
+ '#CC6600',
2392
+ '#CC6633',
2393
+ '#CC9900',
2394
+ '#CC9933',
2395
+ '#CCCC00',
2396
+ '#CCCC33',
2397
+ '#FF0000',
2398
+ '#FF0033',
2399
+ '#FF0066',
2400
+ '#FF0099',
2401
+ '#FF00CC',
2402
+ '#FF00FF',
2403
+ '#FF3300',
2404
+ '#FF3333',
2405
+ '#FF3366',
2406
+ '#FF3399',
2407
+ '#FF33CC',
2408
+ '#FF33FF',
2409
+ '#FF6600',
2410
+ '#FF6633',
2411
+ '#FF9900',
2412
+ '#FF9933',
2413
+ '#FFCC00',
2414
+ '#FFCC33'
2415
+ ];
2416
+
2417
+ /**
2418
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
2419
+ * and the Firebug extension (any Firefox version) are known
2420
+ * to support "%c" CSS customizations.
2421
+ *
2422
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
2423
+ */
2424
+
2425
+ // eslint-disable-next-line complexity
2426
+ function useColors() {
2427
+ // NB: In an Electron preload script, document will be defined but not fully
2428
+ // initialized. Since we know we're in Chrome, we'll just detect this case
2429
+ // explicitly
2430
+ if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
2431
+ return true;
2432
+ }
2433
+
2434
+ // Internet Explorer and Edge do not support colors.
2435
+ if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
2436
+ return false;
2437
+ }
2438
+
2439
+ // Is webkit? http://stackoverflow.com/a/16459606/376773
2440
+ // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
2441
+ return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
2442
+ // Is firebug? http://stackoverflow.com/a/398120/376773
2443
+ (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
2444
+ // Is firefox >= v31?
2445
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
2446
+ (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
2447
+ // Double check webkit in userAgent just in case we are in a worker
2448
+ (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
2449
+ }
2450
+
2451
+ /**
2452
+ * Colorize log arguments if enabled.
2453
+ *
2454
+ * @api public
2455
+ */
2456
+
2457
+ function formatArgs(args) {
2458
+ args[0] = (this.useColors ? '%c' : '') +
2459
+ this.namespace +
2460
+ (this.useColors ? ' %c' : ' ') +
2461
+ args[0] +
2462
+ (this.useColors ? '%c ' : ' ') +
2463
+ '+' + module.exports.humanize(this.diff);
2464
+
2465
+ if (!this.useColors) {
2466
+ return;
2467
+ }
2468
+
2469
+ const c = 'color: ' + this.color;
2470
+ args.splice(1, 0, c, 'color: inherit');
2471
+
2472
+ // The final "%c" is somewhat tricky, because there could be other
2473
+ // arguments passed either before or after the %c, so we need to
2474
+ // figure out the correct index to insert the CSS into
2475
+ let index = 0;
2476
+ let lastC = 0;
2477
+ args[0].replace(/%[a-zA-Z%]/g, match => {
2478
+ if (match === '%%') {
2479
+ return;
2480
+ }
2481
+ index++;
2482
+ if (match === '%c') {
2483
+ // We only are interested in the *last* %c
2484
+ // (the user may have provided their own)
2485
+ lastC = index;
2486
+ }
2487
+ });
2488
+
2489
+ args.splice(lastC, 0, c);
2490
+ }
2491
+
2492
+ /**
2493
+ * Invokes `console.debug()` when available.
2494
+ * No-op when `console.debug` is not a "function".
2495
+ * If `console.debug` is not available, falls back
2496
+ * to `console.log`.
2497
+ *
2498
+ * @api public
2499
+ */
2500
+ exports.log = console.debug || console.log || (() => {});
2501
+
2502
+ /**
2503
+ * Save `namespaces`.
2504
+ *
2505
+ * @param {String} namespaces
2506
+ * @api private
2507
+ */
2508
+ function save(namespaces) {
2509
+ try {
2510
+ if (namespaces) {
2511
+ exports.storage.setItem('debug', namespaces);
2512
+ } else {
2513
+ exports.storage.removeItem('debug');
2514
+ }
2515
+ } catch (error) {
2516
+ // Swallow
2517
+ // XXX (@Qix-) should we be logging these?
2518
+ }
2519
+ }
2520
+
2521
+ /**
2522
+ * Load `namespaces`.
2523
+ *
2524
+ * @return {String} returns the previously persisted debug modes
2525
+ * @api private
2526
+ */
2527
+ function load() {
2528
+ let r;
2529
+ try {
2530
+ r = exports.storage.getItem('debug');
2531
+ } catch (error) {
2532
+ // Swallow
2533
+ // XXX (@Qix-) should we be logging these?
2534
+ }
2535
+
2536
+ // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
2537
+ if (!r && typeof process !== 'undefined' && 'env' in process) {
2538
+ r = process.env.DEBUG;
2539
+ }
2540
+
2541
+ return r;
2542
+ }
2543
+
2544
+ /**
2545
+ * Localstorage attempts to return the localstorage.
2546
+ *
2547
+ * This is necessary because safari throws
2548
+ * when a user disables cookies/localstorage
2549
+ * and you attempt to access it.
2550
+ *
2551
+ * @return {LocalStorage}
2552
+ * @api private
2553
+ */
2554
+
2555
+ function localstorage() {
2556
+ try {
2557
+ // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
2558
+ // The Browser also has localStorage in the global context.
2559
+ return localStorage;
2560
+ } catch (error) {
2561
+ // Swallow
2562
+ // XXX (@Qix-) should we be logging these?
2563
+ }
2564
+ }
2565
+
2566
+ module.exports = requireCommon$2()(exports);
2567
+
2568
+ const {formatters} = module.exports;
2569
+
2570
+ /**
2571
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
2572
+ */
2573
+
2574
+ formatters.j = function (v) {
2575
+ try {
2576
+ return JSON.stringify(v);
2577
+ } catch (error) {
2578
+ return '[UnexpectedJSONParseError]: ' + error.message;
2579
+ }
2580
+ };
2581
+ } (browser, browser.exports));
2582
+ return browser.exports;
2583
+ }
2584
+
2585
+ var node = {exports: {}};
2586
+
2587
+ /**
2588
+ * Module dependencies.
2589
+ */
2590
+
2591
+ var hasRequiredNode;
2592
+
2593
+ function requireNode () {
2594
+ if (hasRequiredNode) return node.exports;
2595
+ hasRequiredNode = 1;
2596
+ (function (module, exports) {
2597
+ const tty = require$$0$1;
2598
+ const util = require$$0;
2599
+
2600
+ /**
2601
+ * This is the Node.js implementation of `debug()`.
2602
+ */
2603
+
2604
+ exports.init = init;
2605
+ exports.log = log;
2606
+ exports.formatArgs = formatArgs;
2607
+ exports.save = save;
2608
+ exports.load = load;
2609
+ exports.useColors = useColors;
2610
+ exports.destroy = util.deprecate(
2611
+ () => {},
2612
+ 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
2613
+ );
2614
+
2615
+ /**
2616
+ * Colors.
2617
+ */
2618
+
2619
+ exports.colors = [6, 2, 3, 4, 5, 1];
2620
+
2621
+ try {
2622
+ // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
2623
+ // eslint-disable-next-line import/no-extraneous-dependencies
2624
+ const supportsColor = require('supports-color');
2625
+
2626
+ if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
2627
+ exports.colors = [
2628
+ 20,
2629
+ 21,
2630
+ 26,
2631
+ 27,
2632
+ 32,
2633
+ 33,
2634
+ 38,
2635
+ 39,
2636
+ 40,
2637
+ 41,
2638
+ 42,
2639
+ 43,
2640
+ 44,
2641
+ 45,
2642
+ 56,
2643
+ 57,
2644
+ 62,
2645
+ 63,
2646
+ 68,
2647
+ 69,
2648
+ 74,
2649
+ 75,
2650
+ 76,
2651
+ 77,
2652
+ 78,
2653
+ 79,
2654
+ 80,
2655
+ 81,
2656
+ 92,
2657
+ 93,
2658
+ 98,
2659
+ 99,
2660
+ 112,
2661
+ 113,
2662
+ 128,
2663
+ 129,
2664
+ 134,
2665
+ 135,
2666
+ 148,
2667
+ 149,
2668
+ 160,
2669
+ 161,
2670
+ 162,
2671
+ 163,
2672
+ 164,
2673
+ 165,
2674
+ 166,
2675
+ 167,
2676
+ 168,
2677
+ 169,
2678
+ 170,
2679
+ 171,
2680
+ 172,
2681
+ 173,
2682
+ 178,
2683
+ 179,
2684
+ 184,
2685
+ 185,
2686
+ 196,
2687
+ 197,
2688
+ 198,
2689
+ 199,
2690
+ 200,
2691
+ 201,
2692
+ 202,
2693
+ 203,
2694
+ 204,
2695
+ 205,
2696
+ 206,
2697
+ 207,
2698
+ 208,
2699
+ 209,
2700
+ 214,
2701
+ 215,
2702
+ 220,
2703
+ 221
2704
+ ];
2705
+ }
2706
+ } catch (error) {
2707
+ // Swallow - we only care if `supports-color` is available; it doesn't have to be.
2708
+ }
2709
+
2710
+ /**
2711
+ * Build up the default `inspectOpts` object from the environment variables.
2712
+ *
2713
+ * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
2714
+ */
2715
+
2716
+ exports.inspectOpts = Object.keys(process.env).filter(key => {
2717
+ return /^debug_/i.test(key);
2718
+ }).reduce((obj, key) => {
2719
+ // Camel-case
2720
+ const prop = key
2721
+ .substring(6)
2722
+ .toLowerCase()
2723
+ .replace(/_([a-z])/g, (_, k) => {
2724
+ return k.toUpperCase();
2725
+ });
2726
+
2727
+ // Coerce string value into JS value
2728
+ let val = process.env[key];
2729
+ if (/^(yes|on|true|enabled)$/i.test(val)) {
2730
+ val = true;
2731
+ } else if (/^(no|off|false|disabled)$/i.test(val)) {
2732
+ val = false;
2733
+ } else if (val === 'null') {
2734
+ val = null;
2735
+ } else {
2736
+ val = Number(val);
2737
+ }
2738
+
2739
+ obj[prop] = val;
2740
+ return obj;
2741
+ }, {});
2742
+
2743
+ /**
2744
+ * Is stdout a TTY? Colored output is enabled when `true`.
2745
+ */
2746
+
2747
+ function useColors() {
2748
+ return 'colors' in exports.inspectOpts ?
2749
+ Boolean(exports.inspectOpts.colors) :
2750
+ tty.isatty(process.stderr.fd);
2751
+ }
2752
+
2753
+ /**
2754
+ * Adds ANSI color escape codes if enabled.
2755
+ *
2756
+ * @api public
2757
+ */
2758
+
2759
+ function formatArgs(args) {
2760
+ const {namespace: name, useColors} = this;
2761
+
2762
+ if (useColors) {
2763
+ const c = this.color;
2764
+ const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
2765
+ const prefix = ` ${colorCode};1m${name} \u001B[0m`;
2766
+
2767
+ args[0] = prefix + args[0].split('\n').join('\n' + prefix);
2768
+ args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
2769
+ } else {
2770
+ args[0] = getDate() + name + ' ' + args[0];
2771
+ }
2772
+ }
2773
+
2774
+ function getDate() {
2775
+ if (exports.inspectOpts.hideDate) {
2776
+ return '';
2777
+ }
2778
+ return new Date().toISOString() + ' ';
2779
+ }
2780
+
2781
+ /**
2782
+ * Invokes `util.format()` with the specified arguments and writes to stderr.
2783
+ */
2784
+
2785
+ function log(...args) {
2786
+ return process.stderr.write(util.format(...args) + '\n');
2787
+ }
2788
+
2789
+ /**
2790
+ * Save `namespaces`.
2791
+ *
2792
+ * @param {String} namespaces
2793
+ * @api private
2794
+ */
2795
+ function save(namespaces) {
2796
+ if (namespaces) {
2797
+ process.env.DEBUG = namespaces;
2798
+ } else {
2799
+ // If you set a process.env field to null or undefined, it gets cast to the
2800
+ // string 'null' or 'undefined'. Just delete instead.
2801
+ delete process.env.DEBUG;
2802
+ }
2803
+ }
2804
+
2805
+ /**
2806
+ * Load `namespaces`.
2807
+ *
2808
+ * @return {String} returns the previously persisted debug modes
2809
+ * @api private
2810
+ */
2811
+
2812
+ function load() {
2813
+ return process.env.DEBUG;
2814
+ }
2815
+
2816
+ /**
2817
+ * Init logic for `debug` instances.
2818
+ *
2819
+ * Create a new `inspectOpts` object in case `useColors` is set
2820
+ * differently for a particular `debug` instance.
2821
+ */
2822
+
2823
+ function init(debug) {
2824
+ debug.inspectOpts = {};
2825
+
2826
+ const keys = Object.keys(exports.inspectOpts);
2827
+ for (let i = 0; i < keys.length; i++) {
2828
+ debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
2829
+ }
2830
+ }
2831
+
2832
+ module.exports = requireCommon$2()(exports);
2833
+
2834
+ const {formatters} = module.exports;
2835
+
2836
+ /**
2837
+ * Map %o to `util.inspect()`, all on a single line.
2838
+ */
2839
+
2840
+ formatters.o = function (v) {
2841
+ this.inspectOpts.colors = this.useColors;
2842
+ return util.inspect(v, this.inspectOpts)
2843
+ .split('\n')
2844
+ .map(str => str.trim())
2845
+ .join(' ');
2846
+ };
2847
+
2848
+ /**
2849
+ * Map %O to `util.inspect()`, allowing multiple lines if needed.
2850
+ */
2851
+
2852
+ formatters.O = function (v) {
2853
+ this.inspectOpts.colors = this.useColors;
2854
+ return util.inspect(v, this.inspectOpts);
2855
+ };
2856
+ } (node, node.exports));
2857
+ return node.exports;
2858
+ }
2859
+
2860
+ /**
2861
+ * Detect Electron renderer / nwjs process, which is node, but we should
2862
+ * treat as a browser.
2863
+ */
2864
+
2865
+ var hasRequiredSrc;
2866
+
2867
+ function requireSrc () {
2868
+ if (hasRequiredSrc) return src.exports;
2869
+ hasRequiredSrc = 1;
2870
+ if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
2871
+ src.exports = requireBrowser();
2872
+ } else {
2873
+ src.exports = requireNode();
2874
+ }
2875
+ return src.exports;
2876
+ }
2877
+
2878
+ /**
2879
+ * @fileOverview
2880
+ * A simple promises-based check to see if a TCP port is already in use.
2881
+ */
2882
+
2883
+ var hasRequiredTcpPortUsed;
2884
+
2885
+ function requireTcpPortUsed () {
2886
+ if (hasRequiredTcpPortUsed) return tcpPortUsed$1;
2887
+ hasRequiredTcpPortUsed = 1;
2888
+
2889
+ // define the exports first to avoid cyclic dependencies.
2890
+ tcpPortUsed$1.check = check;
2891
+ tcpPortUsed$1.waitUntilFreeOnHost = waitUntilFreeOnHost;
2892
+ tcpPortUsed$1.waitUntilFree = waitUntilFree;
2893
+ tcpPortUsed$1.waitUntilUsedOnHost = waitUntilUsedOnHost;
2894
+ tcpPortUsed$1.waitUntilUsed = waitUntilUsed;
2895
+ tcpPortUsed$1.waitForStatus = waitForStatus;
2896
+
2897
+ var is = requireIs2();
2898
+ var net = require$$1;
2899
+ var util = require$$0;
2900
+ var debug = requireSrc()('tcp-port-used');
2901
+
2902
+ // Global Values
2903
+ var TIMEOUT = 2000;
2904
+ var RETRYTIME = 250;
2905
+
2906
+ function getDeferred() {
2907
+ var resolve, reject, promise = new Promise(function(res, rej) {
2908
+ resolve = res;
2909
+ reject = rej;
2910
+ });
2911
+
2912
+ return {
2913
+ resolve: resolve,
2914
+ reject: reject,
2915
+ promise: promise
2916
+ };
2917
+ }
2918
+
2919
+ /**
2920
+ * Creates an options object from all the possible arguments
2921
+ * @private
2922
+ * @param {Number} port a valid TCP port number
2923
+ * @param {String} host The DNS name or IP address.
2924
+ * @param {Boolean} status The desired in use status to wait for: false === not in use, true === in use
2925
+ * @param {Number} retryTimeMs the retry interval in milliseconds - defaultis is 200ms
2926
+ * @param {Number} timeOutMs the amount of time to wait until port is free default is 1000ms
2927
+ * @return {Object} An options object with all the above parameters as properties.
2928
+ */
2929
+ function makeOptionsObj(port, host, inUse, retryTimeMs, timeOutMs) {
2930
+ var opts = {};
2931
+ opts.port = port;
2932
+ opts.host = host;
2933
+ opts.inUse = inUse;
2934
+ opts.retryTimeMs = retryTimeMs;
2935
+ opts.timeOutMs = timeOutMs;
2936
+ return opts;
2937
+ }
2938
+
2939
+ /**
2940
+ * Checks if a TCP port is in use by creating the socket and binding it to the
2941
+ * target port. Once bound, successfully, it's assume the port is availble.
2942
+ * After the socket is closed or in error, the promise is resolved.
2943
+ * Note: you have to be super user to correctly test system ports (0-1023).
2944
+ * @param {Number|Object} port The port you are curious to see if available. If an object, must have the parameters as properties.
2945
+ * @param {String} [host] May be a DNS name or IP address. Default '127.0.0.1'
2946
+ * @return {Object} A deferred Q promise.
2947
+ *
2948
+ * Example usage:
2949
+ *
2950
+ * var tcpPortUsed = require('tcp-port-used');
2951
+ * tcpPortUsed.check(22, '127.0.0.1')
2952
+ * .then(function(inUse) {
2953
+ * debug('Port 22 usage: '+inUse);
2954
+ * }, function(err) {
2955
+ * console.error('Error on check: '+util.inspect(err));
2956
+ * });
2957
+ */
2958
+ function check(port, host) {
2959
+
2960
+ var deferred = getDeferred();
2961
+ var inUse = true;
2962
+ var client;
2963
+
2964
+ var opts;
2965
+ if (!is.obj(port)) {
2966
+ opts = makeOptionsObj(port, host);
2967
+ } else {
2968
+ opts = port;
2969
+ }
2970
+
2971
+ if (!is.port(opts.port)) {
2972
+ debug('Error invalid port: '+util.inspect(opts.port));
2973
+ deferred.reject(new Error('invalid port: '+util.inspect(opts.port)));
2974
+ return deferred.promise;
2975
+ }
2976
+
2977
+ if (is.nullOrUndefined(opts.host)) {
2978
+ debug('set host address to default 127.0.0.1');
2979
+ opts.host = '127.0.0.1';
2980
+ }
2981
+
2982
+ function cleanUp() {
2983
+ if (client) {
2984
+ client.removeAllListeners('connect');
2985
+ client.removeAllListeners('error');
2986
+ client.end();
2987
+ client.destroy();
2988
+ client.unref();
2989
+ }
2990
+ //debug('listeners removed from client socket');
2991
+ }
2992
+
2993
+ function onConnectCb() {
2994
+ //debug('check - promise resolved - in use');
2995
+ deferred.resolve(inUse);
2996
+ cleanUp();
2997
+ }
2998
+
2999
+ function onErrorCb(err) {
3000
+ if (err.code !== 'ECONNREFUSED') {
3001
+ //debug('check - promise rejected, error: '+err.message);
3002
+ deferred.reject(err);
3003
+ } else {
3004
+ //debug('ECONNREFUSED');
3005
+ inUse = false;
3006
+ //debug('check - promise resolved - not in use');
3007
+ deferred.resolve(inUse);
3008
+ }
3009
+ cleanUp();
3010
+ }
3011
+
3012
+ client = new net.Socket();
3013
+ client.once('connect', onConnectCb);
3014
+ client.once('error', onErrorCb);
3015
+ client.connect({port: opts.port, host: opts.host}, function() {});
3016
+
3017
+ return deferred.promise;
3018
+ }
3019
+
3020
+ /**
3021
+ * Creates a deferred promise and fulfills it only when the socket's usage
3022
+ * equals status in terms of 'in use' (false === not in use, true === in use).
3023
+ * Will retry on an interval specified in retryTimeMs. Note: you have to be
3024
+ * super user to correctly test system ports (0-1023).
3025
+ * @param {Number|Object} port a valid TCP port number, if an object, has all the parameters described as properties.
3026
+ * @param {String} host The DNS name or IP address.
3027
+ * @param {Boolean} status The desired in use status to wait for false === not in use, true === in use
3028
+ * @param {Number} [retryTimeMs] the retry interval in milliseconds - defaultis is 200ms
3029
+ * @param {Number} [timeOutMs] the amount of time to wait until port is free default is 1000ms
3030
+ * @return {Object} A deferred promise from the Q library.
3031
+ *
3032
+ * Example usage:
3033
+ *
3034
+ * var tcpPortUsed = require('tcp-port-used');
3035
+ * tcpPortUsed.waitForStatus(44204, 'some.host.com', true, 500, 4000)
3036
+ * .then(function() {
3037
+ * console.log('Port 44204 is now in use.');
3038
+ * }, function(err) {
3039
+ * console.log('Error: ', error.message);
3040
+ * });
3041
+ */
3042
+ function waitForStatus(port, host, inUse, retryTimeMs, timeOutMs) {
3043
+
3044
+ var deferred = getDeferred();
3045
+ var timeoutId;
3046
+ var timedout = false;
3047
+ var retryId;
3048
+
3049
+ // the first arument may be an object, if it is not, make an object
3050
+ var opts;
3051
+ if (is.obj(port)) {
3052
+ opts = port;
3053
+ } else {
3054
+ opts = makeOptionsObj(port, host, inUse, retryTimeMs, timeOutMs);
3055
+ }
3056
+
3057
+ //debug('opts:'+util.inspect(opts);
3058
+
3059
+ if (!is.bool(opts.inUse)) {
3060
+ deferred.reject(new Error('inUse must be a boolean'));
3061
+ return deferred.promise;
3062
+ }
3063
+
3064
+ if (!is.positiveInt(opts.retryTimeMs)) {
3065
+ opts.retryTimeMs = RETRYTIME;
3066
+ debug('set retryTime to default '+RETRYTIME+'ms');
3067
+ }
3068
+
3069
+ if (!is.positiveInt(opts.timeOutMs)) {
3070
+ opts.timeOutMs = TIMEOUT;
3071
+ debug('set timeOutMs to default '+TIMEOUT+'ms');
3072
+ }
3073
+
3074
+ function cleanUp() {
3075
+ if (timeoutId) {
3076
+ clearTimeout(timeoutId);
3077
+ }
3078
+ if (retryId) {
3079
+ clearTimeout(retryId);
3080
+ }
3081
+ }
3082
+
3083
+ function timeoutFunc() {
3084
+ timedout = true;
3085
+ cleanUp();
3086
+ deferred.reject(new Error('timeout'));
3087
+ }
3088
+ timeoutId = setTimeout(timeoutFunc, opts.timeOutMs);
3089
+
3090
+ function doCheck() {
3091
+ check(opts.port, opts.host)
3092
+ .then(function(inUse) {
3093
+ if (timedout) {
3094
+ return;
3095
+ }
3096
+ //debug('doCheck inUse: '+inUse);
3097
+ //debug('doCheck opts.inUse: '+opts.inUse);
3098
+ if (inUse === opts.inUse) {
3099
+ deferred.resolve();
3100
+ cleanUp();
3101
+ return;
3102
+ } else {
3103
+ retryId = setTimeout(function() { doCheck(); }, opts.retryTimeMs);
3104
+ return;
3105
+ }
3106
+ }, function(err) {
3107
+ if (timedout) {
3108
+ return;
3109
+ }
3110
+ deferred.reject(err);
3111
+ cleanUp();
3112
+ });
3113
+ }
3114
+
3115
+ doCheck();
3116
+ return deferred.promise;
3117
+ }
3118
+
3119
+ /**
3120
+ * Creates a deferred promise and fulfills it only when the socket is free.
3121
+ * Will retry on an interval specified in retryTimeMs.
3122
+ * Note: you have to be super user to correctly test system ports (0-1023).
3123
+ * @param {Number} port a valid TCP port number
3124
+ * @param {String} [host] The hostname or IP address of where the socket is.
3125
+ * @param {Number} [retryTimeMs] the retry interval in milliseconds - defaultis is 100ms.
3126
+ * @param {Number} [timeOutMs] the amount of time to wait until port is free. Default 300ms.
3127
+ * @return {Object} A deferred promise from the q library.
3128
+ *
3129
+ * Example usage:
3130
+ *
3131
+ * var tcpPortUsed = require('tcp-port-used');
3132
+ * tcpPortUsed.waitUntilFreeOnHost(44203, 'some.host.com', 500, 4000)
3133
+ * .then(function() {
3134
+ * console.log('Port 44203 is now free.');
3135
+ * }, function(err) {
3136
+ * console.loh('Error: ', error.message);
3137
+ * });
3138
+ */
3139
+ function waitUntilFreeOnHost(port, host, retryTimeMs, timeOutMs) {
3140
+
3141
+ // the first arument may be an object, if it is not, make an object
3142
+ var opts;
3143
+ if (is.obj(port)) {
3144
+ opts = port;
3145
+ opts.inUse = false;
3146
+ } else {
3147
+ opts = makeOptionsObj(port, host, false, retryTimeMs, timeOutMs);
3148
+ }
3149
+
3150
+ return waitForStatus(opts);
3151
+ }
91
3152
 
92
- black: f("\x1b[30m", "\x1b[39m"),
93
- red: f("\x1b[31m", "\x1b[39m"),
94
- green: f("\x1b[32m", "\x1b[39m"),
95
- yellow: f("\x1b[33m", "\x1b[39m"),
96
- blue: f("\x1b[34m", "\x1b[39m"),
97
- magenta: f("\x1b[35m", "\x1b[39m"),
98
- cyan: f("\x1b[36m", "\x1b[39m"),
99
- white: f("\x1b[37m", "\x1b[39m"),
100
- gray: f("\x1b[90m", "\x1b[39m"),
3153
+ /**
3154
+ * For compatibility with previous version of the module, that did not provide
3155
+ * arguements for hostnames. The host is set to the localhost '127.0.0.1'.
3156
+ * @param {Number|Object} port a valid TCP port number. If an object, must contain all the parameters as properties.
3157
+ * @param {Number} [retryTimeMs] the retry interval in milliseconds - defaultis is 100ms.
3158
+ * @param {Number} [timeOutMs] the amount of time to wait until port is free. Default 300ms.
3159
+ * @return {Object} A deferred promise from the q library.
3160
+ *
3161
+ * Example usage:
3162
+ *
3163
+ * var tcpPortUsed = require('tcp-port-used');
3164
+ * tcpPortUsed.waitUntilFree(44203, 500, 4000)
3165
+ * .then(function() {
3166
+ * console.log('Port 44203 is now free.');
3167
+ * }, function(err) {
3168
+ * console.loh('Error: ', error.message);
3169
+ * });
3170
+ */
3171
+ function waitUntilFree(port, retryTimeMs, timeOutMs) {
3172
+
3173
+ // the first arument may be an object, if it is not, make an object
3174
+ var opts;
3175
+ if (is.obj(port)) {
3176
+ opts = port;
3177
+ opts.host = '127.0.0.1';
3178
+ opts.inUse = false;
3179
+ } else {
3180
+ opts = makeOptionsObj(port, '127.0.0.1', false, retryTimeMs, timeOutMs);
3181
+ }
101
3182
 
102
- bgBlack: f("\x1b[40m", "\x1b[49m"),
103
- bgRed: f("\x1b[41m", "\x1b[49m"),
104
- bgGreen: f("\x1b[42m", "\x1b[49m"),
105
- bgYellow: f("\x1b[43m", "\x1b[49m"),
106
- bgBlue: f("\x1b[44m", "\x1b[49m"),
107
- bgMagenta: f("\x1b[45m", "\x1b[49m"),
108
- bgCyan: f("\x1b[46m", "\x1b[49m"),
109
- bgWhite: f("\x1b[47m", "\x1b[49m"),
3183
+ return waitForStatus(opts);
3184
+ }
110
3185
 
111
- blackBright: f("\x1b[90m", "\x1b[39m"),
112
- redBright: f("\x1b[91m", "\x1b[39m"),
113
- greenBright: f("\x1b[92m", "\x1b[39m"),
114
- yellowBright: f("\x1b[93m", "\x1b[39m"),
115
- blueBright: f("\x1b[94m", "\x1b[39m"),
116
- magentaBright: f("\x1b[95m", "\x1b[39m"),
117
- cyanBright: f("\x1b[96m", "\x1b[39m"),
118
- whiteBright: f("\x1b[97m", "\x1b[39m"),
3186
+ /**
3187
+ * Creates a deferred promise and fulfills it only when the socket is used.
3188
+ * Will retry on an interval specified in retryTimeMs.
3189
+ * Note: you have to be super user to correctly test system ports (0-1023).
3190
+ * @param {Number|Object} port a valid TCP port number. If an object, must contain all the parameters as properties.
3191
+ * @param {Number} [retryTimeMs] the retry interval in milliseconds - defaultis is 500ms
3192
+ * @param {Number} [timeOutMs] the amount of time to wait until port is free
3193
+ * @return {Object} A deferred promise from the q library.
3194
+ *
3195
+ * Example usage:
3196
+ *
3197
+ * var tcpPortUsed = require('tcp-port-used');
3198
+ * tcpPortUsed.waitUntilUsedOnHost(44204, 'some.host.com', 500, 4000)
3199
+ * .then(function() {
3200
+ * console.log('Port 44204 is now in use.');
3201
+ * }, function(err) {
3202
+ * console.log('Error: ', error.message);
3203
+ * });
3204
+ */
3205
+ function waitUntilUsedOnHost(port, host, retryTimeMs, timeOutMs) {
119
3206
 
120
- bgBlackBright: f("\x1b[100m", "\x1b[49m"),
121
- bgRedBright: f("\x1b[101m", "\x1b[49m"),
122
- bgGreenBright: f("\x1b[102m", "\x1b[49m"),
123
- bgYellowBright: f("\x1b[103m", "\x1b[49m"),
124
- bgBlueBright: f("\x1b[104m", "\x1b[49m"),
125
- bgMagentaBright: f("\x1b[105m", "\x1b[49m"),
126
- bgCyanBright: f("\x1b[106m", "\x1b[49m"),
127
- bgWhiteBright: f("\x1b[107m", "\x1b[49m"),
128
- }
129
- };
3207
+ // the first arument may be an object, if it is not, make an object
3208
+ var opts;
3209
+ if (is.obj(port)) {
3210
+ opts = port;
3211
+ opts.inUse = true;
3212
+ } else {
3213
+ opts = makeOptionsObj(port, host, true, retryTimeMs, timeOutMs);
3214
+ }
130
3215
 
131
- picocolors.exports = createColors();
132
- picocolors.exports.createColors = createColors;
133
- return picocolors.exports;
134
- }
3216
+ return waitForStatus(opts);
3217
+ }
135
3218
 
136
- var picocolorsExports = /*@__PURE__*/ requirePicocolors();
137
- const colors = /*@__PURE__*/getDefaultExportFromCjs(picocolorsExports);
3219
+ /**
3220
+ * For compatibility to previous version of module which did not have support
3221
+ * for host addresses. This function works only for localhost.
3222
+ * @param {Number} port a valid TCP port number. If an Object, must contain all the parameters as properties.
3223
+ * @param {Number} [retryTimeMs] the retry interval in milliseconds - defaultis is 500ms
3224
+ * @param {Number} [timeOutMs] the amount of time to wait until port is free
3225
+ * @return {Object} A deferred promise from the q library.
3226
+ *
3227
+ * Example usage:
3228
+ *
3229
+ * var tcpPortUsed = require('tcp-port-used');
3230
+ * tcpPortUsed.waitUntilUsed(44204, 500, 4000)
3231
+ * .then(function() {
3232
+ * console.log('Port 44204 is now in use.');
3233
+ * }, function(err) {
3234
+ * console.log('Error: ', error.message);
3235
+ * });
3236
+ */
3237
+ function waitUntilUsed(port, retryTimeMs, timeOutMs) {
3238
+
3239
+ // the first arument may be an object, if it is not, make an object
3240
+ var opts;
3241
+ if (is.obj(port)) {
3242
+ opts = port;
3243
+ opts.host = '127.0.0.1';
3244
+ opts.inUse = true;
3245
+ } else {
3246
+ opts = makeOptionsObj(port, '127.0.0.1', true, retryTimeMs, timeOutMs);
3247
+ }
138
3248
 
139
- function hasViteConfig(input) {
140
- if (!input) {
141
- throw new Error("Vite config not initialized!");
142
- }
3249
+ return waitUntilUsedOnHost(opts);
3250
+ }
3251
+ return tcpPortUsed$1;
143
3252
  }
144
3253
 
145
- function log(message, { type = "info", prefix = true, ...options } = {}) {
146
- hasViteConfig(shared.viteConfig);
147
- let output = "";
148
- if (prefix) {
149
- output += colors.bgMagenta(colors.white("\u2009php\u2009")) + " ";
150
- }
151
- output += message;
152
- shared.viteConfig.logger[type](output, options);
153
- }
154
- log.error = function(json, options = {}) {
155
- let output = json;
156
- let type = "info";
157
- try {
158
- const data = JSON.parse(json);
159
- output = "";
160
- switch (data.code) {
161
- case EPHPError.PARSE:
162
- case EPHPError.ERROR:
163
- case EPHPError.CORE_ERROR:
164
- case EPHPError.COMPILE_ERROR:
165
- case EPHPError.USER_ERROR:
166
- type = "error";
167
- output += colors.bgRedBright(colors.white("Fatal Error"));
168
- break;
169
- case EPHPError.WARNING:
170
- case EPHPError.USER_WARNING:
171
- case EPHPError.COMPILE_WARNING:
172
- case EPHPError.RECOVERABLE_ERROR:
173
- type = "warn";
174
- output += colors.yellowBright("Warning");
175
- break;
176
- case EPHPError.NOTICE:
177
- case EPHPError.USER_NOTICE:
178
- type = "info";
179
- output += colors.bgWhite(colors.black("Notice"));
180
- break;
181
- case EPHPError.STRICT:
182
- type = "info";
183
- output += colors.yellow("Strict");
184
- break;
185
- case EPHPError.DEPRECATED:
186
- case EPHPError.USER_DEPRECATED:
187
- type = "info";
188
- output += colors.cyan("Deprecated");
189
- break;
190
- default:
191
- break;
192
- }
193
- output += " " + data.message + "\r\n";
194
- output += " In: " + data.file.replace(
195
- resolve(shared.tempDir),
196
- shared.viteConfig?.root
197
- ) + "\r\n";
198
- output += " On line: " + data.line;
199
- } catch (error) {
200
- }
201
- log(output, { ...options, type });
202
- };
3254
+ var tcpPortUsedExports = requireTcpPortUsed();
3255
+ const tcpPortUsed = /*@__PURE__*/getDefaultExportFromCjs(tcpPortUsedExports);
203
3256
 
204
3257
  const PHP_Server = {
205
3258
  binary: "php",
@@ -209,7 +3262,7 @@ const PHP_Server = {
209
3262
  start,
210
3263
  stop
211
3264
  };
212
- async function start(root) {
3265
+ async function start(root = shared.projectRoot) {
213
3266
  if (!PHP_Server.process?.pid) {
214
3267
  await new Promise(async (resolve, reject) => {
215
3268
  const routerFileUrl = new URL("./router.php", import.meta.url);
@@ -357,8 +3410,8 @@ function requirePath () {
357
3410
  hasRequiredPath = 1;
358
3411
  Object.defineProperty(path, "__esModule", { value: true });
359
3412
  path.convertPosixPathToPattern = path.convertWindowsPathToPattern = path.convertPathToPattern = path.escapePosixPath = path.escapeWindowsPath = path.escape = path.removeLeadingDotSegment = path.makeAbsolute = path.unixify = void 0;
360
- const os = require$$0;
361
- const path$1 = require$$0$1;
3413
+ const os = require$$0$2;
3414
+ const path$1 = require$$0$3;
362
3415
  const IS_WINDOWS_PLATFORM = os.platform() === 'win32';
363
3416
  const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\
364
3417
  /**
@@ -623,8 +3676,8 @@ function requireGlobParent () {
623
3676
  hasRequiredGlobParent = 1;
624
3677
 
625
3678
  var isGlob = requireIsGlob();
626
- var pathPosixDirname = require$$0$1.posix.dirname;
627
- var isWin32 = require$$0.platform() === 'win32';
3679
+ var pathPosixDirname = require$$0$3.posix.dirname;
3680
+ var isWin32 = require$$0$2.platform() === 'win32';
628
3681
 
629
3682
  var slash = '/';
630
3683
  var backslash = /\\/g;
@@ -1173,7 +4226,7 @@ function requireFillRange () {
1173
4226
  if (hasRequiredFillRange) return fillRange;
1174
4227
  hasRequiredFillRange = 1;
1175
4228
 
1176
- const util = require$$0$2;
4229
+ const util = require$$0;
1177
4230
  const toRegexRange = requireToRegexRange();
1178
4231
 
1179
4232
  const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
@@ -2195,7 +5248,7 @@ function requireConstants$1 () {
2195
5248
  if (hasRequiredConstants$1) return constants$1;
2196
5249
  hasRequiredConstants$1 = 1;
2197
5250
 
2198
- const path = require$$0$1;
5251
+ const path = require$$0$3;
2199
5252
  const WIN_SLASH = '\\\\/';
2200
5253
  const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
2201
5254
 
@@ -2382,7 +5435,7 @@ function requireUtils$2 () {
2382
5435
  hasRequiredUtils$2 = 1;
2383
5436
  (function (exports) {
2384
5437
 
2385
- const path = require$$0$1;
5438
+ const path = require$$0$3;
2386
5439
  const win32 = process.platform === 'win32';
2387
5440
  const {
2388
5441
  REGEX_BACKSLASH,
@@ -3953,7 +7006,7 @@ function requirePicomatch$1 () {
3953
7006
  if (hasRequiredPicomatch$1) return picomatch_1;
3954
7007
  hasRequiredPicomatch$1 = 1;
3955
7008
 
3956
- const path = require$$0$1;
7009
+ const path = require$$0$3;
3957
7010
  const scan = requireScan();
3958
7011
  const parse = requireParse();
3959
7012
  const utils = requireUtils$2();
@@ -4314,7 +7367,7 @@ function requireMicromatch () {
4314
7367
  if (hasRequiredMicromatch) return micromatch_1;
4315
7368
  hasRequiredMicromatch = 1;
4316
7369
 
4317
- const util = require$$0$2;
7370
+ const util = require$$0;
4318
7371
  const braces = requireBraces();
4319
7372
  const picomatch = requirePicomatch();
4320
7373
  const utils = requireUtils$2();
@@ -4796,7 +7849,7 @@ function requirePattern () {
4796
7849
  hasRequiredPattern = 1;
4797
7850
  Object.defineProperty(pattern, "__esModule", { value: true });
4798
7851
  pattern.isAbsolute = pattern.partitionAbsoluteAndRelative = pattern.removeDuplicateSlashes = pattern.matchAny = pattern.convertPatternsToRe = pattern.makeRe = pattern.getPatternParts = pattern.expandBraceExpansion = pattern.expandPatternsWithBraceExpansion = pattern.isAffectDepthOfReadingPattern = pattern.endsWithSlashGlobStar = pattern.hasGlobStar = pattern.getBaseDirectory = pattern.isPatternRelatedToParentDirectory = pattern.getPatternsOutsideCurrentDirectory = pattern.getPatternsInsideCurrentDirectory = pattern.getPositivePatterns = pattern.getNegativePatterns = pattern.isPositivePattern = pattern.isNegativePattern = pattern.convertToNegativePattern = pattern.convertToPositivePattern = pattern.isDynamicPattern = pattern.isStaticPattern = void 0;
4799
- const path = require$$0$1;
7852
+ const path = require$$0$3;
4800
7853
  const globParent = requireGlobParent();
4801
7854
  const micromatch = requireMicromatch();
4802
7855
  const GLOBSTAR = '**';
@@ -5017,7 +8070,7 @@ function requireMerge2 () {
5017
8070
  * Copyright (c) 2014-2020 Teambition
5018
8071
  * Licensed under the MIT license.
5019
8072
  */
5020
- const Stream = require$$0$3;
8073
+ const Stream = require$$0$4;
5021
8074
  const PassThrough = Stream.PassThrough;
5022
8075
  const slice = Array.prototype.slice;
5023
8076
 
@@ -5446,7 +8499,7 @@ function requireFs$2 () {
5446
8499
  (function (exports) {
5447
8500
  Object.defineProperty(exports, "__esModule", { value: true });
5448
8501
  exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
5449
- const fs = require$$0$4;
8502
+ const fs = require$$0$5;
5450
8503
  exports.FILE_SYSTEM_ADAPTER = {
5451
8504
  lstat: fs.lstat,
5452
8505
  stat: fs.stat,
@@ -5876,7 +8929,7 @@ function requireFs () {
5876
8929
  (function (exports) {
5877
8930
  Object.defineProperty(exports, "__esModule", { value: true });
5878
8931
  exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
5879
- const fs = require$$0$4;
8932
+ const fs = require$$0$5;
5880
8933
  exports.FILE_SYSTEM_ADAPTER = {
5881
8934
  lstat: fs.lstat,
5882
8935
  stat: fs.stat,
@@ -5902,7 +8955,7 @@ function requireSettings$2 () {
5902
8955
  if (hasRequiredSettings$2) return settings$2;
5903
8956
  hasRequiredSettings$2 = 1;
5904
8957
  Object.defineProperty(settings$2, "__esModule", { value: true });
5905
- const path = require$$0$1;
8958
+ const path = require$$0$3;
5906
8959
  const fsStat = requireOut$3();
5907
8960
  const fs = requireFs();
5908
8961
  class Settings {
@@ -6387,7 +9440,7 @@ function requireAsync$3 () {
6387
9440
  if (hasRequiredAsync$3) return async$2;
6388
9441
  hasRequiredAsync$3 = 1;
6389
9442
  Object.defineProperty(async$2, "__esModule", { value: true });
6390
- const events_1 = require$$0$5;
9443
+ const events_1 = require$$0$6;
6391
9444
  const fsScandir = requireOut$2();
6392
9445
  const fastq = requireQueue();
6393
9446
  const common = requireCommon();
@@ -6530,7 +9583,7 @@ function requireStream$2 () {
6530
9583
  if (hasRequiredStream$2) return stream$2;
6531
9584
  hasRequiredStream$2 = 1;
6532
9585
  Object.defineProperty(stream$2, "__esModule", { value: true });
6533
- const stream_1 = require$$0$3;
9586
+ const stream_1 = require$$0$4;
6534
9587
  const async_1 = requireAsync$3();
6535
9588
  class StreamProvider {
6536
9589
  constructor(_root, _settings) {
@@ -6664,7 +9717,7 @@ function requireSettings$1 () {
6664
9717
  if (hasRequiredSettings$1) return settings$1;
6665
9718
  hasRequiredSettings$1 = 1;
6666
9719
  Object.defineProperty(settings$1, "__esModule", { value: true });
6667
- const path = require$$0$1;
9720
+ const path = require$$0$3;
6668
9721
  const fsScandir = requireOut$2();
6669
9722
  class Settings {
6670
9723
  constructor(_options = {}) {
@@ -6740,7 +9793,7 @@ function requireReader () {
6740
9793
  if (hasRequiredReader) return reader;
6741
9794
  hasRequiredReader = 1;
6742
9795
  Object.defineProperty(reader, "__esModule", { value: true });
6743
- const path = require$$0$1;
9796
+ const path = require$$0$3;
6744
9797
  const fsStat = requireOut$3();
6745
9798
  const utils = requireUtils$1();
6746
9799
  class Reader {
@@ -6782,7 +9835,7 @@ function requireStream$1 () {
6782
9835
  if (hasRequiredStream$1) return stream$1;
6783
9836
  hasRequiredStream$1 = 1;
6784
9837
  Object.defineProperty(stream$1, "__esModule", { value: true });
6785
- const stream_1 = require$$0$3;
9838
+ const stream_1 = require$$0$4;
6786
9839
  const fsStat = requireOut$3();
6787
9840
  const fsWalk = requireOut$1();
6788
9841
  const reader_1 = requireReader();
@@ -7213,7 +10266,7 @@ function requireProvider () {
7213
10266
  if (hasRequiredProvider) return provider;
7214
10267
  hasRequiredProvider = 1;
7215
10268
  Object.defineProperty(provider, "__esModule", { value: true });
7216
- const path = require$$0$1;
10269
+ const path = require$$0$3;
7217
10270
  const deep_1 = requireDeep();
7218
10271
  const entry_1 = requireEntry$1();
7219
10272
  const error_1 = requireError();
@@ -7300,7 +10353,7 @@ function requireStream () {
7300
10353
  if (hasRequiredStream) return stream;
7301
10354
  hasRequiredStream = 1;
7302
10355
  Object.defineProperty(stream, "__esModule", { value: true });
7303
- const stream_1 = require$$0$3;
10356
+ const stream_1 = require$$0$4;
7304
10357
  const stream_2 = requireStream$1();
7305
10358
  const provider_1 = requireProvider();
7306
10359
  class ProviderStream extends provider_1.default {
@@ -7426,8 +10479,8 @@ function requireSettings () {
7426
10479
  (function (exports) {
7427
10480
  Object.defineProperty(exports, "__esModule", { value: true });
7428
10481
  exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
7429
- const fs = require$$0$4;
7430
- const os = require$$0;
10482
+ const fs = require$$0$5;
10483
+ const os = require$$0$2;
7431
10484
  /**
7432
10485
  * The `os.cpus` method can return zero. We expect the number of cores to be greater than zero.
7433
10486
  * https://github.com/nodejs/node/blob/7faeddf23a98c53896f8b574a6e66589e8fb1eb8/lib/os.js#L106-L107
@@ -7597,23 +10650,6 @@ function requireOut () {
7597
10650
  var outExports = requireOut();
7598
10651
  const fastGlob = /*@__PURE__*/getDefaultExportFromCjs(outExports);
7599
10652
 
7600
- function consoleHijack() {
7601
- const entries = shared.entries;
7602
- ["log", "info", "warn", "error"].forEach((command) => {
7603
- const cx = console[command];
7604
- console[command] = function(...args) {
7605
- cx.apply(
7606
- this,
7607
- args.map(
7608
- (arg) => typeof arg === "string" ? entries.reduce((acc, entry) => {
7609
- return acc.replace(entry + ".html", entry);
7610
- }, arg) : arg
7611
- )
7612
- );
7613
- };
7614
- });
7615
- }
7616
-
7617
10653
  function readFile(file) {
7618
10654
  return readFileSync(file, "utf-8").toString();
7619
10655
  }
@@ -7621,6 +10657,9 @@ function writeFile(file, data) {
7621
10657
  mkdirSync(dirname(file), { recursive: true });
7622
10658
  writeFileSync(file, data);
7623
10659
  }
10660
+ function tempName(entry) {
10661
+ return `${shared.tempDir}/${entry}`;
10662
+ }
7624
10663
 
7625
10664
  function makeID() {
7626
10665
  return Date.now().toString(36) + Math.random() * 100;
@@ -7779,164 +10818,106 @@ const handleExit = {
7779
10818
  }
7780
10819
  };
7781
10820
 
7782
- const serve = {
7783
- rewriteUrl: (url) => url
7784
- };
7785
- function tempName(entry) {
7786
- return `${shared.tempDir}/${entry}`;
7787
- }
7788
- const servePlugin = {
7789
- name: "serve-php",
7790
- apply: "serve",
7791
- enforce: "post",
7792
- configResolved() {
7793
- handleExit.register();
7794
- const gitIgnoreFile = resolve(`${shared.tempDir}/.gitignore`);
7795
- if (!existsSync(gitIgnoreFile)) {
7796
- writeFile(gitIgnoreFile, "*\r\n**/*");
7797
- }
7798
- shared.entries.forEach((entry) => {
7799
- PHP_Code.fromFile(entry).applyEnv().write(tempName(entry));
7800
- });
7801
- },
7802
- async configureServer(server) {
7803
- server.restart = /* @__PURE__ */ ((originalRestart) => {
7804
- return async function(...args) {
7805
- handleExit.unregister();
7806
- return originalRestart.apply(null, args);
7807
- };
7808
- })(server.restart);
7809
- if (!PHP_Server.process) {
7810
- await PHP_Server.start(server?.config.root);
7811
- }
7812
- server.middlewares.use(async (req, res, next) => {
7813
- try {
7814
- if (req.url && !["/@vite", "/@fs", "/@id/__x00__", "/node_modules"].some(
7815
- (path) => req.url.startsWith(path)
7816
- )) {
7817
- req.on("error", (error) => {
7818
- throw error;
7819
- });
7820
- const url = new URL(req.url, "http://localhost");
7821
- if (shared.viteConfig?.server.port) {
7822
- url.port = shared.viteConfig.server.port.toString();
7823
- }
7824
- const requestUrl = url.pathname;
7825
- if (url.pathname.endsWith("/")) {
7826
- url.pathname += "index.php";
7827
- }
7828
- const routedUrl = serve.rewriteUrl(url);
7829
- if (routedUrl) {
7830
- url.pathname = routedUrl.pathname;
7831
- url.search = routedUrl.search;
7832
- url.hash = routedUrl.hash;
7833
- }
7834
- const entryPathname = url.pathname.substring(1);
7835
- const entry = shared.entries.find((file) => {
7836
- return file === entryPathname || file.substring(0, file.lastIndexOf(".")) === entryPathname;
7837
- });
7838
- if (entry) {
7839
- const tempFile = tempName(entry);
7840
- if (existsSync(resolve(tempFile))) {
7841
- url.pathname = tempFile;
7842
- url.host = PHP_Server.host;
7843
- url.port = PHP_Server.port.toString();
7844
- url.searchParams.set(
7845
- internalParam,
7846
- new URLSearchParams({
7847
- $REQUEST_URI: requestUrl,
7848
- $PHP_SELF: "/" + entry,
7849
- temp_dir: shared.tempDir,
7850
- error_levels: shared.devConfig.errorLevels.toString()
7851
- }).toString()
7852
- );
7853
- const body = await new Promise(
7854
- (resolve2, reject) => {
7855
- let data = [];
7856
- req.on("data", (chunk) => {
7857
- data.push(chunk);
7858
- }).on("end", () => {
7859
- resolve2(Buffer.concat(data));
7860
- });
10821
+ const phpProxy = async (req, res, next) => {
10822
+ try {
10823
+ if (req.url && !["/@vite", "/@fs", "/@id/__x00__", "/node_modules"].some(
10824
+ (path) => req.url.startsWith(path)
10825
+ )) {
10826
+ req.on("error", (error) => {
10827
+ throw error;
10828
+ });
10829
+ const url = new URL(req.url, "http://localhost");
10830
+ if (shared.viteConfig?.server.port) {
10831
+ url.port = shared.viteConfig.server.port.toString();
10832
+ }
10833
+ const requestUrl = url.pathname;
10834
+ if (url.pathname.endsWith("/")) {
10835
+ url.pathname += "index.php";
10836
+ }
10837
+ const routedUrl = serve.rewriteUrl(url);
10838
+ if (routedUrl) {
10839
+ url.pathname = routedUrl.pathname;
10840
+ url.search = routedUrl.search;
10841
+ url.hash = routedUrl.hash;
10842
+ }
10843
+ const entryPathname = url.pathname.substring(1);
10844
+ const entry = shared.entries.find((file) => {
10845
+ return file === entryPathname || file.substring(0, file.lastIndexOf(".")) === entryPathname;
10846
+ });
10847
+ if (entry) {
10848
+ const tempFile = tempName(entry);
10849
+ if (existsSync(resolve(tempFile))) {
10850
+ url.pathname = tempFile;
10851
+ url.host = PHP_Server.host;
10852
+ url.port = PHP_Server.port.toString();
10853
+ url.searchParams.set(
10854
+ internalParam,
10855
+ new URLSearchParams({
10856
+ $REQUEST_URI: requestUrl,
10857
+ $PHP_SELF: "/" + entry,
10858
+ temp_dir: shared.tempDir,
10859
+ error_levels: shared.devConfig.errorLevels.toString()
10860
+ }).toString()
10861
+ );
10862
+ const body = await new Promise(
10863
+ (resolve2, reject) => {
10864
+ let data = [];
10865
+ req.on("data", (chunk) => {
10866
+ data.push(chunk);
10867
+ }).on("end", () => {
10868
+ resolve2(Buffer.concat(data));
10869
+ });
10870
+ }
10871
+ );
10872
+ const phpResult = await new Promise(async (resolve2, reject) => {
10873
+ const chunks = [];
10874
+ let statusCode;
10875
+ let incomingHeaders = {};
10876
+ const request = http.request(
10877
+ url.toString(),
10878
+ {
10879
+ method: req.method,
10880
+ headers: {
10881
+ ...req.headers,
10882
+ "content-length": Buffer.byteLength(body)
7861
10883
  }
7862
- );
7863
- const phpResult = await new Promise(async (resolve2, reject) => {
7864
- const chunks = [];
7865
- let statusCode;
7866
- let incomingHeaders = {};
7867
- const request = http.request(
7868
- url.toString(),
7869
- {
7870
- method: req.method,
7871
- headers: {
7872
- ...req.headers,
7873
- "content-length": Buffer.byteLength(body)
7874
- }
7875
- },
7876
- (msg) => {
7877
- statusCode = msg.statusCode;
7878
- incomingHeaders = msg.headers;
7879
- msg.on("data", (data) => {
7880
- chunks.push(data);
7881
- });
7882
- }
7883
- ).on("error", (error) => {
7884
- reject(error);
7885
- }).on("close", () => {
7886
- const content = Buffer.concat(chunks).toString(
7887
- "utf8"
7888
- );
7889
- resolve2({
7890
- statusCode,
7891
- headers: incomingHeaders,
7892
- content
7893
- });
7894
- });
7895
- request.write(body, (error) => {
7896
- if (error) {
7897
- reject(error);
7898
- }
10884
+ },
10885
+ (msg) => {
10886
+ statusCode = msg.statusCode;
10887
+ incomingHeaders = msg.headers;
10888
+ msg.on("data", (data) => {
10889
+ chunks.push(data);
7899
10890
  });
7900
- request.end();
10891
+ }
10892
+ ).on("error", (error) => {
10893
+ reject(error);
10894
+ }).on("close", () => {
10895
+ const content = Buffer.concat(chunks).toString("utf8");
10896
+ resolve2({
10897
+ statusCode,
10898
+ headers: incomingHeaders,
10899
+ content
7901
10900
  });
7902
- let out = phpResult.content;
7903
- if (phpResult.headers["content-type"]?.includes(
7904
- "html"
7905
- )) {
7906
- out = await server.transformIndexHtml(
7907
- `/${entry}.html:${requestUrl}`,
7908
- out,
7909
- requestUrl
7910
- );
10901
+ });
10902
+ request.write(body, (error) => {
10903
+ if (error) {
10904
+ reject(error);
7911
10905
  }
7912
- res.writeHead(
7913
- phpResult.statusCode || 200,
7914
- phpResult.headers
7915
- ).end(out);
7916
- return;
7917
- }
7918
- }
10906
+ });
10907
+ request.end();
10908
+ });
10909
+ res.writeHead(
10910
+ phpResult.statusCode || 200,
10911
+ phpResult.headers
10912
+ ).end(phpResult.content);
10913
+ return;
7919
10914
  }
7920
- } catch (error) {
7921
- console.error("Vite-PHP Error: " + error);
7922
10915
  }
7923
- next();
7924
- });
7925
- },
7926
- handleHotUpdate({ server, file }) {
7927
- const entry = shared.entries.find(
7928
- (entryFile) => resolve(entryFile) === resolve(file)
7929
- );
7930
- if (entry) {
7931
- PHP_Code.fromFile(entry).applyEnv().write(tempName(entry));
7932
- server.moduleGraph.invalidateAll();
7933
- }
7934
- if (entry || !file.startsWith(resolve(shared.tempDir)) && file.includes(".php")) {
7935
- server.ws.send({
7936
- type: "full-reload"
7937
- });
7938
10916
  }
10917
+ } catch (error) {
10918
+ console.error("Vite-PHP Error: " + error);
7939
10919
  }
10920
+ next();
7940
10921
  };
7941
10922
 
7942
10923
  const assetsPattern = new RegExp(
@@ -7975,69 +10956,295 @@ function fixAssetsInjection(input) {
7975
10956
  return out;
7976
10957
  }
7977
10958
 
7978
- const buildPlugin = {
7979
- name: "build-php",
7980
- apply: "build",
7981
- enforce: "pre",
7982
- resolveId(source, importer, options) {
7983
- if (shared.entries.includes(source)) {
7984
- return {
7985
- // Rename ids because Vite transforms only .html files: https://github.com/vitejs/vite/blob/0cde495ebeb48bcfb5961784a30bfaed997790a0/packages/vite/src/node/plugins/html.ts#L330
7986
- id: `${source}.html`,
7987
- resolvedBy: "vite-plugin-php",
7988
- meta: {
7989
- originalId: source
10959
+ const serve = {
10960
+ rewriteUrl: (url) => url
10961
+ };
10962
+ let devServer = void 0;
10963
+ let entryMatcher = new RegExp(``, "gs");
10964
+ const codeMap$1 = /* @__PURE__ */ new Map();
10965
+ const servePlugin = [
10966
+ {
10967
+ name: "php:serve-load",
10968
+ apply: "serve",
10969
+ configResolved: {
10970
+ handler(config) {
10971
+ handleExit.register();
10972
+ const gitIgnoreFile = resolve(`${shared.tempDir}/.gitignore`);
10973
+ if (!existsSync(gitIgnoreFile)) {
10974
+ writeFile(gitIgnoreFile, "*\r\n**/*");
10975
+ }
10976
+ entryMatcher = new RegExp(
10977
+ `(${shared.entries.join("|")}).html`,
10978
+ "gs"
10979
+ );
10980
+ }
10981
+ },
10982
+ configureServer: {
10983
+ async handler(server) {
10984
+ devServer = server;
10985
+ server.restart = /* @__PURE__ */ ((originalRestart) => {
10986
+ return async function(...args) {
10987
+ handleExit.unregister();
10988
+ return originalRestart.apply(null, args);
10989
+ };
10990
+ })(server.restart);
10991
+ if (!PHP_Server.process) {
10992
+ await PHP_Server.start(server.config.root);
10993
+ }
10994
+ server.middlewares.use(phpProxy);
10995
+ }
10996
+ },
10997
+ // `rollupOptions.input` entries not arriving in `resolveId(source, importer, options)` -> force file loading with buildStart
10998
+ buildStart: {
10999
+ async handler(options) {
11000
+ await Promise.allSettled(
11001
+ shared.entries.map(async (entry) => {
11002
+ await this.load({
11003
+ id: entry
11004
+ });
11005
+ })
11006
+ );
11007
+ }
11008
+ },
11009
+ load: {
11010
+ handler(id, options) {
11011
+ if (shared.entries.includes(id)) {
11012
+ const php = PHP_Code.fromFile(id);
11013
+ return {
11014
+ code: php.code
11015
+ };
11016
+ }
11017
+ }
11018
+ }
11019
+ },
11020
+ {
11021
+ name: "php:serve-escape",
11022
+ apply: "serve",
11023
+ transform: {
11024
+ async handler(code, id, options) {
11025
+ if (shared.entries.includes(id) && devServer) {
11026
+ let ogWarnLogger = () => {
11027
+ };
11028
+ if (shared.viteConfig) {
11029
+ const warnings = /* @__PURE__ */ new Set();
11030
+ ogWarnLogger = shared.viteConfig.logger.warn;
11031
+ shared.viteConfig.logger.warn = /* @__PURE__ */ ((fn) => function(...args) {
11032
+ const ser = args.toString().replace(entryMatcher, (match, p1) => p1);
11033
+ if (warnings.has(ser)) {
11034
+ return;
11035
+ }
11036
+ warnings.add(ser);
11037
+ return fn.apply(null, args);
11038
+ })(shared.viteConfig.logger.warn);
11039
+ }
11040
+ const res = {
11041
+ code: await devServer.transformIndexHtml(
11042
+ // Rename ids because Vite transforms only .html files: https://github.com/vitejs/vite/blob/0cde495ebeb48bcfb5961784a30bfaed997790a0/packages/vite/src/node/plugins/html.ts#L330
11043
+ `/${id}.html`,
11044
+ code
11045
+ )
11046
+ };
11047
+ if (shared.viteConfig) {
11048
+ shared.viteConfig.logger.warn = ogWarnLogger;
11049
+ }
11050
+ return res;
11051
+ }
11052
+ }
11053
+ },
11054
+ transformIndexHtml: {
11055
+ order: "pre",
11056
+ handler(html, ctx) {
11057
+ const entry = ctx.path.substring(
11058
+ 1,
11059
+ ctx.path.length - ".html".length
11060
+ );
11061
+ if (shared.entries.includes(entry)) {
11062
+ const php = new PHP_Code(html);
11063
+ php.file = entry;
11064
+ php.applyEnv();
11065
+ php.escape();
11066
+ codeMap$1.set(entry, php.mapping);
11067
+ return php.code;
11068
+ }
11069
+ }
11070
+ }
11071
+ },
11072
+ {
11073
+ name: "php:serve-unescape",
11074
+ apply: "serve",
11075
+ enforce: "post",
11076
+ transform: {
11077
+ order: "post",
11078
+ handler(code, id, options) {
11079
+ let entry = "";
11080
+ if (id.includes("html-proxy") && shared.entries.some((entryItem) => {
11081
+ const res = id.startsWith(`\0/${entryItem}.html?`);
11082
+ if (res) {
11083
+ entry = entryItem;
11084
+ return true;
11085
+ }
11086
+ })) {
11087
+ const escapes = codeMap$1.get(entry);
11088
+ if (escapes) {
11089
+ return {
11090
+ code: PHP_Code.unescape(code, escapes)
11091
+ };
11092
+ }
11093
+ }
11094
+ }
11095
+ },
11096
+ transformIndexHtml: {
11097
+ order: "post",
11098
+ handler(html, ctx) {
11099
+ const entry = ctx.path.substring(
11100
+ 1,
11101
+ ctx.path.length - ".html".length
11102
+ );
11103
+ if (shared.entries.includes(entry)) {
11104
+ const escapes = codeMap$1.get(entry);
11105
+ let php = new PHP_Code(html);
11106
+ php.file = entry;
11107
+ if (escapes) {
11108
+ php.code = PHP_Code.unescape(php.code, escapes);
11109
+ }
11110
+ php.code = fixAssetsInjection(php.code);
11111
+ php.write(tempName(entry));
11112
+ return php.code;
11113
+ }
11114
+ }
11115
+ }
11116
+ },
11117
+ {
11118
+ name: "php:serve-watch",
11119
+ apply: "serve",
11120
+ async watchChange(id, change) {
11121
+ const entry = shared.entries.find(
11122
+ (entryFile) => resolve(entryFile) === resolve(id)
11123
+ );
11124
+ if (entry) {
11125
+ try {
11126
+ await this.load({
11127
+ id: entry
11128
+ });
11129
+ } catch (error) {
11130
+ }
11131
+ }
11132
+ },
11133
+ handleHotUpdate({ server, file }) {
11134
+ const entry = shared.entries.find(
11135
+ (entryFile) => resolve(entryFile) === resolve(file)
11136
+ );
11137
+ if (entry || !file.startsWith(resolve(shared.tempDir)) && file.includes(".php")) {
11138
+ server.ws.send({
11139
+ type: "full-reload"
11140
+ });
11141
+ }
11142
+ if (entry) {
11143
+ server.moduleGraph.invalidateAll();
11144
+ }
11145
+ }
11146
+ }
11147
+ ];
11148
+
11149
+ const entryMap = /* @__PURE__ */ new Map();
11150
+ const codeMap = /* @__PURE__ */ new Map();
11151
+ const buildPlugin = [
11152
+ {
11153
+ name: "php:build-load",
11154
+ apply: "build",
11155
+ enforce: "pre",
11156
+ resolveId: {
11157
+ handler(source, importer, options) {
11158
+ if (shared.entries.includes(source)) {
11159
+ const id = `${source}.html`;
11160
+ entryMap.set(id, source);
11161
+ return {
11162
+ id,
11163
+ resolvedBy: "vite-plugin-php"
11164
+ };
11165
+ }
11166
+ }
11167
+ },
11168
+ load: {
11169
+ handler(id, options) {
11170
+ const entry = entryMap.get(id);
11171
+ if (entry) {
11172
+ const php = PHP_Code.fromFile(entry);
11173
+ return {
11174
+ code: php.code
11175
+ };
7990
11176
  }
7991
- };
11177
+ }
7992
11178
  }
7993
11179
  },
7994
- load(id, options) {
7995
- const moduleInfo = this.getModuleInfo(id);
7996
- const entry = moduleInfo?.meta.originalId;
7997
- if (entry) {
7998
- const php = PHP_Code.fromFile(entry).applyEnv().escape();
7999
- return {
8000
- code: php.code,
8001
- meta: { phpMapping: php.mapping }
8002
- };
11180
+ {
11181
+ name: "php:build-escape",
11182
+ apply: "build",
11183
+ transformIndexHtml: {
11184
+ order: "pre",
11185
+ handler(html, ctx) {
11186
+ const entry = entryMap.get(ctx.filename);
11187
+ if (entry) {
11188
+ ctx.filename = entry;
11189
+ const php = new PHP_Code(html);
11190
+ php.file = entry;
11191
+ php.applyEnv();
11192
+ php.escape();
11193
+ codeMap.set(entry, php.mapping);
11194
+ return php.code;
11195
+ }
11196
+ }
8003
11197
  }
8004
11198
  },
8005
- generateBundle: {
8006
- order: "post",
8007
- handler(options, bundle, isWrite) {
8008
- Object.entries(bundle).forEach(([key, item]) => {
8009
- if (item.type === "asset") {
8010
- const moduleInfo = this.getModuleInfo(item.fileName);
8011
- if (moduleInfo?.meta.originalId) {
8012
- const meta = moduleInfo.meta;
8013
- item.fileName = meta.originalId;
8014
- if (meta.phpMapping) {
8015
- item.source = PHP_Code.unescape(
8016
- item.source.toString(),
8017
- meta.phpMapping
8018
- );
8019
- }
8020
- item.source = fixAssetsInjection(
8021
- item.source.toString()
8022
- );
11199
+ {
11200
+ name: "php:build-unescape",
11201
+ apply: "build",
11202
+ enforce: "post",
11203
+ transformIndexHtml: {
11204
+ order: "post",
11205
+ handler(html, ctx) {
11206
+ const entry = entryMap.get(ctx.filename);
11207
+ if (entry) {
11208
+ const escapes = codeMap.get(entry);
11209
+ if (escapes) {
11210
+ let php = PHP_Code.unescape(html, escapes);
11211
+ php = fixAssetsInjection(php);
11212
+ return php;
8023
11213
  }
8024
- } else if (item.type === "chunk" && item.facadeModuleId) {
8025
- const moduleInfo = this.getModuleInfo(item.facadeModuleId);
8026
- if (moduleInfo) {
8027
- const meta = moduleInfo.meta;
8028
- if (meta.phpMapping) {
8029
- item.code = PHP_Code.unescape(
8030
- item.code,
8031
- meta.phpMapping
8032
- );
11214
+ }
11215
+ }
11216
+ }
11217
+ },
11218
+ {
11219
+ name: "php:build-bundle",
11220
+ apply: "build",
11221
+ enforce: "post",
11222
+ generateBundle: {
11223
+ order: "post",
11224
+ handler(options, bundle, isWrite) {
11225
+ Object.entries(bundle).forEach(([key, item]) => {
11226
+ if (item.type === "asset") {
11227
+ const entry = entryMap.get(item.fileName);
11228
+ if (entry) {
11229
+ item.fileName = entry;
11230
+ }
11231
+ } else if (item.type === "chunk" && item.facadeModuleId) {
11232
+ const entry = entryMap.get(item.facadeModuleId);
11233
+ if (entry) {
11234
+ const escapes = codeMap.get(entry);
11235
+ if (escapes) {
11236
+ item.code = PHP_Code.unescape(
11237
+ item.code,
11238
+ escapes
11239
+ );
11240
+ }
8033
11241
  }
8034
- item.code = fixAssetsInjection(item.code);
8035
11242
  }
8036
- }
8037
- });
11243
+ });
11244
+ }
8038
11245
  }
8039
11246
  }
8040
- };
11247
+ ];
8041
11248
 
8042
11249
  function usePHP(cfg = {}) {
8043
11250
  const { entry = "index.php" } = cfg;
@@ -8052,7 +11259,7 @@ function usePHP(cfg = {}) {
8052
11259
  };
8053
11260
  return [
8054
11261
  {
8055
- name: "init-php",
11262
+ name: "php:init",
8056
11263
  enforce: "post",
8057
11264
  config(config, env) {
8058
11265
  shared.entries = [
@@ -8070,7 +11277,6 @@ function usePHP(cfg = {}) {
8070
11277
  )
8071
11278
  )
8072
11279
  ];
8073
- consoleHijack();
8074
11280
  return {
8075
11281
  server: {
8076
11282
  watch: {
@@ -8078,17 +11284,21 @@ function usePHP(cfg = {}) {
8078
11284
  }
8079
11285
  },
8080
11286
  build: {
8081
- rollupOptions: { input: shared.entries }
11287
+ rollupOptions: {
11288
+ input: shared.entries
11289
+ }
8082
11290
  },
8083
- optimizeDeps: { entries: shared.entries }
11291
+ optimizeDeps: {
11292
+ entries: shared.entries
11293
+ }
8084
11294
  };
8085
11295
  },
8086
11296
  configResolved(_config) {
8087
11297
  shared.viteConfig = _config;
8088
11298
  }
8089
11299
  },
8090
- servePlugin,
8091
- buildPlugin
11300
+ ...servePlugin,
11301
+ ...buildPlugin
8092
11302
  ];
8093
11303
  }
8094
11304