zustand-querystring 0.4.1 → 0.5.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 +277 -60
- package/dist/chunk-TQQUWVLF.mjs +367 -0
- package/dist/format/json.d.mts +6 -0
- package/dist/format/json.d.ts +6 -0
- package/dist/format/json.js +59 -0
- package/dist/format/json.mjs +35 -0
- package/dist/format/marked.d.mts +67 -0
- package/dist/format/marked.d.ts +67 -0
- package/dist/format/marked.js +393 -0
- package/dist/format/marked.mjs +14 -0
- package/dist/format/plain.d.mts +49 -0
- package/dist/format/plain.d.ts +49 -0
- package/dist/format/plain.js +446 -0
- package/dist/format/plain.mjs +421 -0
- package/dist/index.d.mts +33 -16
- package/dist/index.d.ts +33 -16
- package/dist/index.js +442 -105
- package/dist/index.mjs +89 -106
- package/package.json +34 -8
- package/dist/format/readable.d.mts +0 -14
- package/dist/format/readable.d.ts +0 -14
- package/dist/format/readable.js +0 -238
- package/dist/format/readable.mjs +0 -212
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/format/marked.ts
|
|
20
|
+
var marked_exports = {};
|
|
21
|
+
__export(marked_exports, {
|
|
22
|
+
createFormat: () => createFormat,
|
|
23
|
+
default: () => marked_default,
|
|
24
|
+
marked: () => marked,
|
|
25
|
+
parse: () => parse,
|
|
26
|
+
stringify: () => stringify
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(marked_exports);
|
|
29
|
+
function resolveOptions(opts = {}) {
|
|
30
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
31
|
+
return {
|
|
32
|
+
typeObject: (_a = opts.typeObject) != null ? _a : ".",
|
|
33
|
+
typeArray: (_b = opts.typeArray) != null ? _b : "@",
|
|
34
|
+
typeString: (_c = opts.typeString) != null ? _c : "=",
|
|
35
|
+
typePrimitive: (_d = opts.typePrimitive) != null ? _d : ":",
|
|
36
|
+
separator: (_e = opts.separator) != null ? _e : ",",
|
|
37
|
+
terminator: (_f = opts.terminator) != null ? _f : "~",
|
|
38
|
+
escape: (_g = opts.escapeChar) != null ? _g : "_",
|
|
39
|
+
datePrefix: (_h = opts.datePrefix) != null ? _h : "D"
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function validateOptions(opts) {
|
|
43
|
+
const tokens = [
|
|
44
|
+
opts.typeObject,
|
|
45
|
+
opts.typeArray,
|
|
46
|
+
opts.typeString,
|
|
47
|
+
opts.typePrimitive,
|
|
48
|
+
opts.separator,
|
|
49
|
+
opts.terminator,
|
|
50
|
+
opts.escape
|
|
51
|
+
];
|
|
52
|
+
for (const token of tokens) {
|
|
53
|
+
if (token.length === 0) {
|
|
54
|
+
throw new Error("All tokens must be non-empty strings");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (opts.datePrefix.length === 0) {
|
|
58
|
+
throw new Error("datePrefix must be non-empty");
|
|
59
|
+
}
|
|
60
|
+
const seen = /* @__PURE__ */ new Set();
|
|
61
|
+
for (const token of tokens) {
|
|
62
|
+
if (seen.has(token)) {
|
|
63
|
+
throw new Error(`Duplicate token detected: '${token}'`);
|
|
64
|
+
}
|
|
65
|
+
seen.add(token);
|
|
66
|
+
}
|
|
67
|
+
if (seen.has(opts.datePrefix)) {
|
|
68
|
+
throw new Error(`datePrefix '${opts.datePrefix}' conflicts with another token`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function escapeRegex(str) {
|
|
72
|
+
return str.replace(/[.$^*+?()[\]{}|\\-]/g, "\\$&");
|
|
73
|
+
}
|
|
74
|
+
function buildKeyStopPattern(opts) {
|
|
75
|
+
return new RegExp(
|
|
76
|
+
`[${escapeRegex(opts.typeString)}${escapeRegex(opts.typePrimitive)}${escapeRegex(opts.typeArray)}${escapeRegex(opts.typeObject)}${escapeRegex(opts.separator)}]`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
function buildValueStopPattern(opts) {
|
|
80
|
+
return new RegExp(`[${escapeRegex(opts.separator)}${escapeRegex(opts.terminator)}]`);
|
|
81
|
+
}
|
|
82
|
+
function buildKeyEscapePattern(opts) {
|
|
83
|
+
return new RegExp(
|
|
84
|
+
`([${escapeRegex(opts.typeString)}${escapeRegex(opts.typePrimitive)}${escapeRegex(opts.typeArray)}${escapeRegex(opts.typeObject)}${escapeRegex(opts.separator)}])`,
|
|
85
|
+
"g"
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function buildValueEscapePattern(opts) {
|
|
89
|
+
return new RegExp(`([${escapeRegex(opts.separator)}${escapeRegex(opts.terminator)}])`, "g");
|
|
90
|
+
}
|
|
91
|
+
function buildDatePattern(opts) {
|
|
92
|
+
return new RegExp(`^${escapeRegex(opts.datePrefix)}-?\\d+$`);
|
|
93
|
+
}
|
|
94
|
+
function buildDateStartPattern(opts) {
|
|
95
|
+
return new RegExp(`^${escapeRegex(opts.datePrefix)}-?\\d`);
|
|
96
|
+
}
|
|
97
|
+
function encodePreservingMarkers(str, opts) {
|
|
98
|
+
const markers = /* @__PURE__ */ new Set([
|
|
99
|
+
opts.typeObject,
|
|
100
|
+
opts.typeArray,
|
|
101
|
+
opts.typeString,
|
|
102
|
+
opts.typePrimitive,
|
|
103
|
+
opts.separator,
|
|
104
|
+
opts.terminator,
|
|
105
|
+
opts.escape
|
|
106
|
+
]);
|
|
107
|
+
let result = "";
|
|
108
|
+
for (const char of str) {
|
|
109
|
+
if (markers.has(char)) {
|
|
110
|
+
result += char;
|
|
111
|
+
} else {
|
|
112
|
+
result += encodeURIComponent(char);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
function escapeStr(str, pattern, escape, opts) {
|
|
118
|
+
return encodePreservingMarkers(str.replace(pattern, `${escape}$1`), opts);
|
|
119
|
+
}
|
|
120
|
+
function cleanResult(str, standalone, opts) {
|
|
121
|
+
while (str.endsWith(opts.terminator)) {
|
|
122
|
+
str = str.slice(0, -opts.terminator.length);
|
|
123
|
+
}
|
|
124
|
+
const datePattern = new RegExp(`^${escapeRegex(opts.typeString)}${escapeRegex(opts.datePrefix)}-?\\d+$`);
|
|
125
|
+
if (standalone && datePattern.test(str)) {
|
|
126
|
+
return str.slice(opts.typeString.length);
|
|
127
|
+
}
|
|
128
|
+
if (!standalone && str.startsWith(opts.typeObject)) {
|
|
129
|
+
return str.slice(opts.typeObject.length);
|
|
130
|
+
}
|
|
131
|
+
return str;
|
|
132
|
+
}
|
|
133
|
+
function createSerializer(opts) {
|
|
134
|
+
const keyEscape = buildKeyEscapePattern(opts);
|
|
135
|
+
const valueEscape = buildValueEscapePattern(opts);
|
|
136
|
+
const dateStartPattern = buildDateStartPattern(opts);
|
|
137
|
+
function serialize(value, standalone, inArray = false) {
|
|
138
|
+
if (value === null) return `${opts.typePrimitive}null`;
|
|
139
|
+
if (value === void 0) return `${opts.typePrimitive}undefined`;
|
|
140
|
+
if (typeof value === "function") return "";
|
|
141
|
+
if (typeof value === "number") {
|
|
142
|
+
return `${opts.typePrimitive}${value}`;
|
|
143
|
+
}
|
|
144
|
+
if (typeof value === "boolean") {
|
|
145
|
+
return `${opts.typePrimitive}${value}`;
|
|
146
|
+
}
|
|
147
|
+
if (value instanceof Date) {
|
|
148
|
+
return `${opts.typeString}${opts.datePrefix}${value.getTime()}`;
|
|
149
|
+
}
|
|
150
|
+
if (Array.isArray(value)) {
|
|
151
|
+
const items = value.map((v) => serialize(v, standalone, true));
|
|
152
|
+
return `${opts.typeArray}${items.join(opts.separator)}${opts.terminator}`;
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === "object") {
|
|
155
|
+
const entries = [];
|
|
156
|
+
for (const [k, v] of Object.entries(value)) {
|
|
157
|
+
const val = serialize(v, false, false);
|
|
158
|
+
if (val || v === void 0) {
|
|
159
|
+
entries.push(`${escapeStr(k, keyEscape, opts.escape, opts)}${val}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return `${opts.typeObject}${entries.join(opts.separator)}${opts.terminator}`;
|
|
163
|
+
}
|
|
164
|
+
const strVal = String(value);
|
|
165
|
+
let escaped = escapeStr(strVal, valueEscape, opts.escape, opts);
|
|
166
|
+
if (dateStartPattern.test(strVal)) {
|
|
167
|
+
escaped = opts.escape + escaped;
|
|
168
|
+
} else if ((standalone || inArray) && (strVal.startsWith(opts.typeObject) || strVal.startsWith(opts.typeArray) || strVal.startsWith(opts.typePrimitive) || strVal.startsWith(opts.typeString))) {
|
|
169
|
+
escaped = opts.escape + escaped;
|
|
170
|
+
}
|
|
171
|
+
return standalone || inArray ? escaped : `${opts.typeString}${escaped}`;
|
|
172
|
+
}
|
|
173
|
+
return serialize;
|
|
174
|
+
}
|
|
175
|
+
function createParser(opts) {
|
|
176
|
+
const keyStop = buildKeyStopPattern(opts);
|
|
177
|
+
const valueStop = buildValueStopPattern(opts);
|
|
178
|
+
const datePattern = buildDatePattern(opts);
|
|
179
|
+
const tokens = {
|
|
180
|
+
typePrimitive: opts.typePrimitive,
|
|
181
|
+
typeArray: opts.typeArray,
|
|
182
|
+
typeObject: opts.typeObject,
|
|
183
|
+
typeString: opts.typeString,
|
|
184
|
+
separator: opts.separator,
|
|
185
|
+
terminator: opts.terminator,
|
|
186
|
+
escape: opts.escape,
|
|
187
|
+
datePrefix: opts.datePrefix
|
|
188
|
+
};
|
|
189
|
+
return function parseSource(source) {
|
|
190
|
+
let pos = 0;
|
|
191
|
+
function peek(len = 1) {
|
|
192
|
+
return source.slice(pos, pos + len);
|
|
193
|
+
}
|
|
194
|
+
function startsWith(token) {
|
|
195
|
+
return source.slice(pos, pos + token.length) === token;
|
|
196
|
+
}
|
|
197
|
+
function advance(len = 1) {
|
|
198
|
+
pos += len;
|
|
199
|
+
}
|
|
200
|
+
function readUntil(stopPattern, checkEscape = false) {
|
|
201
|
+
let result = "";
|
|
202
|
+
let wasEscaped = false;
|
|
203
|
+
while (pos < source.length) {
|
|
204
|
+
if (startsWith(tokens.escape)) {
|
|
205
|
+
const nextPos = pos + tokens.escape.length;
|
|
206
|
+
const nextChar = source.slice(nextPos, nextPos + 1);
|
|
207
|
+
const isEscapeSequence = stopPattern.test(nextChar);
|
|
208
|
+
const isDateEscape = checkEscape && source.slice(nextPos, nextPos + tokens.datePrefix.length) === tokens.datePrefix;
|
|
209
|
+
if (isEscapeSequence || isDateEscape) {
|
|
210
|
+
if (isDateEscape) {
|
|
211
|
+
wasEscaped = true;
|
|
212
|
+
}
|
|
213
|
+
advance(tokens.escape.length);
|
|
214
|
+
if (pos < source.length) {
|
|
215
|
+
result += peek();
|
|
216
|
+
advance();
|
|
217
|
+
}
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const ch = peek();
|
|
222
|
+
if (stopPattern.test(ch)) break;
|
|
223
|
+
result += ch;
|
|
224
|
+
advance();
|
|
225
|
+
}
|
|
226
|
+
return { value: result, wasEscaped };
|
|
227
|
+
}
|
|
228
|
+
function parseString() {
|
|
229
|
+
const { value, wasEscaped } = readUntil(valueStop, true);
|
|
230
|
+
if (!wasEscaped && datePattern.test(value)) {
|
|
231
|
+
const timestamp = parseInt(value.slice(tokens.datePrefix.length), 10);
|
|
232
|
+
if (!isNaN(timestamp)) {
|
|
233
|
+
return new Date(timestamp);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return value;
|
|
237
|
+
}
|
|
238
|
+
function parsePrimitive() {
|
|
239
|
+
const { value } = readUntil(valueStop, false);
|
|
240
|
+
if (value === "null") return null;
|
|
241
|
+
if (value === "undefined") return void 0;
|
|
242
|
+
if (value === "true") return true;
|
|
243
|
+
if (value === "false") return false;
|
|
244
|
+
return parseFloat(value);
|
|
245
|
+
}
|
|
246
|
+
function parseArray() {
|
|
247
|
+
const result = [];
|
|
248
|
+
let lastWasSeparator = false;
|
|
249
|
+
while (pos < source.length && !startsWith(tokens.terminator)) {
|
|
250
|
+
if (startsWith(tokens.separator)) {
|
|
251
|
+
result.push("");
|
|
252
|
+
advance(tokens.separator.length);
|
|
253
|
+
lastWasSeparator = true;
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
lastWasSeparator = false;
|
|
257
|
+
if (startsWith(tokens.typePrimitive) || startsWith(tokens.typeArray) || startsWith(tokens.typeObject) || startsWith(tokens.typeString)) {
|
|
258
|
+
result.push(parseValue());
|
|
259
|
+
} else {
|
|
260
|
+
result.push(parseString());
|
|
261
|
+
}
|
|
262
|
+
if (pos < source.length && startsWith(tokens.separator)) {
|
|
263
|
+
advance(tokens.separator.length);
|
|
264
|
+
lastWasSeparator = true;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (lastWasSeparator && (startsWith(tokens.terminator) || pos >= source.length)) {
|
|
268
|
+
result.push("");
|
|
269
|
+
}
|
|
270
|
+
if (startsWith(tokens.terminator)) advance(tokens.terminator.length);
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
function parseObject() {
|
|
274
|
+
const result = {};
|
|
275
|
+
while (pos < source.length && !startsWith(tokens.terminator)) {
|
|
276
|
+
const { value: key } = readUntil(keyStop, false);
|
|
277
|
+
result[key] = parseValue();
|
|
278
|
+
if (pos < source.length && !startsWith(tokens.terminator) && startsWith(tokens.separator)) {
|
|
279
|
+
advance(tokens.separator.length);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (startsWith(tokens.terminator)) advance(tokens.terminator.length);
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
function parseValue() {
|
|
286
|
+
if (startsWith(tokens.typePrimitive)) {
|
|
287
|
+
advance(tokens.typePrimitive.length);
|
|
288
|
+
return parsePrimitive();
|
|
289
|
+
}
|
|
290
|
+
if (startsWith(tokens.typeArray)) {
|
|
291
|
+
advance(tokens.typeArray.length);
|
|
292
|
+
return parseArray();
|
|
293
|
+
}
|
|
294
|
+
if (startsWith(tokens.typeObject)) {
|
|
295
|
+
advance(tokens.typeObject.length);
|
|
296
|
+
return parseObject();
|
|
297
|
+
}
|
|
298
|
+
if (startsWith(tokens.typeString)) {
|
|
299
|
+
advance(tokens.typeString.length);
|
|
300
|
+
return parseString();
|
|
301
|
+
}
|
|
302
|
+
throw new Error(`Unexpected type "${peek()}" at position ${pos}`);
|
|
303
|
+
}
|
|
304
|
+
return parseValue();
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function stringify(value, standalone = false, options = {}) {
|
|
308
|
+
const opts = resolveOptions(options);
|
|
309
|
+
const serialize = createSerializer(opts);
|
|
310
|
+
return cleanResult(serialize(value, standalone), standalone, opts);
|
|
311
|
+
}
|
|
312
|
+
function parse(input, standalone = false, options = {}) {
|
|
313
|
+
const opts = resolveOptions(options);
|
|
314
|
+
const datePattern = buildDatePattern(opts);
|
|
315
|
+
const str = decodeURIComponent(input);
|
|
316
|
+
if (str.length === 0) {
|
|
317
|
+
return standalone ? "" : {};
|
|
318
|
+
}
|
|
319
|
+
const hasMarker = str.startsWith(opts.typeString) || str.startsWith(opts.typePrimitive) || str.startsWith(opts.typeArray) || str.startsWith(opts.typeObject);
|
|
320
|
+
let source;
|
|
321
|
+
if (hasMarker) {
|
|
322
|
+
source = str;
|
|
323
|
+
} else if (standalone) {
|
|
324
|
+
if (datePattern.test(str)) {
|
|
325
|
+
const timestamp = parseInt(str.slice(opts.datePrefix.length), 10);
|
|
326
|
+
if (!isNaN(timestamp)) {
|
|
327
|
+
return new Date(timestamp);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
let result = "";
|
|
331
|
+
for (let i = 0; i < str.length; i++) {
|
|
332
|
+
if (str.slice(i, i + opts.escape.length) === opts.escape && i + opts.escape.length < str.length) {
|
|
333
|
+
i += opts.escape.length - 1;
|
|
334
|
+
result += str[i + 1];
|
|
335
|
+
i++;
|
|
336
|
+
} else {
|
|
337
|
+
result += str[i];
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return result;
|
|
341
|
+
} else {
|
|
342
|
+
const escapedMarkers = [opts.typeString, opts.typePrimitive, opts.typeArray, opts.typeObject].map(escapeRegex).join("");
|
|
343
|
+
const escapedEscape = escapeRegex(opts.escape);
|
|
344
|
+
const escapedSeparator = escapeRegex(opts.separator);
|
|
345
|
+
const escapedTerminator = escapeRegex(opts.terminator);
|
|
346
|
+
const objectPattern = new RegExp(
|
|
347
|
+
`[^${escapedEscape}${escapedMarkers}${escapedSeparator}${escapedTerminator}][${escapedMarkers}]`
|
|
348
|
+
);
|
|
349
|
+
source = objectPattern.test(str) ? `${opts.typeObject}${str}` : `${opts.typeString}${str}`;
|
|
350
|
+
}
|
|
351
|
+
const parseSource = createParser(opts);
|
|
352
|
+
return parseSource(source);
|
|
353
|
+
}
|
|
354
|
+
function createFormat(options = {}) {
|
|
355
|
+
const opts = resolveOptions(options);
|
|
356
|
+
validateOptions(opts);
|
|
357
|
+
return {
|
|
358
|
+
stringify(state) {
|
|
359
|
+
return stringify(state, false, options);
|
|
360
|
+
},
|
|
361
|
+
parse(value, _ctx) {
|
|
362
|
+
return parse(value, false, options);
|
|
363
|
+
},
|
|
364
|
+
stringifyStandalone(state) {
|
|
365
|
+
const result = {};
|
|
366
|
+
for (const [key, value] of Object.entries(state)) {
|
|
367
|
+
result[encodeURIComponent(key)] = [stringify(value, true, options)];
|
|
368
|
+
}
|
|
369
|
+
return result;
|
|
370
|
+
},
|
|
371
|
+
parseStandalone(params, _ctx) {
|
|
372
|
+
const result = {};
|
|
373
|
+
for (const [key, values] of Object.entries(params)) {
|
|
374
|
+
if (values.length > 0) {
|
|
375
|
+
result[decodeURIComponent(key)] = parse(values[0], true, options);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
var marked = createFormat();
|
|
383
|
+
var marked_default = marked;
|
|
384
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
385
|
+
0 && (module.exports = {
|
|
386
|
+
createFormat,
|
|
387
|
+
marked,
|
|
388
|
+
parse,
|
|
389
|
+
stringify
|
|
390
|
+
});
|
|
391
|
+
/* v8 ignore next 4 -- @preserve: defensive - handles escape char at very end of source */
|
|
392
|
+
/* v8 ignore next 3 -- @preserve: defensive - parseInt on digit string won't produce NaN */
|
|
393
|
+
/* v8 ignore next 2 -- @preserve: defensive code - all valid types are handled above */
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { QueryStringFormat } from '../index.mjs';
|
|
2
|
+
import 'zustand/vanilla';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Plain URL Query String Format
|
|
6
|
+
*
|
|
7
|
+
* A simple format for URL state serialization with optional configuration.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Dot notation for nested objects: user.name=John
|
|
11
|
+
* - Repeated keys for arrays: tags=a&tags=b&tags=c
|
|
12
|
+
* - Proper escaping of special characters in both keys and values
|
|
13
|
+
* - Auto-parsing of numbers, booleans, and ISO dates
|
|
14
|
+
* - Type coercion from initialState when available
|
|
15
|
+
*
|
|
16
|
+
* Two modes:
|
|
17
|
+
* - Namespaced: entire state in one param (key: 'state')
|
|
18
|
+
* - Standalone: each field as separate param (key: false)
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface PlainFormatOptions {
|
|
22
|
+
/** Separator between key=value entries in namespaced mode @default ',' */
|
|
23
|
+
entrySeparator?: string;
|
|
24
|
+
/** Separator for nested keys (e.g., user.name) @default '.' */
|
|
25
|
+
nestingSeparator?: string;
|
|
26
|
+
/** Array separator: 'repeat' for repeated keys, or string to join values @default 'repeat' */
|
|
27
|
+
arraySeparator?: 'repeat' | string;
|
|
28
|
+
/** Character used to escape special characters @default '_' */
|
|
29
|
+
escapeChar?: string;
|
|
30
|
+
/** String representation of null @default 'null' */
|
|
31
|
+
nullString?: string;
|
|
32
|
+
/** String representation of undefined @default 'undefined' */
|
|
33
|
+
undefinedString?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a plain format with custom configuration.
|
|
37
|
+
*/
|
|
38
|
+
declare function createFormat(options?: PlainFormatOptions): QueryStringFormat;
|
|
39
|
+
/**
|
|
40
|
+
* Default plain format with standard configuration.
|
|
41
|
+
*
|
|
42
|
+
* - Entry separator: `,`
|
|
43
|
+
* - Nesting separator: `.`
|
|
44
|
+
* - Array separator: `,` (comma-separated values)
|
|
45
|
+
* - Escape character: `_`
|
|
46
|
+
*/
|
|
47
|
+
declare const plain: QueryStringFormat;
|
|
48
|
+
|
|
49
|
+
export { type PlainFormatOptions, createFormat, plain };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { QueryStringFormat } from '../index.js';
|
|
2
|
+
import 'zustand/vanilla';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Plain URL Query String Format
|
|
6
|
+
*
|
|
7
|
+
* A simple format for URL state serialization with optional configuration.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Dot notation for nested objects: user.name=John
|
|
11
|
+
* - Repeated keys for arrays: tags=a&tags=b&tags=c
|
|
12
|
+
* - Proper escaping of special characters in both keys and values
|
|
13
|
+
* - Auto-parsing of numbers, booleans, and ISO dates
|
|
14
|
+
* - Type coercion from initialState when available
|
|
15
|
+
*
|
|
16
|
+
* Two modes:
|
|
17
|
+
* - Namespaced: entire state in one param (key: 'state')
|
|
18
|
+
* - Standalone: each field as separate param (key: false)
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface PlainFormatOptions {
|
|
22
|
+
/** Separator between key=value entries in namespaced mode @default ',' */
|
|
23
|
+
entrySeparator?: string;
|
|
24
|
+
/** Separator for nested keys (e.g., user.name) @default '.' */
|
|
25
|
+
nestingSeparator?: string;
|
|
26
|
+
/** Array separator: 'repeat' for repeated keys, or string to join values @default 'repeat' */
|
|
27
|
+
arraySeparator?: 'repeat' | string;
|
|
28
|
+
/** Character used to escape special characters @default '_' */
|
|
29
|
+
escapeChar?: string;
|
|
30
|
+
/** String representation of null @default 'null' */
|
|
31
|
+
nullString?: string;
|
|
32
|
+
/** String representation of undefined @default 'undefined' */
|
|
33
|
+
undefinedString?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a plain format with custom configuration.
|
|
37
|
+
*/
|
|
38
|
+
declare function createFormat(options?: PlainFormatOptions): QueryStringFormat;
|
|
39
|
+
/**
|
|
40
|
+
* Default plain format with standard configuration.
|
|
41
|
+
*
|
|
42
|
+
* - Entry separator: `,`
|
|
43
|
+
* - Nesting separator: `.`
|
|
44
|
+
* - Array separator: `,` (comma-separated values)
|
|
45
|
+
* - Escape character: `_`
|
|
46
|
+
*/
|
|
47
|
+
declare const plain: QueryStringFormat;
|
|
48
|
+
|
|
49
|
+
export { type PlainFormatOptions, createFormat, plain };
|