@hugoalh/adler32 0.5.0 → 0.6.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.
@@ -0,0 +1,372 @@
1
+ // Copyright 2018-2026 the Deno authors. MIT license.
2
+ // This module is browser compatible.
3
+ const FLAG_REGEXP = /^(?:-(?:(?<doubleDash>-)(?<negated>no-)?)?)(?<key>.+?)(?:=(?<value>.*))?$/s;
4
+ const LETTER_REGEXP = /[A-Za-z]/;
5
+ const NUMBER_REGEXP = /-?\d+(\.\d*)?(e-?\d+)?$/;
6
+ const HYPHEN_REGEXP = /^(-|--)[^-]/;
7
+ const VALUE_REGEXP = /=(?<value>.+)/;
8
+ const FLAG_NAME_REGEXP = /^--[^=]+$/;
9
+ const SPECIAL_CHAR_REGEXP = /\W/;
10
+ const NON_WHITESPACE_REGEXP = /\S/;
11
+ function isNumber(string) {
12
+ return NON_WHITESPACE_REGEXP.test(string) && Number.isFinite(Number(string));
13
+ }
14
+ function isConstructorOrProto(obj, key) {
15
+ return (key === "constructor" && typeof obj[key] === "function") ||
16
+ key === "__proto__";
17
+ }
18
+ function setNested(object, keys, value, collect = false) {
19
+ keys = [...keys];
20
+ const key = keys.pop();
21
+ for (const k of keys) {
22
+ if (isConstructorOrProto(object, k))
23
+ return;
24
+ object = (object[k] ??= {});
25
+ }
26
+ if (isConstructorOrProto(object, key))
27
+ return;
28
+ if (collect) {
29
+ const v = object[key];
30
+ if (Array.isArray(v)) {
31
+ v.push(value);
32
+ return;
33
+ }
34
+ value = v ? [v, value] : [value];
35
+ }
36
+ object[key] = value;
37
+ }
38
+ function hasNested(object, keys) {
39
+ for (const key of keys) {
40
+ const value = object[key];
41
+ if (!Object.hasOwn(object, key))
42
+ return false;
43
+ object = value;
44
+ }
45
+ return true;
46
+ }
47
+ function aliasIsBoolean(aliasMap, booleanSet, key) {
48
+ const set = aliasMap.get(key);
49
+ if (set === undefined)
50
+ return false;
51
+ for (const alias of set)
52
+ if (booleanSet.has(alias))
53
+ return true;
54
+ return false;
55
+ }
56
+ function isBooleanString(value) {
57
+ return value === "true" || value === "false";
58
+ }
59
+ function parseBooleanString(value) {
60
+ return value !== "false";
61
+ }
62
+ /**
63
+ * Take a set of command line arguments, optionally with a set of options, and
64
+ * return an object representing the flags found in the passed arguments.
65
+ *
66
+ * By default, any arguments starting with `-` or `--` are considered boolean
67
+ * flags. If the argument name is followed by an equal sign (`=`) it is
68
+ * considered a key-value pair. Any arguments which could not be parsed are
69
+ * available in the `_` property of the returned object.
70
+ *
71
+ * By default, this module tries to determine the type of all arguments
72
+ * automatically and the return type of this function will have an index
73
+ * signature with `any` as value (`{ [x: string]: any }`).
74
+ *
75
+ * If the `string`, `boolean` or `collect` option is set, the return value of
76
+ * this function will be fully typed and the index signature of the return
77
+ * type will change to `{ [x: string]: unknown }`.
78
+ *
79
+ * Any arguments after `'--'` will not be parsed and will end up in `parsedArgs._`.
80
+ *
81
+ * Numeric-looking arguments will be returned as numbers unless `options.string`
82
+ * or `options.boolean` is set for that argument name.
83
+ *
84
+ * See {@linkcode ParseOptions} for more information.
85
+ *
86
+ * @param args An array of command line arguments.
87
+ * @param options Options for the parse function.
88
+ *
89
+ * @typeParam TArgs Type of result.
90
+ * @typeParam TDoubleDash Used by `TArgs` for the result.
91
+ * @typeParam TBooleans Used by `TArgs` for the result.
92
+ * @typeParam TStrings Used by `TArgs` for the result.
93
+ * @typeParam TCollectable Used by `TArgs` for the result.
94
+ * @typeParam TNegatable Used by `TArgs` for the result.
95
+ * @typeParam TDefaults Used by `TArgs` for the result.
96
+ * @typeParam TAliases Used by `TArgs` for the result.
97
+ * @typeParam TAliasArgNames Used by `TArgs` for the result.
98
+ * @typeParam TAliasNames Used by `TArgs` for the result.
99
+ *
100
+ * @return The parsed arguments.
101
+ *
102
+ * @example Usage
103
+ * ```ts
104
+ * import { parseArgs } from "@std/cli/parse-args";
105
+ * import { assertEquals } from "@std/assert/equals";
106
+ *
107
+ * // For proper use, one should use `parseArgs(Deno.args)`
108
+ * assertEquals(parseArgs(["--foo", "--bar=baz", "./quux.txt"]), {
109
+ * foo: true,
110
+ * bar: "baz",
111
+ * _: ["./quux.txt"],
112
+ * });
113
+ * ```
114
+ *
115
+ * @example `string` and `boolean` options
116
+ *
117
+ * Use `string` and `boolean` options to specify the type of the argument.
118
+ *
119
+ * ```ts
120
+ * import { parseArgs } from "@std/cli/parse-args";
121
+ * import { assertEquals } from "@std/assert/equals";
122
+ *
123
+ * const args = parseArgs(["--foo", "--bar", "baz"], {
124
+ * boolean: ["foo"],
125
+ * string: ["bar"],
126
+ * });
127
+ *
128
+ * assertEquals(args, { foo: true, bar: "baz", _: [] });
129
+ * ```
130
+ *
131
+ * @example `collect` option
132
+ *
133
+ * `collect` option tells the parser to treat the option as an array. All
134
+ * values will be collected into one array. If a non-collectable option is used
135
+ * multiple times, the last value is used.
136
+ *
137
+ * ```ts
138
+ * import { parseArgs } from "@std/cli/parse-args";
139
+ * import { assertEquals } from "@std/assert/equals";
140
+ *
141
+ * const args = parseArgs(["--foo", "bar", "--foo", "baz"], {
142
+ * collect: ["foo"],
143
+ * });
144
+ *
145
+ * assertEquals(args, { foo: ["bar", "baz"], _: [] });
146
+ * ```
147
+ *
148
+ * @example `negatable` option
149
+ *
150
+ * `negatable` option tells the parser to treat the option can be negated by
151
+ * prefixing them with `--no-`, like `--no-config`.
152
+ *
153
+ * ```ts
154
+ * import { parseArgs } from "@std/cli/parse-args";
155
+ * import { assertEquals } from "@std/assert/equals";
156
+ *
157
+ * const args = parseArgs(["--no-foo"], {
158
+ * boolean: ["foo"],
159
+ * negatable: ["foo"],
160
+ * });
161
+ *
162
+ * assertEquals(args, { foo: false, _: [] });
163
+ * ```
164
+ */
165
+ export function parseArgs(args, options) {
166
+ const { "--": doubleDash = false, alias = {}, boolean = false, default: defaults = {}, stopEarly = false, string = [], collect = [], negatable = [], unknown: unknownFn = (i) => i, } = options ?? {};
167
+ const aliasMap = new Map();
168
+ const booleanSet = new Set();
169
+ const stringSet = new Set();
170
+ const collectSet = new Set();
171
+ const negatableSet = new Set();
172
+ let allBools = false;
173
+ if (alias) {
174
+ for (const [key, value] of Object.entries(alias)) {
175
+ if (value === undefined) {
176
+ throw new TypeError("Alias value must be defined");
177
+ }
178
+ const aliases = Array.isArray(value) ? value : [value];
179
+ aliasMap.set(key, new Set(aliases));
180
+ aliases.forEach((alias) => aliasMap.set(alias, new Set([key, ...aliases.filter((it) => it !== alias)])));
181
+ }
182
+ }
183
+ if (boolean) {
184
+ if (typeof boolean === "boolean") {
185
+ allBools = boolean;
186
+ }
187
+ else {
188
+ const booleanArgs = Array.isArray(boolean) ? boolean : [boolean];
189
+ for (const key of booleanArgs.filter(Boolean)) {
190
+ booleanSet.add(key);
191
+ aliasMap.get(key)?.forEach((al) => {
192
+ booleanSet.add(al);
193
+ });
194
+ }
195
+ }
196
+ }
197
+ if (string) {
198
+ const stringArgs = Array.isArray(string) ? string : [string];
199
+ for (const key of stringArgs.filter(Boolean)) {
200
+ stringSet.add(key);
201
+ aliasMap.get(key)?.forEach((al) => stringSet.add(al));
202
+ }
203
+ }
204
+ if (collect) {
205
+ const collectArgs = Array.isArray(collect) ? collect : [collect];
206
+ for (const key of collectArgs.filter(Boolean)) {
207
+ collectSet.add(key);
208
+ aliasMap.get(key)?.forEach((al) => collectSet.add(al));
209
+ }
210
+ }
211
+ if (negatable) {
212
+ const negatableArgs = Array.isArray(negatable) ? negatable : [negatable];
213
+ for (const key of negatableArgs.filter(Boolean)) {
214
+ negatableSet.add(key);
215
+ aliasMap.get(key)?.forEach((alias) => negatableSet.add(alias));
216
+ }
217
+ }
218
+ const argv = { _: [] };
219
+ function setArgument(key, value, arg, collect) {
220
+ if (!booleanSet.has(key) &&
221
+ !stringSet.has(key) &&
222
+ !aliasMap.has(key) &&
223
+ !collectSet.has(key) &&
224
+ !(allBools && FLAG_NAME_REGEXP.test(arg)) &&
225
+ unknownFn?.(arg, key, value) === false) {
226
+ return;
227
+ }
228
+ if (typeof value === "string" && !stringSet.has(key)) {
229
+ value = isNumber(value) ? Number(value) : value;
230
+ }
231
+ const collectable = collect && collectSet.has(key);
232
+ setNested(argv, key.split("."), value, collectable);
233
+ aliasMap.get(key)?.forEach((key) => {
234
+ setNested(argv, key.split("."), value, collectable);
235
+ });
236
+ }
237
+ let notFlags = [];
238
+ // all args after "--" are not parsed
239
+ const index = args.indexOf("--");
240
+ if (index !== -1) {
241
+ notFlags = args.slice(index + 1);
242
+ args = args.slice(0, index);
243
+ }
244
+ argsLoop: for (let i = 0; i < args.length; i++) {
245
+ const arg = args[i];
246
+ const groups = arg.match(FLAG_REGEXP)?.groups;
247
+ if (groups) {
248
+ const { doubleDash, negated } = groups;
249
+ let key = groups.key;
250
+ let value = groups.value;
251
+ if (doubleDash) {
252
+ if (value != null) {
253
+ if (booleanSet.has(key))
254
+ value = parseBooleanString(value);
255
+ setArgument(key, value, arg, true);
256
+ continue;
257
+ }
258
+ if (negated) {
259
+ if (negatableSet.has(key)) {
260
+ setArgument(key, false, arg, false);
261
+ continue;
262
+ }
263
+ key = `no-${key}`;
264
+ }
265
+ const next = args[i + 1];
266
+ if (next) {
267
+ if (!booleanSet.has(key) &&
268
+ !allBools &&
269
+ !next.startsWith("-") &&
270
+ (!aliasMap.has(key) || !aliasIsBoolean(aliasMap, booleanSet, key))) {
271
+ value = next;
272
+ i++;
273
+ setArgument(key, value, arg, true);
274
+ continue;
275
+ }
276
+ if (isBooleanString(next)) {
277
+ value = parseBooleanString(next);
278
+ i++;
279
+ setArgument(key, value, arg, true);
280
+ continue;
281
+ }
282
+ }
283
+ value = stringSet.has(key) ? "" : true;
284
+ setArgument(key, value, arg, true);
285
+ continue;
286
+ }
287
+ const letters = arg.slice(1, -1).split("");
288
+ for (const [j, letter] of letters.entries()) {
289
+ const next = arg.slice(j + 2);
290
+ if (next === "-") {
291
+ setArgument(letter, next, arg, true);
292
+ continue;
293
+ }
294
+ if (next === "=") {
295
+ setArgument(letter, "", arg, true);
296
+ continue argsLoop;
297
+ }
298
+ if (LETTER_REGEXP.test(letter)) {
299
+ const groups = VALUE_REGEXP.exec(next)?.groups;
300
+ if (groups) {
301
+ setArgument(letter, groups.value, arg, true);
302
+ continue argsLoop;
303
+ }
304
+ if (NUMBER_REGEXP.test(next)) {
305
+ setArgument(letter, next, arg, true);
306
+ continue argsLoop;
307
+ }
308
+ }
309
+ if (letters[j + 1]?.match(SPECIAL_CHAR_REGEXP)) {
310
+ setArgument(letter, arg.slice(j + 2), arg, true);
311
+ continue argsLoop;
312
+ }
313
+ setArgument(letter, stringSet.has(letter) ? "" : true, arg, true);
314
+ }
315
+ key = arg.slice(-1);
316
+ if (key === "-")
317
+ continue;
318
+ const nextArg = args[i + 1];
319
+ if (nextArg) {
320
+ if (!HYPHEN_REGEXP.test(nextArg) &&
321
+ !booleanSet.has(key) &&
322
+ (!aliasMap.has(key) || !aliasIsBoolean(aliasMap, booleanSet, key))) {
323
+ setArgument(key, nextArg, arg, true);
324
+ i++;
325
+ continue;
326
+ }
327
+ if (isBooleanString(nextArg)) {
328
+ const value = parseBooleanString(nextArg);
329
+ setArgument(key, value, arg, true);
330
+ i++;
331
+ continue;
332
+ }
333
+ }
334
+ setArgument(key, stringSet.has(key) ? "" : true, arg, true);
335
+ continue;
336
+ }
337
+ if (unknownFn?.(arg) !== false) {
338
+ argv._.push(stringSet.has("_") || !isNumber(arg) ? arg : Number(arg));
339
+ }
340
+ if (stopEarly) {
341
+ argv._.push(...args.slice(i + 1));
342
+ break;
343
+ }
344
+ }
345
+ for (const [key, value] of Object.entries(defaults)) {
346
+ const keys = key.split(".");
347
+ if (!hasNested(argv, keys)) {
348
+ setNested(argv, keys, value);
349
+ aliasMap.get(key)?.forEach((key) => setNested(argv, key.split("."), value));
350
+ }
351
+ }
352
+ for (const key of booleanSet.keys()) {
353
+ const keys = key.split(".");
354
+ if (!hasNested(argv, keys)) {
355
+ const value = collectSet.has(key) ? [] : false;
356
+ setNested(argv, keys, value);
357
+ }
358
+ }
359
+ for (const key of stringSet.keys()) {
360
+ const keys = key.split(".");
361
+ if (!hasNested(argv, keys) && collectSet.has(key)) {
362
+ setNested(argv, keys, []);
363
+ }
364
+ }
365
+ if (doubleDash) {
366
+ argv["--"] = notFlags;
367
+ }
368
+ else {
369
+ argv._.push(...notFlags);
370
+ }
371
+ return argv;
372
+ }
package/mod.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import "./_dnt.polyfills.js";
1
2
  export type Adler32AcceptDataType = string | BigUint64Array | Uint8Array | Uint16Array | Uint32Array;
