@nyaomaru/divider 1.9.17 → 1.9.19

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
@@ -209,9 +209,22 @@ Some common use cases are wrapped as presets for convenience.
209
209
  | `emailDivider` | Divide email into [local-part, domain] (by '@') |
210
210
  | `csvDivider` | Divide comma-separated strings, with quoted field support |
211
211
  | `pathDivider` | Divide file paths by / or \| |
212
+ | `queryDivider` | Divide query strings into [key, value] pairs (URL-safe) |
212
213
 
213
214
  [Presets detail](src/presets/README.md)
214
215
 
216
+ Example:
217
+
218
+ ```ts
219
+ import { queryDivider } from '@nyaomaru/divider';
220
+
221
+ queryDivider('?q=hello+world');
222
+ // [['q', 'hello world']] // default: '+' treated as space and % decoded
223
+
224
+ queryDivider('q=hello+world', { mode: 'raw' });
225
+ // [['q', 'hello+world']] // raw mode keeps '+' and % as-is
226
+ ```
227
+
215
228
  ## 🎯 General Options
216
229
 
217
230
  | Option | Type | Default | Description |
package/dist/index.cjs CHANGED
@@ -27,7 +27,8 @@ __export(index_exports, {
27
27
  dividerLoop: () => dividerLoop,
28
28
  dividerNumberString: () => dividerNumberString,
29
29
  emailDivider: () => emailDivider,
30
- pathDivider: () => pathDivider
30
+ pathDivider: () => pathDivider,
31
+ queryDivider: () => queryDivider
31
32
  });
32
33
  module.exports = __toCommonJS(index_exports);
33
34
 
@@ -509,6 +510,45 @@ function pathDivider(input, options = {}) {
509
510
  const maybeTrimmed = trim ? segments.map((segment) => segment.trim()) : segments;
510
511
  return collapse ? maybeTrimmed.filter((segment) => !isEmptyString(segment)) : maybeTrimmed;
511
512
  }
513
+
514
+ // src/presets/query-divider.ts
515
+ function tryExtractQuery(input) {
516
+ try {
517
+ const url = new URL(input);
518
+ return url.search.startsWith("?") ? url.search.slice(1) : url.search;
519
+ } catch {
520
+ return input;
521
+ }
522
+ }
523
+ function stripLeadingQuestionMark(query) {
524
+ return query.startsWith("?") ? query.slice(1) : query;
525
+ }
526
+ function splitOnFirstEquals(part) {
527
+ const kv = dividePreserve(part, "=");
528
+ if (kv.length === 1) return [kv[0] ?? "", ""];
529
+ return [kv[0] ?? "", kv.slice(1).join("=")];
530
+ }
531
+ function decodeField(text, mode, trim) {
532
+ let t = text;
533
+ if (mode === "auto") {
534
+ t = t.replace(/\+/g, " ");
535
+ try {
536
+ t = decodeURIComponent(t);
537
+ } catch {
538
+ }
539
+ }
540
+ if (trim) t = t.trim();
541
+ return t;
542
+ }
543
+ function queryDivider(input, { mode = "auto", trim = false } = {}) {
544
+ if (input.length === 0) return [];
545
+ const query = stripLeadingQuestionMark(tryExtractQuery(input));
546
+ if (query.length === 0) return [];
547
+ return dividePreserve(query, "&").map((part) => {
548
+ const [key, value] = splitOnFirstEquals(part);
549
+ return [decodeField(key, mode, trim), decodeField(value, mode, trim)];
550
+ });
551
+ }
512
552
  // Annotate the CommonJS export names for ESM import in node:
