@ultirequiem/leap-year 2.0.0 → 2.1.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.
package/README.md CHANGED
@@ -22,6 +22,7 @@ isLeapYear(2016); //=> true
22
22
  isLeapYear("6 October 2006 00:07:00 GMT"); //=> false
23
23
  isLeapYear("2000"); //=> false
24
24
  isLeapYear(new Date(2016, 1, 1)); //=> true
25
+ isLeapYear("13 December 400 00:07:00 GMT", true); //=> { year: 400, result: true }
25
26
  ```
26
27
 
27
28
  ### [Node.js 🐢](https://www.npmjs.com/package/@ultirequiem/leap-year)
@@ -35,16 +36,10 @@ import { isLeapYear } from "@ultirequiem/leap-year";
35
36
  You can use any [CDN](https://en.wikipedia.org/wiki/Content_delivery_network)
36
37
  that you like.
37
38
 
38
- As an example, for
39
- [type module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
40
- 👇
41
-
42
- - [SkyPack](https://cdn.skypack.dev/@ultirequiem/leap-year)
43
-
44
- Or for a plain
45
- [script tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) 🦔
46
-
47
- - [jsdelivr](https://cdn.jsdelivr.net/npm/@ultirequiem/leap-year)
39
+ Eg. [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
40
+ ▶ [SkyPack](https://cdn.skypack.dev/@ultirequiem/leap-year) _/_
41
+ [script tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) ▶
42
+ [JSDelivr](https://cdn.jsdelivr.net/npm/@ultirequiem/leap-year).
48
43
 
49
44
  The API is the same on all this platforms.
50
45
 
@@ -53,6 +48,50 @@ The API is the same on all this platforms.
53
48
  [Autogenerated Documentation](https://doc.deno.land/https://deno.land/x/leap_year/mod.ts)
54
49
  🚀
55
50
 
51
+ ## CLI Tool
52
+
53
+ Was done mainly as usage example.
54
+
55
+ ### Install
56
+
57
+ - Node.js 🦍
58
+
59
+ ```sh
60
+ npm install -g @ultirequiem/leap-year
61
+ ```
62
+
63
+ - Deno 🦕
64
+
65
+ ```sh
66
+ deno install https://deno.land/x/leap_year/leap-year.ts
67
+ ```
68
+
69
+ ### Usage
70
+
71
+ ```sh
72
+ leap-year "13 October 2020 00:07:00 GMT" 400 345
73
+ true
74
+ true
75
+ false
76
+ ```
77
+
78
+ Or with the verbose flag 👇
79
+
80
+ ```sh
81
+ leap-year "13 October 2020 00:07:00 GMT" 400 345 --verbose # -v
82
+ 2020 is a leap year.
83
+ 400 is a leap year.
84
+ 345 is not a leap year.
85
+ ```
86
+
87
+ ## Related
88
+
89
+ - [leap_year_utils](https://github.com/UltiRequiem/leap_year_utils): Utilities
90
+ around this package
91
+
92
+ - [parse_datelike](https://github.com/UltiRequiem/parse_datelike): Parse a
93
+ number/string/date to a number/string/date
94
+
56
95
  ## Support
57
96
 
58
97
  Open an Issue, I will check it a soon as possible 👀
@@ -0,0 +1,15 @@
1
+ // https://github.com/tc39/proposal-accessible-object-hasownproperty/blob/main/polyfill.js
2
+ if (!Object.hasOwn) {
3
+ Object.defineProperty(Object, "hasOwn", {
4
+ value: function (object, property) {
5
+ if (object == null) {
6
+ throw new TypeError("Cannot convert undefined or null to object");
7
+ }
8
+ return Object.prototype.hasOwnProperty.call(Object(object), property);
9
+ },
10
+ configurable: true,
11
+ enumerable: false,
12
+ writable: true,
13
+ });
14
+ }
15
+ export {};
@@ -0,0 +1,62 @@
1
+ import { Deno } from "@deno/shim-deno";
2
+ export { Deno } from "@deno/shim-deno";
3
+ const dntGlobals = {
4
+ Deno,
5
+ };
6
+ export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
7
+ // deno-lint-ignore ban-types
8
+ function createMergeProxy(baseObj, extObj) {
9
+ return new Proxy(baseObj, {
10
+ get(_target, prop, _receiver) {
11
+ if (prop in extObj) {
12
+ return extObj[prop];
13
+ }
14
+ else {
15
+ return baseObj[prop];
16
+ }
17
+ },
18
+ set(_target, prop, value) {
19
+ if (prop in extObj) {
20
+ delete extObj[prop];
21
+ }
22
+ baseObj[prop] = value;
23
+ return true;
24
+ },
25
+ deleteProperty(_target, prop) {
26
+ let success = false;
27
+ if (prop in extObj) {
28
+ delete extObj[prop];
29
+ success = true;
30
+ }
31
+ if (prop in baseObj) {
32
+ delete baseObj[prop];
33
+ success = true;
34
+ }
35
+ return success;
36
+ },
37
+ ownKeys(_target) {
38
+ const baseKeys = Reflect.ownKeys(baseObj);
39
+ const extKeys = Reflect.ownKeys(extObj);
40
+ const extKeysSet = new Set(extKeys);
41
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
42
+ },
43
+ defineProperty(_target, prop, desc) {
44
+ if (prop in extObj) {
45
+ delete extObj[prop];
46
+ }
47
+ Reflect.defineProperty(baseObj, prop, desc);
48
+ return true;
49
+ },
50
+ getOwnPropertyDescriptor(_target, prop) {
51
+ if (prop in extObj) {
52
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
53
+ }
54
+ else {
55
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
56
+ }
57
+ },
58
+ has(_target, prop) {
59
+ return prop in extObj || prop in baseObj;
60
+ },
61
+ });
62
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+ export class DenoStdInternalError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = "DenoStdInternalError";
7
+ }
8
+ }
9
+ /** Make an assertion, if not `true`, then throw. */
10
+ export function assert(expr, msg = "") {
11
+ if (!expr) {
12
+ throw new DenoStdInternalError(msg);
13
+ }
14
+ }
@@ -0,0 +1,256 @@
1
+ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+ import { assert } from "../_util/assert.js";
4
+ const { hasOwn } = Object;
5
+ function get(obj, key) {
6
+ if (hasOwn(obj, key)) {
7
+ return obj[key];
8
+ }
9
+ }
10
+ function getForce(obj, key) {
11
+ const v = get(obj, key);
12
+ assert(v != null);
13
+ return v;
14
+ }
15
+ function isNumber(x) {
16
+ if (typeof x === "number")
17
+ return true;
18
+ if (/^0x[0-9a-f]+$/i.test(String(x)))
19
+ return true;
20
+ return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(String(x));
21
+ }
22
+ function hasKey(obj, keys) {
23
+ let o = obj;
24
+ keys.slice(0, -1).forEach((key) => {
25
+ o = (get(o, key) ?? {});
26
+ });
27
+ const key = keys[keys.length - 1];
28
+ return key in o;
29
+ }
30
+ /** Take a set of command line arguments, with an optional set of options, and
31
+ * return an object representation of those argument.
32
+ *
33
+ * ```ts
34
+ * import { parse } from "./mod.ts";
35
+ * const parsedArgs = parse(Deno.args);
36
+ * ```
37
+ */
38
+ export function parse(args, { "--": doubleDash = false, alias = {}, boolean = false, default: defaults = {}, stopEarly = false, string = [], unknown = (i) => i, } = {}) {
39
+ const flags = {
40
+ bools: {},
41
+ strings: {},
42
+ unknownFn: unknown,
43
+ allBools: false,
44
+ };
45
+ if (boolean !== undefined) {
46
+ if (typeof boolean === "boolean") {
47
+ flags.allBools = !!boolean;
48
+ }
49
+ else {
50
+ const booleanArgs = typeof boolean === "string" ? [boolean] : boolean;
51
+ for (const key of booleanArgs.filter(Boolean)) {
52
+ flags.bools[key] = true;
53
+ }
54
+ }
55
+ }
56
+ const aliases = {};
57
+ if (alias !== undefined) {
58
+ for (const key in alias) {
59
+ const val = getForce(alias, key);
60
+ if (typeof val === "string") {
61
+ aliases[key] = [val];
62
+ }
63
+ else {
64
+ aliases[key] = val;
65
+ }
66
+ for (const alias of getForce(aliases, key)) {
67
+ aliases[alias] = [key].concat(aliases[key].filter((y) => alias !== y));
68
+ }
69
+ }
70
+ }
71
+ if (string !== undefined) {
72
+ const stringArgs = typeof string === "string" ? [string] : string;
73
+ for (const key of stringArgs.filter(Boolean)) {
74
+ flags.strings[key] = true;
75
+ const alias = get(aliases, key);
76
+ if (alias) {
77
+ for (const al of alias) {
78
+ flags.strings[al] = true;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ const argv = { _: [] };
84
+ function argDefined(key, arg) {
85
+ return ((flags.allBools && /^--[^=]+$/.test(arg)) ||
86
+ get(flags.bools, key) ||
87
+ !!get(flags.strings, key) ||
88
+ !!get(aliases, key));
89
+ }
90
+ function setKey(obj, keys, value) {
91
+ let o = obj;
92
+ keys.slice(0, -1).forEach(function (key) {
93
+ if (get(o, key) === undefined) {
94
+ o[key] = {};
95
+ }
96
+ o = get(o, key);
97
+ });
98
+ const key = keys[keys.length - 1];
99
+ if (get(o, key) === undefined ||
100
+ get(flags.bools, key) ||
101
+ typeof get(o, key) === "boolean") {
102
+ o[key] = value;
103
+ }
104
+ else if (Array.isArray(get(o, key))) {
105
+ o[key].push(value);
106
+ }
107
+ else {
108
+ o[key] = [get(o, key), value];
109
+ }
110
+ }
111
+ function setArg(key, val, arg = undefined) {
112
+ if (arg && flags.unknownFn && !argDefined(key, arg)) {
113
+ if (flags.unknownFn(arg, key, val) === false)
114
+ return;
115
+ }
116
+ const value = !get(flags.strings, key) && isNumber(val) ? Number(val) : val;
117
+ setKey(argv, key.split("."), value);
118
+ const alias = get(aliases, key);
119
+ if (alias) {
120
+ for (const x of alias) {
121
+ setKey(argv, x.split("."), value);
122
+ }
123
+ }
124
+ }
125
+ function aliasIsBoolean(key) {
126
+ return getForce(aliases, key).some((x) => typeof get(flags.bools, x) === "boolean");
127
+ }
128
+ for (const key of Object.keys(flags.bools)) {
129
+ setArg(key, defaults[key] === undefined ? false : defaults[key]);
130
+ }
131
+ let notFlags = [];
132
+ // all args after "--" are not parsed
133
+ if (args.includes("--")) {
134
+ notFlags = args.slice(args.indexOf("--") + 1);
135
+ args = args.slice(0, args.indexOf("--"));
136
+ }
137
+ for (let i = 0; i < args.length; i++) {
138
+ const arg = args[i];
139
+ if (/^--.+=/.test(arg)) {
140
+ const m = arg.match(/^--([^=]+)=(.*)$/s);
141
+ assert(m != null);
142
+ const [, key, value] = m;
143
+ if (flags.bools[key]) {
144
+ const booleanValue = value !== "false";
145
+ setArg(key, booleanValue, arg);
146
+ }
147
+ else {
148
+ setArg(key, value, arg);
149
+ }
150
+ }
151
+ else if (/^--no-.+/.test(arg)) {
152
+ const m = arg.match(/^--no-(.+)/);
153
+ assert(m != null);
154
+ setArg(m[1], false, arg);
155
+ }
156
+ else if (/^--.+/.test(arg)) {
157
+ const m = arg.match(/^--(.+)/);
158
+ assert(m != null);
159
+ const [, key] = m;
160
+ const next = args[i + 1];
161
+ if (next !== undefined &&
162
+ !/^-/.test(next) &&
163
+ !get(flags.bools, key) &&
164
+ !flags.allBools &&
165
+ (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
166
+ setArg(key, next, arg);
167
+ i++;
168
+ }
169
+ else if (/^(true|false)$/.test(next)) {
170
+ setArg(key, next === "true", arg);
171
+ i++;
172
+ }
173
+ else {
174
+ setArg(key, get(flags.strings, key) ? "" : true, arg);
175
+ }
176
+ }
177
+ else if (/^-[^-]+/.test(arg)) {
178
+ const letters = arg.slice(1, -1).split("");
179
+ let broken = false;
180
+ for (let j = 0; j < letters.length; j++) {
181
+ const next = arg.slice(j + 2);
182
+ if (next === "-") {
183
+ setArg(letters[j], next, arg);
184
+ continue;
185
+ }
186
+ if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
187
+ setArg(letters[j], next.split(/=(.+)/)[1], arg);
188
+ broken = true;
189
+ break;
190
+ }
191
+ if (/[A-Za-z]/.test(letters[j]) &&
192
+ /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
193
+ setArg(letters[j], next, arg);
194
+ broken = true;
195
+ break;
196
+ }
197
+ if (letters[j + 1] && letters[j + 1].match(/\W/)) {
198
+ setArg(letters[j], arg.slice(j + 2), arg);
199
+ broken = true;
200
+ break;
201
+ }
202
+ else {
203
+ setArg(letters[j], get(flags.strings, letters[j]) ? "" : true, arg);
204
+ }
205
+ }
206
+ const [key] = arg.slice(-1);
207
+ if (!broken && key !== "-") {
208
+ if (args[i + 1] &&
209
+ !/^(-|--)[^-]/.test(args[i + 1]) &&
210
+ !get(flags.bools, key) &&
211
+ (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
212
+ setArg(key, args[i + 1], arg);
213
+ i++;
214
+ }
215
+ else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
216
+ setArg(key, args[i + 1] === "true", arg);
217
+ i++;
218
+ }
219
+ else {
220
+ setArg(key, get(flags.strings, key) ? "" : true, arg);
221
+ }
222
+ }
223
+ }
224
+ else {
225
+ if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
226
+ argv._.push(flags.strings["_"] ?? !isNumber(arg) ? arg : Number(arg));
227
+ }
228
+ if (stopEarly) {
229
+ argv._.push(...args.slice(i + 1));
230
+ break;
231
+ }
232
+ }
233
+ }
234
+ for (const key of Object.keys(defaults)) {
235
+ if (!hasKey(argv, key.split("."))) {
236
+ setKey(argv, key.split("."), defaults[key]);
237
+ if (aliases[key]) {
238
+ for (const x of aliases[key]) {
239
+ setKey(argv, x.split("."), defaults[key]);
240
+ }
241
+ }
242
+ }
243
+ }
244
+ if (doubleDash) {
245
+ argv["--"] = [];
246
+ for (const key of notFlags) {
247
+ argv["--"].push(key);
248
+ }
249
+ }
250
+ else {
251
+ for (const key of notFlags) {
252
+ argv._.push(key);
253
+ }
254
+ }
255
+ return argv;
256
+ }
@@ -0,0 +1,9 @@
1
+ export function parseDateLike(date) {
2
+ if (typeof date === "string") {
3
+ date = new Date(date);
4
+ }
5
+ if (!(date instanceof Date) && typeof date !== "number") {
6
+ throw new TypeError(`Expected "year" type to be "Date" | "number" | "string" and got ${typeof date}.`);
7
+ }
8
+ return date instanceof Date ? date.getUTCFullYear() : date;
9
+ }
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import "./_dnt.polyfills.js";
3
+ import * as dntShim from "./_dnt.shims.js";
4
+ import { parse } from "./deps/deno.land/std@0.128.0/flags/mod.js";
5
+ import { isLeapYear } from "./mod.js";
6
+ const { _: years, verbose } = parse(dntShim.Deno.args, {
7
+ boolean: ["verbose"],
8
+ alias: { v: "verbose" },
9
+ });
10
+ for (const year of years) {
11
+ const { year: parsedYear, result } = isLeapYear(year, true);
12
+ if (verbose) {
13
+ console.log(`${parsedYear} is ${result ? "" : "not "}a leap year.`);
14
+ continue;
15
+ }
16
+ console.log(result);
17
+ }
package/esm/mod.js CHANGED
@@ -1,40 +1,7 @@
1
- /**
2
- * Check if a year is a [leap year](https://en.wikipedia.org/wiki/Leap_year).
3
- *
4
- * @param year - Default: `new Date()`.
5
- *
6
- * @example
7
- * ```javascript
8
- * import { isLeapYear } from "https://deno.land/x/leap_year/mod.ts";
9
- *
10
- * isLeapYear(2014); //=> false
11
- * isLeapYear(2016); //=> true
12
- * isLeapYear("6 October 2006 00:07:00 GMT") //=> false
13
- * isLeapYear("200"); //=> false
14
- * isLeapYear(new Date(2016, 1, 1)); //=> true
15
- * ```
16
- */
17
- export function isLeapYear(year = new Date()) {
18
- year = internalParse(year);
19
- return (year % 4 === 0 && year % 100 !== 0) ?? year % 400 === 0;
20
- }
21
- export function generateLeapYear(config) {
22
- const { min = 0, max = new Date() } = config;
23
- const maxYear = internalParse(max);
24
- const leapYears = [];
25
- for (let year = min; year <= maxYear; year++) {
26
- if (isLeapYear(year)) {
27
- leapYears.push(year);
28
- }
29
- }
30
- return leapYears;
31
- }
32
- function internalParse(date) {
33
- if (typeof date === "string") {
34
- date = new Date(date);
35
- }
36
- if (!(date instanceof Date) && typeof date !== "number") {
37
- throw new TypeError(`Expected "year" type to be "Date" | "number" | "string" and got ${typeof date}.`);
38
- }
39
- return date instanceof Date ? date.getUTCFullYear() : date;
1
+ import "./_dnt.polyfills.js";
2
+ import { parseDateLike } from "./deps/deno.land/x/parse_datelike@0.0.1/mod.js";
3
+ export function isLeapYear(year = new Date(), returnValue = false) {
4
+ year = parseDateLike(year);
5
+ const result = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
6
+ return returnValue ? { result, year } : result;
40
7
  }
package/package.json CHANGED
@@ -2,9 +2,12 @@
2
2
  "module": "./esm/mod.js",
3
3
  "main": "./script/mod.js",
4
4
  "types": "./types/mod.d.ts",
5
+ "bin": {
6
+ "leap-year": "./esm/leap-year.js"
7
+ },
5
8
  "name": "@ultirequiem/leap-year",
6
9
  "description": "Check if a year is leap.",
7
- "version": "2.0.0",
10
+ "version": "2.1.0",
8
11
  "license": "MIT",
9
12
  "funding": {
10
13
  "type": "patreon",
@@ -31,10 +34,11 @@
31
34
  "scripts": {
32
35
  "test": "node test_runner.js"
33
36
  },
34
- "dependencies": {},
37
+ "dependencies": {
38
+ "@deno/shim-deno": "~0.4.3"
39
+ },
35
40
  "devDependencies": {
36
41
  "@types/node": "16.11.26",
37
- "chalk": "4.1.2",
38
- "@deno/shim-deno": "~0.4.3"
42
+ "chalk": "4.1.2"
39
43
  }
40
44
  }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // https://github.com/tc39/proposal-accessible-object-hasownproperty/blob/main/polyfill.js
4
+ if (!Object.hasOwn) {
5
+ Object.defineProperty(Object, "hasOwn", {
6
+ value: function (object, property) {
7
+ if (object == null) {
8
+ throw new TypeError("Cannot convert undefined or null to object");
9
+ }
10
+ return Object.prototype.hasOwnProperty.call(Object(object), property);
11
+ },
12
+ configurable: true,
13
+ enumerable: false,
14
+ writable: true,
15
+ });
16
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dntGlobalThis = exports.Deno = void 0;
4
+ const shim_deno_1 = require("@deno/shim-deno");
5
+ var shim_deno_2 = require("@deno/shim-deno");
6
+ Object.defineProperty(exports, "Deno", { enumerable: true, get: function () { return shim_deno_2.Deno; } });
7
+ const dntGlobals = {
8
+ Deno: shim_deno_1.Deno,
9
+ };
10
+ exports.dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
11
+ // deno-lint-ignore ban-types
12
+ function createMergeProxy(baseObj, extObj) {
13
+ return new Proxy(baseObj, {
14
+ get(_target, prop, _receiver) {
15
+ if (prop in extObj) {
16
+ return extObj[prop];
17
+ }
18
+ else {
19
+ return baseObj[prop];
20
+ }
21
+ },
22
+ set(_target, prop, value) {
23
+ if (prop in extObj) {
24
+ delete extObj[prop];
25
+ }
26
+ baseObj[prop] = value;
27
+ return true;
28
+ },
29
+ deleteProperty(_target, prop) {
30
+ let success = false;
31
+ if (prop in extObj) {
32
+ delete extObj[prop];
33
+ success = true;
34
+ }
35
+ if (prop in baseObj) {
36
+ delete baseObj[prop];
37
+ success = true;
38
+ }
39
+ return success;
40
+ },
41
+ ownKeys(_target) {
42
+ const baseKeys = Reflect.ownKeys(baseObj);
43
+ const extKeys = Reflect.ownKeys(extObj);
44
+ const extKeysSet = new Set(extKeys);
45
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
46
+ },
47
+ defineProperty(_target, prop, desc) {
48
+ if (prop in extObj) {
49
+ delete extObj[prop];
50
+ }
51
+ Reflect.defineProperty(baseObj, prop, desc);
52
+ return true;
53
+ },
54
+ getOwnPropertyDescriptor(_target, prop) {
55
+ if (prop in extObj) {
56
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
57
+ }
58
+ else {
59
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
60
+ }
61
+ },
62
+ has(_target, prop) {
63
+ return prop in extObj || prop in baseObj;
64
+ },
65
+ });
66
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
3
+ // This module is browser compatible.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.assert = exports.DenoStdInternalError = void 0;
6
+ class DenoStdInternalError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "DenoStdInternalError";
10
+ }
11
+ }
12
+ exports.DenoStdInternalError = DenoStdInternalError;
13
+ /** Make an assertion, if not `true`, then throw. */
14
+ function assert(expr, msg = "") {
15
+ if (!expr) {
16
+ throw new DenoStdInternalError(msg);
17
+ }
18
+ }
19
+ exports.assert = assert;
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
3
+ // This module is browser compatible.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.parse = void 0;
6
+ const assert_js_1 = require("../_util/assert.js");
7
+ const { hasOwn } = Object;
8
+ function get(obj, key) {
9
+ if (hasOwn(obj, key)) {
10
+ return obj[key];
11
+ }
12
+ }
13
+ function getForce(obj, key) {
14
+ const v = get(obj, key);
15
+ (0, assert_js_1.assert)(v != null);
16
+ return v;
17
+ }
18
+ function isNumber(x) {
19
+ if (typeof x === "number")
20
+ return true;
21
+ if (/^0x[0-9a-f]+$/i.test(String(x)))
22
+ return true;
23
+ return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(String(x));
24
+ }
25
+ function hasKey(obj, keys) {
26
+ let o = obj;
27
+ keys.slice(0, -1).forEach((key) => {
28
+ o = (get(o, key) ?? {});
29
+ });
30
+ const key = keys[keys.length - 1];
31
+ return key in o;
32
+ }
33
+ /** Take a set of command line arguments, with an optional set of options, and
34
+ * return an object representation of those argument.
35
+ *
36
+ * ```ts
37
+ * import { parse } from "./mod.ts";
38
+ * const parsedArgs = parse(Deno.args);
39
+ * ```
40
+ */
41
+ function parse(args, { "--": doubleDash = false, alias = {}, boolean = false, default: defaults = {}, stopEarly = false, string = [], unknown = (i) => i, } = {}) {
42
+ const flags = {
43
+ bools: {},
44
+ strings: {},
45
+ unknownFn: unknown,
46
+ allBools: false,
47
+ };
48
+ if (boolean !== undefined) {
49
+ if (typeof boolean === "boolean") {
50
+ flags.allBools = !!boolean;
51
+ }
52
+ else {
53
+ const booleanArgs = typeof boolean === "string" ? [boolean] : boolean;
54
+ for (const key of booleanArgs.filter(Boolean)) {
55
+ flags.bools[key] = true;
56
+ }
57
+ }
58
+ }
59
+ const aliases = {};
60
+ if (alias !== undefined) {
61
+ for (const key in alias) {
62
+ const val = getForce(alias, key);
63
+ if (typeof val === "string") {
64
+ aliases[key] = [val];
65
+ }
66
+ else {
67
+ aliases[key] = val;
68
+ }
69
+ for (const alias of getForce(aliases, key)) {
70
+ aliases[alias] = [key].concat(aliases[key].filter((y) => alias !== y));
71
+ }
72
+ }
73
+ }
74
+ if (string !== undefined) {
75
+ const stringArgs = typeof string === "string" ? [string] : string;
76
+ for (const key of stringArgs.filter(Boolean)) {
77
+ flags.strings[key] = true;
78
+ const alias = get(aliases, key);
79
+ if (alias) {
80
+ for (const al of alias) {
81
+ flags.strings[al] = true;
82
+ }
83
+ }
84
+ }
85
+ }
86
+ const argv = { _: [] };
87
+ function argDefined(key, arg) {
88
+ return ((flags.allBools && /^--[^=]+$/.test(arg)) ||
89
+ get(flags.bools, key) ||
90
+ !!get(flags.strings, key) ||
91
+ !!get(aliases, key));
92
+ }
93
+ function setKey(obj, keys, value) {
94
+ let o = obj;
95
+ keys.slice(0, -1).forEach(function (key) {
96
+ if (get(o, key) === undefined) {
97
+ o[key] = {};
98
+ }
99
+ o = get(o, key);
100
+ });
101
+ const key = keys[keys.length - 1];
102
+ if (get(o, key) === undefined ||
103
+ get(flags.bools, key) ||
104
+ typeof get(o, key) === "boolean") {
105
+ o[key] = value;
106
+ }
107
+ else if (Array.isArray(get(o, key))) {
108
+ o[key].push(value);
109
+ }
110
+ else {
111
+ o[key] = [get(o, key), value];
112
+ }
113
+ }
114
+ function setArg(key, val, arg = undefined) {
115
+ if (arg && flags.unknownFn && !argDefined(key, arg)) {
116
+ if (flags.unknownFn(arg, key, val) === false)
117
+ return;
118
+ }
119
+ const value = !get(flags.strings, key) && isNumber(val) ? Number(val) : val;
120
+ setKey(argv, key.split("."), value);
121
+ const alias = get(aliases, key);
122
+ if (alias) {
123
+ for (const x of alias) {
124
+ setKey(argv, x.split("."), value);
125
+ }
126
+ }
127
+ }
128
+ function aliasIsBoolean(key) {
129
+ return getForce(aliases, key).some((x) => typeof get(flags.bools, x) === "boolean");
130
+ }
131
+ for (const key of Object.keys(flags.bools)) {
132
+ setArg(key, defaults[key] === undefined ? false : defaults[key]);
133
+ }
134
+ let notFlags = [];
135
+ // all args after "--" are not parsed
136
+ if (args.includes("--")) {
137
+ notFlags = args.slice(args.indexOf("--") + 1);
138
+ args = args.slice(0, args.indexOf("--"));
139
+ }
140
+ for (let i = 0; i < args.length; i++) {
141
+ const arg = args[i];
142
+ if (/^--.+=/.test(arg)) {
143
+ const m = arg.match(/^--([^=]+)=(.*)$/s);
144
+ (0, assert_js_1.assert)(m != null);
145
+ const [, key, value] = m;
146
+ if (flags.bools[key]) {
147
+ const booleanValue = value !== "false";
148
+ setArg(key, booleanValue, arg);
149
+ }
150
+ else {
151
+ setArg(key, value, arg);
152
+ }
153
+ }
154
+ else if (/^--no-.+/.test(arg)) {
155
+ const m = arg.match(/^--no-(.+)/);
156
+ (0, assert_js_1.assert)(m != null);
157
+ setArg(m[1], false, arg);
158
+ }
159
+ else if (/^--.+/.test(arg)) {
160
+ const m = arg.match(/^--(.+)/);
161
+ (0, assert_js_1.assert)(m != null);
162
+ const [, key] = m;
163
+ const next = args[i + 1];
164
+ if (next !== undefined &&
165
+ !/^-/.test(next) &&
166
+ !get(flags.bools, key) &&
167
+ !flags.allBools &&
168
+ (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
169
+ setArg(key, next, arg);
170
+ i++;
171
+ }
172
+ else if (/^(true|false)$/.test(next)) {
173
+ setArg(key, next === "true", arg);
174
+ i++;
175
+ }
176
+ else {
177
+ setArg(key, get(flags.strings, key) ? "" : true, arg);
178
+ }
179
+ }
180
+ else if (/^-[^-]+/.test(arg)) {
181
+ const letters = arg.slice(1, -1).split("");
182
+ let broken = false;
183
+ for (let j = 0; j < letters.length; j++) {
184
+ const next = arg.slice(j + 2);
185
+ if (next === "-") {
186
+ setArg(letters[j], next, arg);
187
+ continue;
188
+ }
189
+ if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
190
+ setArg(letters[j], next.split(/=(.+)/)[1], arg);
191
+ broken = true;
192
+ break;
193
+ }
194
+ if (/[A-Za-z]/.test(letters[j]) &&
195
+ /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
196
+ setArg(letters[j], next, arg);
197
+ broken = true;
198
+ break;
199
+ }
200
+ if (letters[j + 1] && letters[j + 1].match(/\W/)) {
201
+ setArg(letters[j], arg.slice(j + 2), arg);
202
+ broken = true;
203
+ break;
204
+ }
205
+ else {
206
+ setArg(letters[j], get(flags.strings, letters[j]) ? "" : true, arg);
207
+ }
208
+ }
209
+ const [key] = arg.slice(-1);
210
+ if (!broken && key !== "-") {
211
+ if (args[i + 1] &&
212
+ !/^(-|--)[^-]/.test(args[i + 1]) &&
213
+ !get(flags.bools, key) &&
214
+ (get(aliases, key) ? !aliasIsBoolean(key) : true)) {
215
+ setArg(key, args[i + 1], arg);
216
+ i++;
217
+ }
218
+ else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
219
+ setArg(key, args[i + 1] === "true", arg);
220
+ i++;
221
+ }
222
+ else {
223
+ setArg(key, get(flags.strings, key) ? "" : true, arg);
224
+ }
225
+ }
226
+ }
227
+ else {
228
+ if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
229
+ argv._.push(flags.strings["_"] ?? !isNumber(arg) ? arg : Number(arg));
230
+ }
231
+ if (stopEarly) {
232
+ argv._.push(...args.slice(i + 1));
233
+ break;
234
+ }
235
+ }
236
+ }
237
+ for (const key of Object.keys(defaults)) {
238
+ if (!hasKey(argv, key.split("."))) {
239
+ setKey(argv, key.split("."), defaults[key]);
240
+ if (aliases[key]) {
241
+ for (const x of aliases[key]) {
242
+ setKey(argv, x.split("."), defaults[key]);
243
+ }
244
+ }
245
+ }
246
+ }
247
+ if (doubleDash) {
248
+ argv["--"] = [];
249
+ for (const key of notFlags) {
250
+ argv["--"].push(key);
251
+ }
252
+ }
253
+ else {
254
+ for (const key of notFlags) {
255
+ argv._.push(key);
256
+ }
257
+ }
258
+ return argv;
259
+ }
260
+ exports.parse = parse;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDateLike = void 0;
4
+ function parseDateLike(date) {
5
+ if (typeof date === "string") {
6
+ date = new Date(date);
7
+ }
8
+ if (!(date instanceof Date) && typeof date !== "number") {
9
+ throw new TypeError(`Expected "year" type to be "Date" | "number" | "string" and got ${typeof date}.`);
10
+ }
11
+ return date instanceof Date ? date.getUTCFullYear() : date;
12
+ }
13
+ exports.parseDateLike = parseDateLike;
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ require("./_dnt.polyfills.js");
28
+ const dntShim = __importStar(require("./_dnt.shims.js"));
29
+ const mod_js_1 = require("./deps/deno.land/std@0.128.0/flags/mod.js");
30
+ const mod_js_2 = require("./mod.js");
31
+ const { _: years, verbose } = (0, mod_js_1.parse)(dntShim.Deno.args, {
32
+ boolean: ["verbose"],
33
+ alias: { v: "verbose" },
34
+ });
35
+ for (const year of years) {
36
+ const { year: parsedYear, result } = (0, mod_js_2.isLeapYear)(year, true);
37
+ if (verbose) {
38
+ console.log(`${parsedYear} is ${result ? "" : "not "}a leap year.`);
39
+ continue;
40
+ }
41
+ console.log(result);
42
+ }
package/script/mod.js CHANGED
@@ -1,45 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateLeapYear = exports.isLeapYear = void 0;
4
- /**
5
- * Check if a year is a [leap year](https://en.wikipedia.org/wiki/Leap_year).
6
- *
7
- * @param year - Default: `new Date()`.
8
- *
9
- * @example
10
- * ```javascript
11
- * import { isLeapYear } from "https://deno.land/x/leap_year/mod.ts";
12
- *
13
- * isLeapYear(2014); //=> false
14
- * isLeapYear(2016); //=> true
15
- * isLeapYear("6 October 2006 00:07:00 GMT") //=> false
16
- * isLeapYear("200"); //=> false
17
- * isLeapYear(new Date(2016, 1, 1)); //=> true
18
- * ```
19
- */
20
- function isLeapYear(year = new Date()) {
21
- year = internalParse(year);
22
- return (year % 4 === 0 && year % 100 !== 0) ?? year % 400 === 0;
3
+ exports.isLeapYear = void 0;
4
+ require("./_dnt.polyfills.js");
5
+ const mod_js_1 = require("./deps/deno.land/x/parse_datelike@0.0.1/mod.js");
6
+ function isLeapYear(year = new Date(), returnValue = false) {
7
+ year = (0, mod_js_1.parseDateLike)(year);
8
+ const result = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
9
+ return returnValue ? { result, year } : result;
23
10
  }
24
11
  exports.isLeapYear = isLeapYear;
25
- function generateLeapYear(config) {
26
- const { min = 0, max = new Date() } = config;
27
- const maxYear = internalParse(max);
28
- const leapYears = [];
29
- for (let year = min; year <= maxYear; year++) {
30
- if (isLeapYear(year)) {
31
- leapYears.push(year);
32
- }
33
- }
34
- return leapYears;
35
- }
36
- exports.generateLeapYear = generateLeapYear;
37
- function internalParse(date) {
38
- if (typeof date === "string") {
39
- date = new Date(date);
40
- }
41
- if (!(date instanceof Date) && typeof date !== "number") {
42
- throw new TypeError(`Expected "year" type to be "Date" | "number" | "string" and got ${typeof date}.`);
43
- }
44
- return date instanceof Date ? date.getUTCFullYear() : date;
45
- }
@@ -0,0 +1,11 @@
1
+ declare global {
2
+ interface Object {
3
+ /**
4
+ * Determines whether an object has a property with the specified name.
5
+ * @param o An object.
6
+ * @param v A property name.
7
+ */
8
+ hasOwn(o: object, v: PropertyKey): boolean;
9
+ }
10
+ }
11
+ export {};
@@ -0,0 +1,5 @@
1
+ import { Deno } from "@deno/shim-deno";
2
+ export { Deno } from "@deno/shim-deno";
3
+ export declare const dntGlobalThis: Omit<typeof globalThis, "Deno"> & {
4
+ Deno: typeof Deno;
5
+ };
@@ -0,0 +1,5 @@
1
+ export declare class DenoStdInternalError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /** Make an assertion, if not `true`, then throw. */
5
+ export declare function assert(expr: unknown, msg?: string): asserts expr;
@@ -0,0 +1,50 @@
1
+ export interface Args {
2
+ /** Contains all the arguments that didn't have an option associated with
3
+ * them. */
4
+ _: Array<string | number>;
5
+ [key: string]: any;
6
+ }
7
+ export interface ArgParsingOptions {
8
+ /** When `true`, populate the result `_` with everything before the `--` and
9
+ * the result `['--']` with everything after the `--`. Here's an example:
10
+ *
11
+ * ```ts
12
+ * // $ deno run example.ts -- a arg1
13
+ * import { parse } from "./mod.ts";
14
+ * console.dir(parse(Deno.args, { "--": false }));
15
+ * // output: { _: [ "a", "arg1" ] }
16
+ * console.dir(parse(Deno.args, { "--": true }));
17
+ * // output: { _: [], --: [ "a", "arg1" ] }
18
+ * ```
19
+ *
20
+ * Defaults to `false`.
21
+ */
22
+ "--"?: boolean;
23
+ /** An object mapping string names to strings or arrays of string argument
24
+ * names to use as aliases */
25
+ alias?: Record<string, string | string[]>;
26
+ /** A boolean, string or array of strings to always treat as booleans. If
27
+ * `true` will treat all double hyphenated arguments without equal signs as
28
+ * `boolean` (e.g. affects `--foo`, not `-f` or `--foo=bar`) */
29
+ boolean?: boolean | string | string[];
30
+ /** An object mapping string argument names to default values. */
31
+ default?: Record<string, unknown>;
32
+ /** When `true`, populate the result `_` with everything after the first
33
+ * non-option. */
34
+ stopEarly?: boolean;
35
+ /** A string or array of strings argument names to always treat as strings. */
36
+ string?: string | string[];
37
+ /** A function which is invoked with a command line parameter not defined in
38
+ * the `options` configuration object. If the function returns `false`, the
39
+ * unknown option is not added to `parsedArgs`. */
40
+ unknown?: (arg: string, key?: string, value?: unknown) => unknown;
41
+ }
42
+ /** Take a set of command line arguments, with an optional set of options, and
43
+ * return an object representation of those argument.
44
+ *
45
+ * ```ts
46
+ * import { parse } from "./mod.ts";
47
+ * const parsedArgs = parse(Deno.args);
48
+ * ```
49
+ */
50
+ export declare function parse(args: string[], { "--": doubleDash, alias, boolean, default: defaults, stopEarly, string, unknown, }?: ArgParsingOptions): Args;
@@ -0,0 +1,2 @@
1
+ export declare type DateLike = Date | number | string;
2
+ export declare function parseDateLike(date: DateLike): number;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "./_dnt.polyfills.js";
package/types/mod.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import "./_dnt.polyfills.js";
1
2
  /**
2
3
  * Check if a year is a [leap year](https://en.wikipedia.org/wiki/Leap_year).
3
4
  *
@@ -14,9 +15,8 @@
14
15
  * isLeapYear(new Date(2016, 1, 1)); //=> true
15
16
  * ```
16
17
  */
17
- export declare function isLeapYear(year?: DateLike): boolean;
18
- export declare function generateLeapYear(config: {
19
- min?: number;
20
- max?: DateLike;
21
- }): number[];
22
- export declare type DateLike = Date | number | string;
18
+ export declare function isLeapYear(year?: Date | string | number): boolean;
19
+ export declare function isLeapYear(year?: Date | string | number, returnValue?: boolean): {
20
+ year: number;
21
+ result: boolean;
22
+ };