2
3
  /**
3
4
  * Get the checksum of the data with algorithm Adler32.
package/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["src/mod.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAC9B,MAAM,GACN,cAAc,GACd,UAAU,GACV,WAAW,GACX,WAAW,CAAC;AACf;;GAEG;AACH,qBAAa,OAAO;;IACnB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAEjC;IAMD;;;OAGG;gBACS,IAAI,CAAC,EAAE,qBAAqB;IAKxC;;;OAGG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IACD;;;OAGG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,IAAI,IAAI,UAAU;IAalB;;;OAGG;IACH,OAAO,IAAI,MAAM;IASjB;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAazC;;;;OAIG;IACG,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAMpF;AACD,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAK7B,MAAM,MAAM,qBAAqB,GAC9B,MAAM,GACN,cAAc,GACd,UAAU,GACV,WAAW,GACX,WAAW,CAAC;AACf;;GAEG;AACH,qBAAa,OAAO;;IACnB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAEjC;IAMD;;;OAGG;gBACS,IAAI,CAAC,EAAE,qBAAqB;IAKxC;;;OAGG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IACD;;;OAGG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,IAAI,IAAI,UAAU;IAIlB;;;OAGG;IACH,OAAO,IAAI,MAAM;IAUjB;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAazC;;;;OAIG;IACG,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAMpF;AACD,eAAe,OAAO,CAAC"}
package/mod.js CHANGED
@@ -1,3 +1,8 @@
1
+ import "./_dnt.polyfills.js";
2
+ if (typeof Uint8Array.fromHex === "undefined") {
3
+ //deno-lint-ignore hugoalh/no-import-dynamic -- Polyfill.
4
+ await import("es-arraybuffer-base64/Uint8Array.fromHex/auto");
5
+ }
1
6
  /**
2
7
  * Get the checksum of the data with algorithm Adler32.
3
8
  */