513
553
  0 && (module.exports = {
514
554
  csvDivider,
@@ -518,5 +558,6 @@ function pathDivider(input, options = {}) {
518
558
  dividerLoop,
519
559
  dividerNumberString,
520
560
  emailDivider,
521
- pathDivider
561
+ pathDivider,
562
+ queryDivider
522
563
  });
package/dist/index.d.cts CHANGED
@@ -158,6 +158,11 @@ type PathDividerOptions = Pick<DividerOptions, 'trim'> & {
158
158
  /** Collapse empty segments produced by leading/trailing or repeated separators. */
159
159
  collapse?: boolean;
160
160
  };
161
+ type QueryDecodeMode = 'auto' | 'raw';
162
+ type QueryDividerOptions = Pick<DividerOptions, 'trim'> & {
163
+ /** Decoding mode: 'auto' applies standard URL decoding; 'raw' leaves values untouched. */
164
+ mode?: QueryDecodeMode;
165
+ };
161
166
 
162
167
  /**
163
168
  * Divides a CSV line into an array of fields, handling quoted values appropriately.
@@ -190,4 +195,15 @@ declare function emailDivider(input: string, options?: EmailDividerOptions): Div
190
195
  */
191
196
  declare function pathDivider(input: string, options?: PathDividerOptions): DividerStringResult;
192
197
 
193
- export { type DividerArg, type DividerArgs, type DividerArrayResult, type DividerEmptyOptions, type DividerExcludeMode, type DividerInferredOptions, type DividerInput, type DividerLoopEmptyOptions, type DividerLoopOptions, type DividerLoopOptionsLike, type DividerOptions, type DividerResult, type DividerSeparator, type DividerSeparators, type DividerStringResult, type ExtractedDividerOptions, type NumericSeparator, type StringArrayInput, type StringInput, type StringSeparator, csvDivider, divider, dividerFirst, dividerLast, dividerLoop, dividerNumberString, emailDivider, pathDivider };
198
+ /**
199
+ * Divide a query string into key/value pairs.
200
+ * - Supports raw query (with or without leading '?').
201
+ * - Accepts full URLs (query extracted automatically).
202
+ * - Preserves empty keys/values and trailing separators.
203
+ * @param input Query string or full URL.
204
+ * @param options Parsing options: { mode?: 'auto' | 'raw'; trim?: boolean }.
205
+ * @returns Array of [key, value] string tuples in input order.
206
+ */
207
+ declare function queryDivider(input: string, { mode, trim }?: QueryDividerOptions): DividerArrayResult;
208
+
209
+ export { type DividerArg, type DividerArgs, type DividerArrayResult, type DividerEmptyOptions, type DividerExcludeMode, type DividerInferredOptions, type DividerInput, type DividerLoopEmptyOptions, type DividerLoopOptions, type DividerLoopOptionsLike, type DividerOptions, type DividerResult, type DividerSeparator, type DividerSeparators, type DividerStringResult, type ExtractedDividerOptions, type NumericSeparator, type StringArrayInput, type StringInput, type StringSeparator, csvDivider, divider, dividerFirst, dividerLast, dividerLoop, dividerNumberString, emailDivider, pathDivider, queryDivider };
package/dist/index.d.ts CHANGED
@@ -158,6 +158,11 @@ type PathDividerOptions = Pick<DividerOptions, 'trim'> & {
158
158
  /** Collapse empty segments produced by leading/trailing or repeated separators. */
159
159
  collapse?: boolean;
160
160
  };
161
+ type QueryDecodeMode = 'auto' | 'raw';
162
+ type QueryDividerOptions = Pick<DividerOptions, 'trim'> & {
163
+ /** Decoding mode: 'auto' applies standard URL decoding; 'raw' leaves values untouched. */
164
+ mode?: QueryDecodeMode;
165
+ };
161
166
 
162
167
  /**
163
168
  * Divides a CSV line into an array of fields, handling quoted values appropriately.
@@ -190,4 +195,15 @@ declare function emailDivider(input: string, options?: EmailDividerOptions): Div
190
195
  */
191
196
  declare function pathDivider(input: string, options?: PathDividerOptions): DividerStringResult;
192
197
 
193
- export { type DividerArg, type DividerArgs, type DividerArrayResult, type DividerEmptyOptions, type DividerExcludeMode, type DividerInferredOptions, type DividerInput, type DividerLoopEmptyOptions, type DividerLoopOptions, type DividerLoopOptionsLike, type DividerOptions, type DividerResult, type DividerSeparator, type DividerSeparators, type DividerStringResult, type ExtractedDividerOptions, type NumericSeparator, type StringArrayInput, type StringInput, type StringSeparator, csvDivider, divider, dividerFirst, dividerLast, dividerLoop, dividerNumberString, emailDivider, pathDivider };
198
+ /**
199
+ * Divide a query string into key/value pairs.
200
+ * - Supports raw query (with or without leading '?').
201
+ * - Accepts full URLs (query extracted automatically).
202
+ * - Preserves empty keys/values and trailing separators.
203
+ * @param input Query string or full URL.
204
+ * @param options Parsing options: { mode?: 'auto' | 'raw'; trim?: boolean }.
205
+ * @returns Array of [key, value] string tuples in input order.
206
+ */
207
+ declare function queryDivider(input: string, { mode, trim }?: QueryDividerOptions): DividerArrayResult;
208
+
209
+ export { type DividerArg, type DividerArgs, type DividerArrayResult, type DividerEmptyOptions, type DividerExcludeMode, type DividerInferredOptions, type DividerInput, type DividerLoopEmptyOptions, type DividerLoopOptions, type DividerLoopOptionsLike, type DividerOptions, type DividerResult, type DividerSeparator, type DividerSeparators, type DividerStringResult, type ExtractedDividerOptions, type NumericSeparator, type StringArrayInput, type StringInput, type StringSeparator, csvDivider, divider, dividerFirst, dividerLast, dividerLoop, dividerNumberString, emailDivider, pathDivider, queryDivider };
package/dist/index.js CHANGED
@@ -476,6 +476,45 @@ function pathDivider(input, options = {}) {
476
476
  const maybeTrimmed = trim ? segments.map((segment) => segment.trim()) : segments;
477
477
  return collapse ? maybeTrimmed.filter((segment) => !isEmptyString(segment)) : maybeTrimmed;
478
478
  }
479
+
480
+ // src/presets/query-divider.ts
481
+ function tryExtractQuery(input) {
482
+ try {
483
+ const url = new URL(input);
484
+ return url.search.startsWith("?") ? url.search.slice(1) : url.search;
485
+ } catch {
486
+ return input;
487
+ }
488
+ }
489
+ function stripLeadingQuestionMark(query) {
490
+ return query.startsWith("?") ? query.slice(1) : query;
491
+ }
492
+ function splitOnFirstEquals(part) {
493
+ const kv = dividePreserve(part, "=");
494
+ if (kv.length === 1) return [kv[0] ?? "", ""];
495
+ return [kv[0] ?? "", kv.slice(1).join("=")];
496
+ }
497
+ function decodeField(text, mode, trim) {
498
+ let t = text;
499
+ if (mode === "auto") {
500
+ t = t.replace(/\+/g, " ");
501
+ try {
502
+ t = decodeURIComponent(t);
503
+ } catch {
504
+ }
505
+ }
506
+ if (trim) t = t.trim();
507
+ return t;
508
+ }
509
+ function queryDivider(input, { mode = "auto", trim = false } = {}) {
510
+ if (input.length === 0) return [];
511
+ const query = stripLeadingQuestionMark(tryExtractQuery(input));
512
+ if (query.length === 0) return [];
513
+ return dividePreserve(query, "&").map((part) => {
514
+ const [key, value] = splitOnFirstEquals(part);
515
+ return [decodeField(key, mode, trim), decodeField(value, mode, trim)];
516
+ });
517
+ }
479
518
  export {
480
519
  csvDivider,
481
520
  divider,
@@ -484,5 +523,6 @@ export {
484
523
  dividerLoop,
485
524
  dividerNumberString,
486
525
  emailDivider,
487
- pathDivider
526
+ pathDivider,
527
+ queryDivider
488
528
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nyaomaru/divider",
3
3
  "type": "module",
4
- "version": "1.9.17",
4
+ "version": "1.9.19",
5
5
  "description": "To divide string or string[] with a given separator",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",