@@ -39,16 +44,7 @@ export class Adler32 {
39
44
  * @returns {Uint8Array}
40
45
  */
41
46
  hash() {
42
- if (this.#hashUint8Array === null) {
43
- const hex = this.hashHex();
44
- const bytes = [];
45
- for (let index = 0; index < hex.length; index += 2) {
46
- bytes.push(hex.slice(index, index + 2));
47
- }
48
- this.#hashUint8Array = Uint8Array.from(bytes.map((byte) => {
49
- return Number.parseInt(byte, 16);
50
- }));
51
- }
47
+ this.#hashUint8Array ??= Uint8Array.fromHex(this.hashHex());
52
48
  return Uint8Array.from(this.#hashUint8Array);
53
49
  }
54
50
  /**
@@ -57,10 +53,11 @@ export class Adler32 {
57
53
  */
58
54
  hashHex() {
59
55
  if (this.#hashHex === null) {
60
- this.#hashHex = (this.#b * 65536n + this.#a).toString(16).toUpperCase().padStart(8, "0");
61
- if (this.#hashHex.length !== 8) {
62
- throw new Error(`Unexpected hash hex result \`${this.#hashHex}\`! Please submit a bug report.`);
56
+ const result = (this.#b * 65536n + this.#a).toString(16).toUpperCase().padStart(8, "0");
57
+ if (result.length !== 8) {
58
+ throw new Error(`Unexpected hash hex result \`${result}\`! Please submit a bug report.`);
63
59
  }
60
+ this.#hashHex = result;
64
61
  }
65
62
  return this.#hashHex;
66
63
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hugoalh/adler32",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "A module to get the checksum of the data with algorithm Adler32.",
5
5
  "keywords": [
6
6
  "adler32",
@@ -13,9 +13,18 @@
13
13
  "license": "MIT",
14
14
  "author": "hugoalh",
15
15
  "type": "module",
16
+ "bin": {
17
+ "adler32": "./cli.js"
18
+ },
16
19
  "main": "./mod.js",
17
20
  "module": "./mod.js",
18
21
  "exports": {
22
+ "./cli": {
23
+ "import": {
24
+ "types": "./cli.d.ts",
25
+ "default": "./cli.js"
26
+ }
27
+ },
19
28
  ".": {
20
29
  "import": {
21
30
  "types": "./mod.d.ts",
@@ -28,11 +37,15 @@
28
37
  "type": "git",
29
38
  "url": "git+https://github.com/hugoalh/adler32-es.git"
30
39
  },
31
- "scripts": {},
40
+ "dependencies": {
41
+ "es-arraybuffer-base64": "^1.1.2",
42
+ "@deno/shim-deno": "^0.19.2",
43
+ "@deno/shim-prompts": "^0.1.1",
44
+ "@deno/shim-timers": "^0.1.0"
45
+ },
32
46
  "devDependencies": {
33
- "@types/node": "^20.9.0"
47
+ "@types/node": "^24.5.0"
34
48
  },
35
- "engines": {},
36
49
  "private": false,
37
50
  "publishConfig": {
38
51
  "access": "public"