@resistdesign/voltra 3.0.0-alpha.27 → 3.0.0-alpha.28
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/api/index.js +6 -383
- package/app/index.js +10 -1268
- package/app/utils/Route.d.ts +18 -0
- package/app/utils/UniversalRouteAdapter.d.ts +0 -11
- package/build/index.js +2 -12
- package/common/index.js +7 -384
- package/iac/index.js +2 -258
- package/iac/packs/index.js +2 -254
- package/native/index.d.ts +4 -0
- package/native/index.js +62 -705
- package/native/testing/react-native.d.ts +28 -0
- package/native/utils/Route.d.ts +34 -1
- package/package.json +1 -1
- package/web/index.js +6 -539
package/app/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import '../chunk-MUCSL3UR.js';
|
|
2
|
+
export { createEasyLayout, getEasyLayoutTemplateDetails, getPascalCaseAreaName } from '../chunk-FQMZMCXU.js';
|
|
3
|
+
export { Route, RouteContext, RouteContextConsumer, RouteContextProvider, RouteProvider, buildHistoryPath, buildQueryString, buildRoutePath, canUseBrowserHistory, computeTrackPixels, createBrowserRouteAdapter, createHistoryBackHandler, createManualRouteAdapter, createMemoryHistory, createNativeRouteAdapter, createRouteAdapterFromHistory, createUniversalAdapter, parseHistoryPath, useRouteContext } from '../chunk-G5CLUK4Y.js';
|
|
4
|
+
export { AutoForm, AutoFormView, computeAreaBounds, createAutoField, createFormRenderer, getFieldKind, parseTemplate, resolveSuite, useFormEngine, validateAreas } from '../chunk-WELZGQDJ.js';
|
|
5
|
+
import '../chunk-HVY7POTD.js';
|
|
6
|
+
import '../chunk-IWRHGGGH.js';
|
|
7
|
+
import { mergeStringPaths, PATH_DELIMITER } from '../chunk-GYWRAW3Y.js';
|
|
8
|
+
import '../chunk-I2KLQ2HA.js';
|
|
1
9
|
import { createContext, useContext, useRef, useMemo, useCallback, useState, useEffect } from 'react';
|
|
2
|
-
import { jsx
|
|
10
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
11
|
|
|
4
|
-
// src/app/utils/ApplicationState.tsx
|
|
5
12
|
var getApplicationStateIdentifier = (subStateIdMap) => subStateIdMap ? subStateIdMap : {};
|
|
6
13
|
var getApplicationStateModified = (identifier, modificationState) => !!modificationState.get(identifier);
|
|
7
14
|
var getApplicationStateValue = (identifier, applicationState) => applicationState.get(identifier);
|
|
@@ -122,83 +129,6 @@ var ApplicationStateProvider = ({
|
|
|
122
129
|
return /* @__PURE__ */ jsx(Provider, { value: controller, children });
|
|
123
130
|
};
|
|
124
131
|
|
|
125
|
-
// src/common/Routing.ts
|
|
126
|
-
var PATH_DELIMITER = "/";
|
|
127
|
-
var getPotentialJSONValue = (value) => {
|
|
128
|
-
try {
|
|
129
|
-
return JSON.parse(value);
|
|
130
|
-
} catch (error) {
|
|
131
|
-
return value;
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
var getPathArray = (path, delimiter = PATH_DELIMITER, filterEmptyOutput = false, filterEmptyInput = true, useJson = true, uriDecodeParts = true) => path.split(delimiter).filter(filterEmptyInput ? (p) => p !== "" : () => true).map(uriDecodeParts ? decodeURIComponent : (x) => x).map(useJson ? getPotentialJSONValue : (p) => p).filter(filterEmptyOutput ? (p) => p ?? false : () => true);
|
|
135
|
-
var getPathString = (parts = [], delimiter = PATH_DELIMITER, filterEmptyInput = false, useJson = true, uriEncodeParts = false) => parts.filter(filterEmptyInput ? (p) => p ?? false : () => true).map(useJson ? (p) => JSON.stringify(p) : (x) => x).map(uriEncodeParts ? encodeURIComponent : (x) => x).join(delimiter);
|
|
136
|
-
var mergeStringPaths = (path1, path2, delimiter = PATH_DELIMITER, filterEmptyOutput = false, filterEmptyInput = true, useJson = true, uriEncodeParts = false) => getPathString(
|
|
137
|
-
[
|
|
138
|
-
...getPathArray(
|
|
139
|
-
path1,
|
|
140
|
-
delimiter,
|
|
141
|
-
filterEmptyOutput,
|
|
142
|
-
filterEmptyInput,
|
|
143
|
-
useJson,
|
|
144
|
-
uriEncodeParts
|
|
145
|
-
),
|
|
146
|
-
...getPathArray(
|
|
147
|
-
path2,
|
|
148
|
-
delimiter,
|
|
149
|
-
filterEmptyOutput,
|
|
150
|
-
filterEmptyInput,
|
|
151
|
-
useJson,
|
|
152
|
-
uriEncodeParts
|
|
153
|
-
)
|
|
154
|
-
],
|
|
155
|
-
delimiter,
|
|
156
|
-
filterEmptyInput,
|
|
157
|
-
useJson,
|
|
158
|
-
uriEncodeParts
|
|
159
|
-
);
|
|
160
|
-
var resolvePath = (currentPath, newPath) => {
|
|
161
|
-
const newSegments = getPathArray(newPath, PATH_DELIMITER, true);
|
|
162
|
-
let currentSegments = getPathArray(currentPath, PATH_DELIMITER, true);
|
|
163
|
-
if (newPath.startsWith("/")) {
|
|
164
|
-
currentSegments = [];
|
|
165
|
-
}
|
|
166
|
-
newSegments.forEach((segment) => {
|
|
167
|
-
if (segment === "..") {
|
|
168
|
-
if (currentSegments.length > 0) {
|
|
169
|
-
currentSegments.pop();
|
|
170
|
-
}
|
|
171
|
-
} else if (segment !== ".") {
|
|
172
|
-
currentSegments.push(segment);
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
return "/" + currentSegments.join("/");
|
|
176
|
-
};
|
|
177
|
-
var getParamsAndTestPath = (path, testPath, exact = false) => {
|
|
178
|
-
const pathList = getPathArray(path);
|
|
179
|
-
const testPathList = getPathArray(testPath);
|
|
180
|
-
if (exact && pathList.length !== testPathList.length) {
|
|
181
|
-
return false;
|
|
182
|
-
} else {
|
|
183
|
-
let params = {};
|
|
184
|
-
if (pathList.length >= testPathList.length) {
|
|
185
|
-
for (let i = 0; i < testPathList.length; i++) {
|
|
186
|
-
const testPathPart = testPathList[i];
|
|
187
|
-
const pathPart = pathList[i];
|
|
188
|
-
if (testPathPart.startsWith(":")) {
|
|
189
|
-
const paramName = testPathPart.slice(1);
|
|
190
|
-
params[paramName] = pathPart;
|
|
191
|
-
} else if (pathPart !== testPathPart) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
return params;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
132
|
// src/app/utils/Service.ts
|
|
203
133
|
var getFullUrl = (protocol, domain, basePath = "", path = "", port) => {
|
|
204
134
|
const portString = !!port ? `:${port}` : "";
|
|
@@ -354,884 +284,6 @@ var useDebugDependencies = (dependencies) => {
|
|
|
354
284
|
}, dependencies);
|
|
355
285
|
};
|
|
356
286
|
|
|
357
|
-
// src/app/utils/easy-layout/parseTemplate.ts
|
|
358
|
-
var parseTrackSpec = (token) => {
|
|
359
|
-
const trimmed = token.trim();
|
|
360
|
-
const numericMatch = trimmed.match(/^([0-9]*\.?[0-9]+)(fr|px|%)$/);
|
|
361
|
-
if (!numericMatch) {
|
|
362
|
-
throw new Error(
|
|
363
|
-
`Invalid track token "${trimmed}". Supported units are fr, px, and %.`
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
|
-
const value = Number(numericMatch[1]);
|
|
367
|
-
const suffix = numericMatch[2];
|
|
368
|
-
if (!Number.isFinite(value) || value < 0) {
|
|
369
|
-
throw new Error(`Track value must be a non-negative number. Received "${trimmed}".`);
|
|
370
|
-
}
|
|
371
|
-
if (suffix === "fr") {
|
|
372
|
-
return { kind: "fr", value };
|
|
373
|
-
}
|
|
374
|
-
if (suffix === "px") {
|
|
375
|
-
return { kind: "px", value };
|
|
376
|
-
}
|
|
377
|
-
return { kind: "pct", value };
|
|
378
|
-
};
|
|
379
|
-
var normalizeAreas = (areaPart) => {
|
|
380
|
-
return areaPart.trim().split(/\s+/g).map((token) => token.trim()).filter(Boolean);
|
|
381
|
-
};
|
|
382
|
-
var parseTemplate = (template = "") => {
|
|
383
|
-
const lines = template.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
384
|
-
const areaGrid = [];
|
|
385
|
-
const rowTracks = [];
|
|
386
|
-
let colTracks = null;
|
|
387
|
-
for (const line of lines) {
|
|
388
|
-
if (line.startsWith("\\")) {
|
|
389
|
-
if (colTracks) {
|
|
390
|
-
throw new Error("Template can include only one column-track line.");
|
|
391
|
-
}
|
|
392
|
-
const colTokens = line.replace(/\\/g, " ").trim().split(/\s+/g).filter(Boolean);
|
|
393
|
-
colTracks = colTokens.map(parseTrackSpec);
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
const parts = line.split(",").map((part) => part.trim());
|
|
397
|
-
const areaPart = parts[0] || "";
|
|
398
|
-
if (!areaPart) {
|
|
399
|
-
continue;
|
|
400
|
-
}
|
|
401
|
-
if (parts.length > 2) {
|
|
402
|
-
throw new Error(
|
|
403
|
-
`Invalid row definition "${line}". Expected "<areas>, <row-track>".`
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
const areas = normalizeAreas(areaPart);
|
|
407
|
-
if (!areas.length) {
|
|
408
|
-
continue;
|
|
409
|
-
}
|
|
410
|
-
areaGrid.push(areas);
|
|
411
|
-
const rowTrack = parts[1];
|
|
412
|
-
if (rowTrack) {
|
|
413
|
-
rowTracks.push(parseTrackSpec(rowTrack));
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
if (!areaGrid.length) {
|
|
417
|
-
throw new Error("Template must include at least one area row.");
|
|
418
|
-
}
|
|
419
|
-
const expectedWidth = areaGrid[0].length;
|
|
420
|
-
for (let rowIndex = 0; rowIndex < areaGrid.length; rowIndex++) {
|
|
421
|
-
const width = areaGrid[rowIndex].length;
|
|
422
|
-
if (width !== expectedWidth) {
|
|
423
|
-
throw new Error(
|
|
424
|
-
`All area rows must have the same width. Expected ${expectedWidth}, received ${width} at row ${rowIndex + 1}.`
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
if (colTracks && colTracks.length !== expectedWidth) {
|
|
429
|
-
throw new Error(
|
|
430
|
-
`Column track count must match area width. Expected ${expectedWidth}, received ${colTracks.length}.`
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
const areaNames = Array.from(
|
|
434
|
-
new Set(
|
|
435
|
-
areaGrid.flat().map((name) => name.trim()).filter((name) => !!name && name !== ".")
|
|
436
|
-
)
|
|
437
|
-
);
|
|
438
|
-
return {
|
|
439
|
-
areaGrid,
|
|
440
|
-
rowTracks,
|
|
441
|
-
colTracks: colTracks || [],
|
|
442
|
-
areaNames
|
|
443
|
-
};
|
|
444
|
-
};
|
|
445
|
-
|
|
446
|
-
// src/app/utils/easy-layout/computeAreaBounds.ts
|
|
447
|
-
var computeAreaBounds = (parsed) => {
|
|
448
|
-
const result = {};
|
|
449
|
-
for (let rowIndex = 0; rowIndex < parsed.areaGrid.length; rowIndex++) {
|
|
450
|
-
const row = parsed.areaGrid[rowIndex];
|
|
451
|
-
for (let colIndex = 0; colIndex < row.length; colIndex++) {
|
|
452
|
-
const name = row[colIndex];
|
|
453
|
-
if (!name || name === ".") {
|
|
454
|
-
continue;
|
|
455
|
-
}
|
|
456
|
-
const row1 = rowIndex + 1;
|
|
457
|
-
const col1 = colIndex + 1;
|
|
458
|
-
const existing = result[name];
|
|
459
|
-
if (!existing) {
|
|
460
|
-
result[name] = {
|
|
461
|
-
name,
|
|
462
|
-
rowStart: row1,
|
|
463
|
-
rowEnd: row1,
|
|
464
|
-
colStart: col1,
|
|
465
|
-
colEnd: col1
|
|
466
|
-
};
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
existing.rowStart = Math.min(existing.rowStart, row1);
|
|
470
|
-
existing.rowEnd = Math.max(existing.rowEnd, row1);
|
|
471
|
-
existing.colStart = Math.min(existing.colStart, col1);
|
|
472
|
-
existing.colEnd = Math.max(existing.colEnd, col1);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
return result;
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
// src/app/utils/easy-layout/validateAreas.ts
|
|
479
|
-
var validateAreas = (parsed) => {
|
|
480
|
-
const bounds = computeAreaBounds(parsed);
|
|
481
|
-
for (const areaName of parsed.areaNames) {
|
|
482
|
-
const bound = bounds[areaName];
|
|
483
|
-
if (!bound) {
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
for (let row = bound.rowStart; row <= bound.rowEnd; row++) {
|
|
487
|
-
for (let col = bound.colStart; col <= bound.colEnd; col++) {
|
|
488
|
-
const token = parsed.areaGrid[row - 1]?.[col - 1];
|
|
489
|
-
if (token !== areaName) {
|
|
490
|
-
throw new Error(
|
|
491
|
-
`Area "${areaName}" must be a rectangle. Missing "${areaName}" at row ${row}, col ${col}.`
|
|
492
|
-
);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
// src/app/utils/EasyLayout.tsx
|
|
500
|
-
var getPascalCaseAreaName = (area) => {
|
|
501
|
-
return area.split("-").map((a) => a[0].toUpperCase() + a.slice(1)).join("");
|
|
502
|
-
};
|
|
503
|
-
var convertLayoutToCSS = (layout = "", spacing = {}) => {
|
|
504
|
-
const parsed = parseTemplate(layout);
|
|
505
|
-
validateAreas(parsed);
|
|
506
|
-
const renderTrack = (track) => {
|
|
507
|
-
if (track.kind === "px") {
|
|
508
|
-
return `${track.value}px`;
|
|
509
|
-
}
|
|
510
|
-
if (track.kind === "pct") {
|
|
511
|
-
return `${track.value}%`;
|
|
512
|
-
}
|
|
513
|
-
return `${track.value}fr`;
|
|
514
|
-
};
|
|
515
|
-
const areaRows = parsed.areaGrid.map((row) => row.join(" "));
|
|
516
|
-
const rows = parsed.rowTracks.map(renderTrack);
|
|
517
|
-
let css = "";
|
|
518
|
-
if (parsed.colTracks.length) {
|
|
519
|
-
css += `
|
|
520
|
-
grid-template-columns: ${parsed.colTracks.map(renderTrack).join(" ")};`;
|
|
521
|
-
}
|
|
522
|
-
css += `
|
|
523
|
-
grid-template-areas:
|
|
524
|
-
${areaRows.map((a) => ` "${a}"`).join("\n")};`;
|
|
525
|
-
if (rows.length) {
|
|
526
|
-
css += `
|
|
527
|
-
grid-template-rows: ${rows.join(" ")};`;
|
|
528
|
-
}
|
|
529
|
-
if (typeof spacing.gap !== "undefined") {
|
|
530
|
-
css += `
|
|
531
|
-
gap: ${typeof spacing.gap === "number" ? `${spacing.gap}px` : spacing.gap};`;
|
|
532
|
-
}
|
|
533
|
-
if (typeof spacing.padding !== "undefined") {
|
|
534
|
-
css += `
|
|
535
|
-
padding: ${typeof spacing.padding === "number" ? `${spacing.padding}px` : spacing.padding};`;
|
|
536
|
-
}
|
|
537
|
-
return {
|
|
538
|
-
areasList: parsed.areaNames,
|
|
539
|
-
css
|
|
540
|
-
};
|
|
541
|
-
};
|
|
542
|
-
var getEasyLayoutTemplateDetails = (layout = "", spacing = {}) => convertLayoutToCSS(layout, spacing);
|
|
543
|
-
var createEasyLayout = (config, extendFrom, areasExtendFrom, spacing = {}) => {
|
|
544
|
-
return (layoutTemplate, ...expressions) => {
|
|
545
|
-
const mergedTemplate = layoutTemplate.reduce((acc, l, ind) => {
|
|
546
|
-
const expr = expressions[ind - 1];
|
|
547
|
-
const exprStr = typeof expr === "undefined" ? "" : expr;
|
|
548
|
-
return `${acc}${l}${exprStr}`;
|
|
549
|
-
}, "");
|
|
550
|
-
const { areasList, css } = convertLayoutToCSS(mergedTemplate, spacing);
|
|
551
|
-
const layout = config.createLayout({ base: extendFrom, css });
|
|
552
|
-
const areas = areasList.reduce((acc, area) => {
|
|
553
|
-
const pascalCaseAreaName = getPascalCaseAreaName(area);
|
|
554
|
-
const component = config.createArea({ base: areasExtendFrom, area });
|
|
555
|
-
return {
|
|
556
|
-
...acc,
|
|
557
|
-
[pascalCaseAreaName]: component
|
|
558
|
-
};
|
|
559
|
-
}, {});
|
|
560
|
-
return {
|
|
561
|
-
layout,
|
|
562
|
-
areas
|
|
563
|
-
};
|
|
564
|
-
};
|
|
565
|
-
};
|
|
566
|
-
|
|
567
|
-
// src/app/utils/easy-layout/computeTracks.ts
|
|
568
|
-
var computeTrackPixels = ({
|
|
569
|
-
tracks,
|
|
570
|
-
totalPx,
|
|
571
|
-
gapPx = 0,
|
|
572
|
-
paddingPx = 0
|
|
573
|
-
}) => {
|
|
574
|
-
if (!tracks.length) {
|
|
575
|
-
return [];
|
|
576
|
-
}
|
|
577
|
-
const gapsPx = Math.max(0, tracks.length - 1) * Math.max(0, gapPx);
|
|
578
|
-
const usablePx = Math.max(0, totalPx - Math.max(0, paddingPx) * 2 - gapsPx);
|
|
579
|
-
let fixedPx = 0;
|
|
580
|
-
let frTotal = 0;
|
|
581
|
-
for (const track of tracks) {
|
|
582
|
-
if (track.kind === "px") {
|
|
583
|
-
fixedPx += track.value;
|
|
584
|
-
} else if (track.kind === "pct") {
|
|
585
|
-
fixedPx += usablePx * track.value / 100;
|
|
586
|
-
} else {
|
|
587
|
-
frTotal += track.value;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
const remainderPx = Math.max(0, usablePx - fixedPx);
|
|
591
|
-
return tracks.map((track) => {
|
|
592
|
-
if (track.kind === "px") {
|
|
593
|
-
return track.value;
|
|
594
|
-
}
|
|
595
|
-
if (track.kind === "pct") {
|
|
596
|
-
return usablePx * track.value / 100;
|
|
597
|
-
}
|
|
598
|
-
if (frTotal <= 0) {
|
|
599
|
-
return 0;
|
|
600
|
-
}
|
|
601
|
-
return remainderPx * track.value / frTotal;
|
|
602
|
-
});
|
|
603
|
-
};
|
|
604
|
-
|
|
605
|
-
// src/app/utils/History.ts
|
|
606
|
-
var createHistoryBackHandler = (history) => {
|
|
607
|
-
return {
|
|
608
|
-
/**
|
|
609
|
-
* @returns True when back navigation was handled by history.
|
|
610
|
-
*/
|
|
611
|
-
handle: () => {
|
|
612
|
-
if (history.index > 0) {
|
|
613
|
-
history.back();
|
|
614
|
-
return true;
|
|
615
|
-
}
|
|
616
|
-
return false;
|
|
617
|
-
}
|
|
618
|
-
};
|
|
619
|
-
};
|
|
620
|
-
var ensurePrefix = (value, prefix) => value ? value.startsWith(prefix) ? value : `${prefix}${value}` : "";
|
|
621
|
-
var parseHistoryPath = (inputPath) => {
|
|
622
|
-
const raw = String(inputPath ?? "").trim();
|
|
623
|
-
if (!raw) {
|
|
624
|
-
return { path: "/" };
|
|
625
|
-
}
|
|
626
|
-
try {
|
|
627
|
-
const absoluteUrl = new URL(raw);
|
|
628
|
-
return {
|
|
629
|
-
path: absoluteUrl.pathname || "/",
|
|
630
|
-
...absoluteUrl.search ? { search: absoluteUrl.search } : {},
|
|
631
|
-
...absoluteUrl.hash ? { hash: absoluteUrl.hash } : {}
|
|
632
|
-
};
|
|
633
|
-
} catch (error) {
|
|
634
|
-
let target = raw;
|
|
635
|
-
let hash = "";
|
|
636
|
-
let search = "";
|
|
637
|
-
const hashIndex = target.indexOf("#");
|
|
638
|
-
if (hashIndex >= 0) {
|
|
639
|
-
hash = target.slice(hashIndex);
|
|
640
|
-
target = target.slice(0, hashIndex);
|
|
641
|
-
}
|
|
642
|
-
const searchIndex = target.indexOf("?");
|
|
643
|
-
if (searchIndex >= 0) {
|
|
644
|
-
search = target.slice(searchIndex);
|
|
645
|
-
target = target.slice(0, searchIndex);
|
|
646
|
-
}
|
|
647
|
-
const path = target ? target.startsWith("/") ? target : `/${target}` : "/";
|
|
648
|
-
return {
|
|
649
|
-
path,
|
|
650
|
-
...search && search !== "?" ? { search } : {},
|
|
651
|
-
...hash && hash !== "#" ? { hash } : {}
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
var buildHistoryPath = ({
|
|
656
|
-
path,
|
|
657
|
-
search,
|
|
658
|
-
hash
|
|
659
|
-
}) => {
|
|
660
|
-
const normalizedPath = path ? path.startsWith("/") ? path : `/${path}` : "/";
|
|
661
|
-
const normalizedSearch = search ? ensurePrefix(search, "?") : "";
|
|
662
|
-
const normalizedHash = hash ? ensurePrefix(hash, "#") : "";
|
|
663
|
-
return `${normalizedPath}${normalizedSearch}${normalizedHash}`;
|
|
664
|
-
};
|
|
665
|
-
var getHistoryLocation = (inputPath, state, getNextKey, currentLocation, replaceSearch = false) => {
|
|
666
|
-
const parsed = parseHistoryPath(inputPath);
|
|
667
|
-
const nextSearch = typeof parsed.search === "undefined" ? replaceSearch ? void 0 : currentLocation?.search : parsed.search;
|
|
668
|
-
return {
|
|
669
|
-
path: parsed.path,
|
|
670
|
-
...typeof nextSearch !== "undefined" ? { search: nextSearch } : {},
|
|
671
|
-
...parsed.hash ? { hash: parsed.hash } : {},
|
|
672
|
-
...typeof state !== "undefined" ? { state } : {},
|
|
673
|
-
key: getNextKey()
|
|
674
|
-
};
|
|
675
|
-
};
|
|
676
|
-
var createMemoryHistory = (initialPath = "/") => {
|
|
677
|
-
let keyCounter = 0;
|
|
678
|
-
const getNextKey = () => `h${keyCounter++}`;
|
|
679
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
680
|
-
const entries = [
|
|
681
|
-
{
|
|
682
|
-
location: getHistoryLocation(
|
|
683
|
-
initialPath,
|
|
684
|
-
void 0,
|
|
685
|
-
getNextKey,
|
|
686
|
-
void 0,
|
|
687
|
-
true
|
|
688
|
-
)
|
|
689
|
-
}
|
|
690
|
-
];
|
|
691
|
-
let currentIndex = 0;
|
|
692
|
-
const getCurrentLocation = () => entries[currentIndex].location;
|
|
693
|
-
const notify = () => {
|
|
694
|
-
const location = getCurrentLocation();
|
|
695
|
-
listeners.forEach((listener) => listener(location));
|
|
696
|
-
};
|
|
697
|
-
const push = (path, opts) => {
|
|
698
|
-
const location = getHistoryLocation(
|
|
699
|
-
path,
|
|
700
|
-
opts?.state,
|
|
701
|
-
getNextKey,
|
|
702
|
-
getCurrentLocation(),
|
|
703
|
-
opts?.replaceSearch === true
|
|
704
|
-
);
|
|
705
|
-
if (currentIndex < entries.length - 1) {
|
|
706
|
-
entries.splice(currentIndex + 1);
|
|
707
|
-
}
|
|
708
|
-
entries.push({ location });
|
|
709
|
-
currentIndex = entries.length - 1;
|
|
710
|
-
notify();
|
|
711
|
-
};
|
|
712
|
-
const replace = (path, opts) => {
|
|
713
|
-
const location = getHistoryLocation(
|
|
714
|
-
path,
|
|
715
|
-
opts?.state,
|
|
716
|
-
getNextKey,
|
|
717
|
-
getCurrentLocation(),
|
|
718
|
-
opts?.replaceSearch === true
|
|
719
|
-
);
|
|
720
|
-
entries[currentIndex] = { location };
|
|
721
|
-
notify();
|
|
722
|
-
};
|
|
723
|
-
const go = (delta) => {
|
|
724
|
-
if (!Number.isFinite(delta)) {
|
|
725
|
-
return;
|
|
726
|
-
}
|
|
727
|
-
const targetIndex = Math.max(
|
|
728
|
-
0,
|
|
729
|
-
Math.min(entries.length - 1, currentIndex + Math.trunc(delta))
|
|
730
|
-
);
|
|
731
|
-
if (targetIndex === currentIndex) {
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
currentIndex = targetIndex;
|
|
735
|
-
notify();
|
|
736
|
-
};
|
|
737
|
-
return {
|
|
738
|
-
get location() {
|
|
739
|
-
return getCurrentLocation();
|
|
740
|
-
},
|
|
741
|
-
get length() {
|
|
742
|
-
return entries.length;
|
|
743
|
-
},
|
|
744
|
-
get index() {
|
|
745
|
-
return currentIndex;
|
|
746
|
-
},
|
|
747
|
-
push,
|
|
748
|
-
replace,
|
|
749
|
-
go,
|
|
750
|
-
back: () => go(-1),
|
|
751
|
-
forward: () => go(1),
|
|
752
|
-
listen: (listener) => {
|
|
753
|
-
listeners.add(listener);
|
|
754
|
-
return () => listeners.delete(listener);
|
|
755
|
-
}
|
|
756
|
-
};
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
// src/app/utils/RouteHistory.ts
|
|
760
|
-
var createRouteAdapterFromHistory = (history) => {
|
|
761
|
-
return {
|
|
762
|
-
getPath: () => history.location.path,
|
|
763
|
-
subscribe: (listener) => {
|
|
764
|
-
return history.listen((location) => {
|
|
765
|
-
listener(location.path);
|
|
766
|
-
});
|
|
767
|
-
},
|
|
768
|
-
push: (path) => {
|
|
769
|
-
history.push(path, { replaceSearch: true });
|
|
770
|
-
},
|
|
771
|
-
replace: (path) => {
|
|
772
|
-
history.replace(path, { replaceSearch: true });
|
|
773
|
-
},
|
|
774
|
-
back: history.back,
|
|
775
|
-
canGoBack: () => history.index > 0
|
|
776
|
-
};
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
// src/app/utils/UniversalRouteAdapter.ts
|
|
780
|
-
var getWindow = () => {
|
|
781
|
-
if (typeof globalThis === "undefined") {
|
|
782
|
-
return void 0;
|
|
783
|
-
}
|
|
784
|
-
if ("window" in globalThis) {
|
|
785
|
-
return globalThis.window;
|
|
786
|
-
}
|
|
787
|
-
return void 0;
|
|
788
|
-
};
|
|
789
|
-
var getRuntimeRequire = () => {
|
|
790
|
-
const runtimeRequire = globalThis.__voltra_require__;
|
|
791
|
-
if (typeof runtimeRequire === "function") {
|
|
792
|
-
return runtimeRequire;
|
|
793
|
-
}
|
|
794
|
-
try {
|
|
795
|
-
return (0, eval)("require");
|
|
796
|
-
} catch (error) {
|
|
797
|
-
return void 0;
|
|
798
|
-
}
|
|
799
|
-
};
|
|
800
|
-
var tryGetReactNativeBackHandler = () => {
|
|
801
|
-
const runtimeRequire = getRuntimeRequire();
|
|
802
|
-
if (!runtimeRequire) {
|
|
803
|
-
return void 0;
|
|
804
|
-
}
|
|
805
|
-
try {
|
|
806
|
-
const reactNativeModule = runtimeRequire("react-native");
|
|
807
|
-
const platform = reactNativeModule?.Platform;
|
|
808
|
-
const backHandler = reactNativeModule?.BackHandler;
|
|
809
|
-
if (platform?.OS !== "android") {
|
|
810
|
-
return void 0;
|
|
811
|
-
}
|
|
812
|
-
if (typeof backHandler?.addEventListener !== "function") {
|
|
813
|
-
return void 0;
|
|
814
|
-
}
|
|
815
|
-
return backHandler;
|
|
816
|
-
} catch (error) {
|
|
817
|
-
return void 0;
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
|
-
var canUseBrowserHistory = () => {
|
|
821
|
-
const WINDOW = getWindow();
|
|
822
|
-
return Boolean(
|
|
823
|
-
WINDOW && WINDOW.location && WINDOW.history && typeof WINDOW.history.pushState === "function"
|
|
824
|
-
);
|
|
825
|
-
};
|
|
826
|
-
var createBrowserRouteAdapter = () => {
|
|
827
|
-
const WINDOW = getWindow();
|
|
828
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
829
|
-
const notify = () => {
|
|
830
|
-
const path = WINDOW?.location?.pathname ?? "";
|
|
831
|
-
listeners.forEach((listener) => listener(path));
|
|
832
|
-
};
|
|
833
|
-
const handleHistoryEvent = () => {
|
|
834
|
-
notify();
|
|
835
|
-
};
|
|
836
|
-
return {
|
|
837
|
-
getPath: () => WINDOW?.location?.pathname ?? "",
|
|
838
|
-
subscribe: (listener) => {
|
|
839
|
-
listeners.add(listener);
|
|
840
|
-
if (WINDOW) {
|
|
841
|
-
WINDOW.addEventListener("popstate", handleHistoryEvent);
|
|
842
|
-
WINDOW.addEventListener("statechanged", handleHistoryEvent);
|
|
843
|
-
}
|
|
844
|
-
return () => {
|
|
845
|
-
listeners.delete(listener);
|
|
846
|
-
if (WINDOW) {
|
|
847
|
-
WINDOW.removeEventListener("popstate", handleHistoryEvent);
|
|
848
|
-
WINDOW.removeEventListener("statechanged", handleHistoryEvent);
|
|
849
|
-
}
|
|
850
|
-
};
|
|
851
|
-
},
|
|
852
|
-
push: (path, title = "") => {
|
|
853
|
-
if (!WINDOW?.history) {
|
|
854
|
-
return;
|
|
855
|
-
}
|
|
856
|
-
const targetPath = parseHistoryPath(path).path;
|
|
857
|
-
if (targetPath === (WINDOW.location?.pathname ?? "")) {
|
|
858
|
-
return;
|
|
859
|
-
}
|
|
860
|
-
WINDOW.history.pushState({}, title, path);
|
|
861
|
-
notify();
|
|
862
|
-
},
|
|
863
|
-
replace: (path, title = "") => {
|
|
864
|
-
if (!WINDOW?.history?.replaceState) {
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
const targetPath = parseHistoryPath(path).path;
|
|
868
|
-
if (targetPath === (WINDOW.location?.pathname ?? "")) {
|
|
869
|
-
return;
|
|
870
|
-
}
|
|
871
|
-
WINDOW.history.replaceState({}, title, path);
|
|
872
|
-
notify();
|
|
873
|
-
},
|
|
874
|
-
back: () => WINDOW?.history?.back(),
|
|
875
|
-
canGoBack: () => (WINDOW?.history?.length ?? 0) > 1
|
|
876
|
-
};
|
|
877
|
-
};
|
|
878
|
-
var createNativeRouteAdapter = (initialPath = "/", ingress) => {
|
|
879
|
-
const mapURLToPath = ingress?.mapURLToPath ?? ((url) => buildHistoryPath(parseHistoryPath(url)));
|
|
880
|
-
const onIncomingURL = ingress?.onIncomingURL ?? "replace";
|
|
881
|
-
const history = createMemoryHistory(initialPath);
|
|
882
|
-
const adapter = createRouteAdapterFromHistory(history);
|
|
883
|
-
let stopIngress;
|
|
884
|
-
let stopBackHandler;
|
|
885
|
-
let ingressStarted = false;
|
|
886
|
-
let subscribers = 0;
|
|
887
|
-
const applyPath = (path, mode) => {
|
|
888
|
-
const normalizedPath = parseHistoryPath(path).path;
|
|
889
|
-
if (!normalizedPath || normalizedPath === history.location.path) {
|
|
890
|
-
return;
|
|
891
|
-
}
|
|
892
|
-
if (mode === "push") {
|
|
893
|
-
history.push(normalizedPath, { replaceSearch: true });
|
|
894
|
-
return;
|
|
895
|
-
}
|
|
896
|
-
history.replace(normalizedPath, { replaceSearch: true });
|
|
897
|
-
};
|
|
898
|
-
const startIngress = async () => {
|
|
899
|
-
if (ingressStarted || !ingress) {
|
|
900
|
-
return;
|
|
901
|
-
}
|
|
902
|
-
ingressStarted = true;
|
|
903
|
-
const startKey = history.location.key;
|
|
904
|
-
const startIndex = history.index;
|
|
905
|
-
if (ingress.subscribe) {
|
|
906
|
-
stopIngress = ingress.subscribe((url) => {
|
|
907
|
-
const nextPath = mapURLToPath(url);
|
|
908
|
-
if (!nextPath) {
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
applyPath(nextPath, onIncomingURL);
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
const initialURL = await ingress.getInitialURL?.();
|
|
915
|
-
const userNavigated = history.location.key !== startKey || history.index !== startIndex;
|
|
916
|
-
if (!userNavigated && initialURL) {
|
|
917
|
-
const nextPath = mapURLToPath(initialURL);
|
|
918
|
-
if (nextPath) {
|
|
919
|
-
applyPath(nextPath, "replace");
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
};
|
|
923
|
-
const startBackHandler = () => {
|
|
924
|
-
if (stopBackHandler) {
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
927
|
-
const reactNativeBackHandler = tryGetReactNativeBackHandler();
|
|
928
|
-
if (!reactNativeBackHandler) {
|
|
929
|
-
return;
|
|
930
|
-
}
|
|
931
|
-
const historyBackHandler = createHistoryBackHandler(history);
|
|
932
|
-
const handleHardwareBackPress = () => historyBackHandler.handle();
|
|
933
|
-
const subscription = reactNativeBackHandler.addEventListener(
|
|
934
|
-
"hardwareBackPress",
|
|
935
|
-
handleHardwareBackPress
|
|
936
|
-
);
|
|
937
|
-
stopBackHandler = () => {
|
|
938
|
-
if (typeof subscription?.remove === "function") {
|
|
939
|
-
subscription.remove();
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
reactNativeBackHandler.removeEventListener?.(
|
|
943
|
-
"hardwareBackPress",
|
|
944
|
-
handleHardwareBackPress
|
|
945
|
-
);
|
|
946
|
-
};
|
|
947
|
-
};
|
|
948
|
-
return {
|
|
949
|
-
...adapter,
|
|
950
|
-
push: (path, title) => {
|
|
951
|
-
if (parseHistoryPath(path).path === history.location.path) {
|
|
952
|
-
return;
|
|
953
|
-
}
|
|
954
|
-
adapter.push?.(path, title);
|
|
955
|
-
},
|
|
956
|
-
replace: (path, title) => {
|
|
957
|
-
if (parseHistoryPath(path).path === history.location.path) {
|
|
958
|
-
return;
|
|
959
|
-
}
|
|
960
|
-
adapter.replace?.(path, title);
|
|
961
|
-
},
|
|
962
|
-
subscribe: (listener) => {
|
|
963
|
-
subscribers += 1;
|
|
964
|
-
if (subscribers === 1) {
|
|
965
|
-
void startIngress();
|
|
966
|
-
startBackHandler();
|
|
967
|
-
}
|
|
968
|
-
const unlisten = adapter.subscribe(listener);
|
|
969
|
-
return () => {
|
|
970
|
-
unlisten();
|
|
971
|
-
subscribers = Math.max(0, subscribers - 1);
|
|
972
|
-
if (subscribers === 0) {
|
|
973
|
-
stopIngress?.();
|
|
974
|
-
stopIngress = void 0;
|
|
975
|
-
ingressStarted = false;
|
|
976
|
-
stopBackHandler?.();
|
|
977
|
-
stopBackHandler = void 0;
|
|
978
|
-
}
|
|
979
|
-
};
|
|
980
|
-
},
|
|
981
|
-
back: adapter.back,
|
|
982
|
-
canGoBack: adapter.canGoBack
|
|
983
|
-
};
|
|
984
|
-
};
|
|
985
|
-
var createUniversalAdapter = (options = {}) => {
|
|
986
|
-
const { strategy = "auto", initialPath = "/", ingress } = options;
|
|
987
|
-
if (strategy === "web") {
|
|
988
|
-
return createBrowserRouteAdapter();
|
|
989
|
-
}
|
|
990
|
-
if (strategy === "native") {
|
|
991
|
-
return createNativeRouteAdapter(initialPath, ingress);
|
|
992
|
-
}
|
|
993
|
-
return canUseBrowserHistory() ? createBrowserRouteAdapter() : createNativeRouteAdapter(initialPath, ingress);
|
|
994
|
-
};
|
|
995
|
-
var createManualRouteAdapter = (initialPath = "/") => {
|
|
996
|
-
let currentPath = initialPath;
|
|
997
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
998
|
-
const updatePath = (nextPath) => {
|
|
999
|
-
currentPath = nextPath;
|
|
1000
|
-
listeners.forEach((listener) => listener(nextPath));
|
|
1001
|
-
};
|
|
1002
|
-
const adapter = {
|
|
1003
|
-
getPath: () => currentPath,
|
|
1004
|
-
subscribe: (listener) => {
|
|
1005
|
-
listeners.add(listener);
|
|
1006
|
-
return () => {
|
|
1007
|
-
listeners.delete(listener);
|
|
1008
|
-
};
|
|
1009
|
-
},
|
|
1010
|
-
push: (path) => updatePath(path),
|
|
1011
|
-
replace: (path) => updatePath(path)
|
|
1012
|
-
};
|
|
1013
|
-
return {
|
|
1014
|
-
adapter,
|
|
1015
|
-
updatePath
|
|
1016
|
-
};
|
|
1017
|
-
};
|
|
1018
|
-
var isDevelopmentMode = () => {
|
|
1019
|
-
const env = globalThis?.process?.env?.NODE_ENV;
|
|
1020
|
-
return env !== "production";
|
|
1021
|
-
};
|
|
1022
|
-
var buildQueryString = (query = {}) => {
|
|
1023
|
-
const parts = [];
|
|
1024
|
-
for (const [key, rawValue] of Object.entries(query)) {
|
|
1025
|
-
if (rawValue === void 0) {
|
|
1026
|
-
continue;
|
|
1027
|
-
}
|
|
1028
|
-
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
1029
|
-
for (const value of values) {
|
|
1030
|
-
if (value === void 0) {
|
|
1031
|
-
continue;
|
|
1032
|
-
}
|
|
1033
|
-
const encodedKey = encodeURIComponent(key);
|
|
1034
|
-
const encodedValue = value === null ? "" : encodeURIComponent(String(value));
|
|
1035
|
-
parts.push(`${encodedKey}=${encodedValue}`);
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
return parts.join("&");
|
|
1039
|
-
};
|
|
1040
|
-
var buildRoutePath = (segments, query) => {
|
|
1041
|
-
const normalizedSegments = segments.map((segment) => String(segment));
|
|
1042
|
-
const basePath = "/" + getPathString(normalizedSegments, "/", true, false, true);
|
|
1043
|
-
const queryString = query ? buildQueryString(query) : "";
|
|
1044
|
-
return queryString ? `${basePath}?${queryString}` : basePath;
|
|
1045
|
-
};
|
|
1046
|
-
var RouteContext = createContext({
|
|
1047
|
-
currentWindowPath: "",
|
|
1048
|
-
parentPath: "",
|
|
1049
|
-
params: {},
|
|
1050
|
-
isTopLevel: true
|
|
1051
|
-
});
|
|
1052
|
-
var {
|
|
1053
|
-
/**
|
|
1054
|
-
* @ignore
|
|
1055
|
-
*/
|
|
1056
|
-
Provider: RouteContextProvider,
|
|
1057
|
-
/**
|
|
1058
|
-
* @ignore
|
|
1059
|
-
*/
|
|
1060
|
-
Consumer: RouteContextConsumer
|
|
1061
|
-
} = RouteContext;
|
|
1062
|
-
var useRouteContext = () => useContext(RouteContext);
|
|
1063
|
-
var getWindow2 = () => {
|
|
1064
|
-
if (typeof globalThis === "undefined") {
|
|
1065
|
-
return void 0;
|
|
1066
|
-
}
|
|
1067
|
-
if ("window" in globalThis) {
|
|
1068
|
-
return globalThis.window;
|
|
1069
|
-
}
|
|
1070
|
-
return void 0;
|
|
1071
|
-
};
|
|
1072
|
-
var useBrowserLinkInterceptor = (adapter) => {
|
|
1073
|
-
useEffect(() => {
|
|
1074
|
-
const WINDOW = getWindow2();
|
|
1075
|
-
if (!WINDOW || !adapter?.push) {
|
|
1076
|
-
return void 0;
|
|
1077
|
-
}
|
|
1078
|
-
const handleAnchorClick = (event) => {
|
|
1079
|
-
let target = event.target;
|
|
1080
|
-
while (target && target.nodeName !== "A") {
|
|
1081
|
-
target = target.parentNode;
|
|
1082
|
-
}
|
|
1083
|
-
if (!target || target.nodeName !== "A") {
|
|
1084
|
-
return;
|
|
1085
|
-
}
|
|
1086
|
-
const anchor = target;
|
|
1087
|
-
const href = anchor.getAttribute("href");
|
|
1088
|
-
const title = anchor.getAttribute("title") ?? "";
|
|
1089
|
-
if (!href) {
|
|
1090
|
-
return;
|
|
1091
|
-
}
|
|
1092
|
-
try {
|
|
1093
|
-
new URL(href);
|
|
1094
|
-
return;
|
|
1095
|
-
} catch (error) {
|
|
1096
|
-
const nextPath = resolvePath(WINDOW.location?.pathname ?? "", href);
|
|
1097
|
-
event.preventDefault();
|
|
1098
|
-
adapter.push?.(nextPath, title);
|
|
1099
|
-
}
|
|
1100
|
-
};
|
|
1101
|
-
WINDOW.document?.addEventListener("click", handleAnchorClick);
|
|
1102
|
-
return () => {
|
|
1103
|
-
WINDOW.document?.removeEventListener("click", handleAnchorClick);
|
|
1104
|
-
};
|
|
1105
|
-
}, [adapter]);
|
|
1106
|
-
};
|
|
1107
|
-
var RouteProvider = ({
|
|
1108
|
-
adapter,
|
|
1109
|
-
initialPath,
|
|
1110
|
-
children
|
|
1111
|
-
}) => {
|
|
1112
|
-
const [currentPath, setCurrentPath] = useState(
|
|
1113
|
-
initialPath ?? adapter.getPath()
|
|
1114
|
-
);
|
|
1115
|
-
useEffect(() => {
|
|
1116
|
-
return adapter.subscribe((nextPath) => {
|
|
1117
|
-
setCurrentPath(nextPath);
|
|
1118
|
-
});
|
|
1119
|
-
}, [adapter]);
|
|
1120
|
-
const contextValue = useMemo(
|
|
1121
|
-
() => ({
|
|
1122
|
-
currentWindowPath: currentPath,
|
|
1123
|
-
parentPath: "",
|
|
1124
|
-
params: {},
|
|
1125
|
-
isTopLevel: true,
|
|
1126
|
-
adapter
|
|
1127
|
-
}),
|
|
1128
|
-
[currentPath, adapter]
|
|
1129
|
-
);
|
|
1130
|
-
return /* @__PURE__ */ jsx(RouteContextProvider, { value: contextValue, children });
|
|
1131
|
-
};
|
|
1132
|
-
var RouteMatcher = ({
|
|
1133
|
-
/**
|
|
1134
|
-
* Use `:` as the first character to denote a parameter in the path.
|
|
1135
|
-
*/
|
|
1136
|
-
path,
|
|
1137
|
-
onParamsChange,
|
|
1138
|
-
exact = false,
|
|
1139
|
-
children
|
|
1140
|
-
}) => {
|
|
1141
|
-
const {
|
|
1142
|
-
currentWindowPath = "",
|
|
1143
|
-
parentPath = "",
|
|
1144
|
-
params: parentParams = {},
|
|
1145
|
-
adapter
|
|
1146
|
-
} = useRouteContext();
|
|
1147
|
-
const targetCurrentPath = useMemo(
|
|
1148
|
-
() => currentWindowPath,
|
|
1149
|
-
[currentWindowPath]
|
|
1150
|
-
);
|
|
1151
|
-
const fullPath = useMemo(
|
|
1152
|
-
() => mergeStringPaths(parentPath, path),
|
|
1153
|
-
[parentPath, path]
|
|
1154
|
-
);
|
|
1155
|
-
const newParams = useMemo(
|
|
1156
|
-
() => getParamsAndTestPath(targetCurrentPath, fullPath, exact),
|
|
1157
|
-
[targetCurrentPath, fullPath, exact]
|
|
1158
|
-
);
|
|
1159
|
-
const params = useMemo(
|
|
1160
|
-
() => ({
|
|
1161
|
-
...parentParams,
|
|
1162
|
-
...newParams ? newParams : {}
|
|
1163
|
-
}),
|
|
1164
|
-
[parentParams, newParams]
|
|
1165
|
-
);
|
|
1166
|
-
const newRouteContext = useMemo(
|
|
1167
|
-
() => ({
|
|
1168
|
-
currentWindowPath: targetCurrentPath,
|
|
1169
|
-
parentPath: fullPath,
|
|
1170
|
-
params,
|
|
1171
|
-
isTopLevel: false,
|
|
1172
|
-
adapter
|
|
1173
|
-
}),
|
|
1174
|
-
[targetCurrentPath, fullPath, params, adapter]
|
|
1175
|
-
);
|
|
1176
|
-
useEffect(() => {
|
|
1177
|
-
if (onParamsChange) {
|
|
1178
|
-
onParamsChange(params);
|
|
1179
|
-
}
|
|
1180
|
-
}, [params, onParamsChange]);
|
|
1181
|
-
return newParams ? /* @__PURE__ */ jsx(RouteContextProvider, { value: newRouteContext, children }) : null;
|
|
1182
|
-
};
|
|
1183
|
-
var RouteRootProvider = ({
|
|
1184
|
-
children,
|
|
1185
|
-
adapter,
|
|
1186
|
-
initialPath,
|
|
1187
|
-
ingress
|
|
1188
|
-
}) => {
|
|
1189
|
-
const routeContext = useRouteContext();
|
|
1190
|
-
const autoAdapterRef = useRef(null);
|
|
1191
|
-
if (typeof routeContext.adapter !== "undefined" && isDevelopmentMode()) {
|
|
1192
|
-
throw new Error(
|
|
1193
|
-
"Route provider mode is root-only. Nested Route requires a path."
|
|
1194
|
-
);
|
|
1195
|
-
}
|
|
1196
|
-
if (!autoAdapterRef.current) {
|
|
1197
|
-
autoAdapterRef.current = adapter ?? createUniversalAdapter({ initialPath, ingress });
|
|
1198
|
-
}
|
|
1199
|
-
useBrowserLinkInterceptor(autoAdapterRef.current);
|
|
1200
|
-
return /* @__PURE__ */ jsx(RouteProvider, { adapter: autoAdapterRef.current, initialPath, children });
|
|
1201
|
-
};
|
|
1202
|
-
var Route = (props) => {
|
|
1203
|
-
const hasMatcherProps = typeof props.path !== "undefined" || typeof props.exact !== "undefined" || typeof props.onParamsChange !== "undefined";
|
|
1204
|
-
const hasProviderProps = typeof props.initialPath !== "undefined" || typeof props.adapter !== "undefined" || typeof props.ingress !== "undefined";
|
|
1205
|
-
if (hasMatcherProps) {
|
|
1206
|
-
if (hasProviderProps && isDevelopmentMode()) {
|
|
1207
|
-
throw new Error(
|
|
1208
|
-
"Route matcher mode does not support provider props. Remove initialPath/adapter/ingress or use a root Route without path."
|
|
1209
|
-
);
|
|
1210
|
-
}
|
|
1211
|
-
return /* @__PURE__ */ jsx(
|
|
1212
|
-
RouteMatcher,
|
|
1213
|
-
{
|
|
1214
|
-
path: props.path ?? "",
|
|
1215
|
-
onParamsChange: props.onParamsChange,
|
|
1216
|
-
exact: props.exact,
|
|
1217
|
-
children: props.children
|
|
1218
|
-
}
|
|
1219
|
-
);
|
|
1220
|
-
}
|
|
1221
|
-
if (typeof props.path === "undefined") {
|
|
1222
|
-
return /* @__PURE__ */ jsx(
|
|
1223
|
-
RouteRootProvider,
|
|
1224
|
-
{
|
|
1225
|
-
adapter: props.adapter,
|
|
1226
|
-
initialPath: props.initialPath,
|
|
1227
|
-
ingress: props.ingress,
|
|
1228
|
-
children: props.children
|
|
1229
|
-
}
|
|
1230
|
-
);
|
|
1231
|
-
}
|
|
1232
|
-
return null;
|
|
1233
|
-
};
|
|
1234
|
-
|
|
1235
287
|
// src/common/IdGeneration/getSimpleId.ts
|
|
1236
288
|
var LAST_HAST_ID = 0;
|
|
1237
289
|
var textEncoder = new TextEncoder();
|
|
@@ -1486,113 +538,6 @@ var TypeInfoORMClient = class {
|
|
|
1486
538
|
};
|
|
1487
539
|
};
|
|
1488
540
|
|
|
1489
|
-
// src/app/forms/core/getFieldKind.ts
|
|
1490
|
-
var hasSelectableValues = (field) => {
|
|
1491
|
-
const possibleValues = field.possibleValues ?? [];
|
|
1492
|
-
return possibleValues.some(
|
|
1493
|
-
(value) => typeof value === "string" || typeof value === "number"
|
|
1494
|
-
);
|
|
1495
|
-
};
|
|
1496
|
-
var getFieldKind = (field) => {
|
|
1497
|
-
if (field.typeReference) {
|
|
1498
|
-
return field.array ? "relation_array" : "relation_single";
|
|
1499
|
-
}
|
|
1500
|
-
if (field.tags?.customType) {
|
|
1501
|
-
return field.array ? "custom_array" : "custom_single";
|
|
1502
|
-
}
|
|
1503
|
-
if (field.array) {
|
|
1504
|
-
return "array";
|
|
1505
|
-
}
|
|
1506
|
-
if (hasSelectableValues(field)) {
|
|
1507
|
-
return "enum_select";
|
|
1508
|
-
}
|
|
1509
|
-
if (field.type === "boolean") {
|
|
1510
|
-
return "boolean";
|
|
1511
|
-
}
|
|
1512
|
-
if (field.type === "number") {
|
|
1513
|
-
return "number";
|
|
1514
|
-
}
|
|
1515
|
-
return "string";
|
|
1516
|
-
};
|
|
1517
|
-
|
|
1518
|
-
// src/app/forms/core/resolveSuite.ts
|
|
1519
|
-
var fieldKinds = [
|
|
1520
|
-
"string",
|
|
1521
|
-
"number",
|
|
1522
|
-
"boolean",
|
|
1523
|
-
"enum_select",
|
|
1524
|
-
"array",
|
|
1525
|
-
"relation_single",
|
|
1526
|
-
"relation_array",
|
|
1527
|
-
"custom_single",
|
|
1528
|
-
"custom_array"
|
|
1529
|
-
];
|
|
1530
|
-
var getMissingKinds = (renderers) => {
|
|
1531
|
-
return fieldKinds.filter((kind) => !renderers[kind]);
|
|
1532
|
-
};
|
|
1533
|
-
var resolveSuite = (overrides, fallback) => {
|
|
1534
|
-
const mergedRenderers = {
|
|
1535
|
-
...fallback.renderers ?? {},
|
|
1536
|
-
...overrides?.renderers ?? {}
|
|
1537
|
-
};
|
|
1538
|
-
const missingKinds = getMissingKinds(mergedRenderers);
|
|
1539
|
-
if (missingKinds.length) {
|
|
1540
|
-
throw new Error(
|
|
1541
|
-
`Missing renderers for field kinds: ${missingKinds.join(", ")}`
|
|
1542
|
-
);
|
|
1543
|
-
}
|
|
1544
|
-
const mergedPrimitives = {
|
|
1545
|
-
...fallback.primitives ?? {},
|
|
1546
|
-
...overrides?.primitives ?? {}
|
|
1547
|
-
};
|
|
1548
|
-
return {
|
|
1549
|
-
renderers: mergedRenderers,
|
|
1550
|
-
primitives: Object.keys(mergedPrimitives).length ? mergedPrimitives : void 0
|
|
1551
|
-
};
|
|
1552
|
-
};
|
|
1553
|
-
|
|
1554
|
-
// src/app/forms/core/createAutoField.ts
|
|
1555
|
-
var createAutoField = (suite) => {
|
|
1556
|
-
const renderField = (props) => {
|
|
1557
|
-
const { field, fieldKey, value, onChange, error, disabled } = props;
|
|
1558
|
-
const { tags } = field;
|
|
1559
|
-
const context = {
|
|
1560
|
-
field,
|
|
1561
|
-
fieldKey,
|
|
1562
|
-
label: tags?.label ?? fieldKey,
|
|
1563
|
-
required: !field.optional,
|
|
1564
|
-
disabled: !!disabled,
|
|
1565
|
-
error,
|
|
1566
|
-
value,
|
|
1567
|
-
onChange,
|
|
1568
|
-
constraints: tags?.constraints,
|
|
1569
|
-
format: tags?.format,
|
|
1570
|
-
possibleValues: field.possibleValues,
|
|
1571
|
-
allowCustomSelection: tags?.allowCustomSelection,
|
|
1572
|
-
customType: tags?.customType,
|
|
1573
|
-
onRelationAction: props.onRelationAction,
|
|
1574
|
-
onCustomTypeAction: props.onCustomTypeAction,
|
|
1575
|
-
renderField
|
|
1576
|
-
};
|
|
1577
|
-
const kind = getFieldKind(field);
|
|
1578
|
-
return suite.renderers[kind](context);
|
|
1579
|
-
};
|
|
1580
|
-
return renderField;
|
|
1581
|
-
};
|
|
1582
|
-
|
|
1583
|
-
// src/app/forms/core/createFormRenderer.ts
|
|
1584
|
-
var createFormRenderer = (options) => {
|
|
1585
|
-
const resolvedSuite = resolveSuite(
|
|
1586
|
-
options.suite,
|
|
1587
|
-
options.fallbackSuite
|
|
1588
|
-
);
|
|
1589
|
-
const AutoField = createAutoField(resolvedSuite);
|
|
1590
|
-
return {
|
|
1591
|
-
AutoField,
|
|
1592
|
-
suite: resolvedSuite
|
|
1593
|
-
};
|
|
1594
|
-
};
|
|
1595
|
-
|
|
1596
541
|
// src/app/forms/core/mergeSuites.ts
|
|
1597
542
|
var mergeSuites = (base, overrides) => {
|
|
1598
543
|
return {
|
|
@@ -1611,208 +556,5 @@ var withRendererOverride = (kind, renderer) => ({
|
|
|
1611
556
|
[kind]: renderer
|
|
1612
557
|
}
|
|
1613
558
|
});
|
|
1614
|
-
var getDeniedOperation = (deniedOperations, operation) => {
|
|
1615
|
-
if (!deniedOperations) {
|
|
1616
|
-
return false;
|
|
1617
|
-
}
|
|
1618
|
-
const denied = deniedOperations[operation];
|
|
1619
|
-
if (typeof denied === "boolean") {
|
|
1620
|
-
return denied;
|
|
1621
|
-
}
|
|
1622
|
-
return deniedOperations[operation.toLowerCase()] ?? false;
|
|
1623
|
-
};
|
|
1624
|
-
var buildInitialValues = (initialValues, typeInfo) => {
|
|
1625
|
-
const values = { ...initialValues };
|
|
1626
|
-
for (const [key, field] of Object.entries(typeInfo.fields ?? {})) {
|
|
1627
|
-
if (values[key] !== void 0) {
|
|
1628
|
-
continue;
|
|
1629
|
-
}
|
|
1630
|
-
const defaultValue = field.tags?.constraints?.defaultValue;
|
|
1631
|
-
if (defaultValue !== void 0) {
|
|
1632
|
-
let parsedDefaultValue = defaultValue;
|
|
1633
|
-
try {
|
|
1634
|
-
parsedDefaultValue = JSON.parse(defaultValue);
|
|
1635
|
-
} catch (error) {
|
|
1636
|
-
}
|
|
1637
|
-
values[key] = parsedDefaultValue;
|
|
1638
|
-
continue;
|
|
1639
|
-
}
|
|
1640
|
-
if (field.array && !field.typeReference && !field.optional) {
|
|
1641
|
-
values[key] = [];
|
|
1642
|
-
continue;
|
|
1643
|
-
}
|
|
1644
|
-
if (field.type === "boolean" && !field.optional) {
|
|
1645
|
-
values[key] = false;
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
return values;
|
|
1649
|
-
};
|
|
1650
|
-
var useFormEngine = (initialValues = {}, typeInfo, options) => {
|
|
1651
|
-
const operation = options?.operation ?? "CREATE" /* CREATE */;
|
|
1652
|
-
const [values, setValues] = useState(
|
|
1653
|
-
buildInitialValues(initialValues, typeInfo)
|
|
1654
|
-
);
|
|
1655
|
-
const [errors, setErrors] = useState({});
|
|
1656
|
-
const setFieldValue = useCallback((path, value) => {
|
|
1657
|
-
setValues((prev) => {
|
|
1658
|
-
return {
|
|
1659
|
-
...prev,
|
|
1660
|
-
[path]: value
|
|
1661
|
-
};
|
|
1662
|
-
});
|
|
1663
|
-
}, []);
|
|
1664
|
-
const validate = useCallback(() => {
|
|
1665
|
-
const newErrors = {};
|
|
1666
|
-
for (const [key, field] of Object.entries(typeInfo.fields ?? {})) {
|
|
1667
|
-
if (field.tags?.hidden) {
|
|
1668
|
-
continue;
|
|
1669
|
-
}
|
|
1670
|
-
const val = values[key];
|
|
1671
|
-
if (field.readonly && (val === void 0 || val === null || val === "")) {
|
|
1672
|
-
continue;
|
|
1673
|
-
}
|
|
1674
|
-
const isMissing = val === void 0 || val === null || val === "" || field.array && (!Array.isArray(val) || val.length === 0);
|
|
1675
|
-
if (!field.optional && isMissing) {
|
|
1676
|
-
newErrors[key] = "This field is required";
|
|
1677
|
-
continue;
|
|
1678
|
-
}
|
|
1679
|
-
if (isMissing) {
|
|
1680
|
-
continue;
|
|
1681
|
-
}
|
|
1682
|
-
const constraints = field.tags?.constraints;
|
|
1683
|
-
if (constraints?.pattern && typeof val === "string") {
|
|
1684
|
-
const pattern = new RegExp(constraints.pattern);
|
|
1685
|
-
if (!pattern.test(val)) {
|
|
1686
|
-
newErrors[key] = "Value does not match required pattern";
|
|
1687
|
-
continue;
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
if (field.type === "number" && typeof val === "number") {
|
|
1691
|
-
if (constraints?.min !== void 0 && val < constraints.min) {
|
|
1692
|
-
newErrors[key] = `Value must be at least ${constraints.min}`;
|
|
1693
|
-
continue;
|
|
1694
|
-
}
|
|
1695
|
-
if (constraints?.max !== void 0 && val > constraints.max) {
|
|
1696
|
-
newErrors[key] = `Value must be at most ${constraints.max}`;
|
|
1697
|
-
continue;
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
setErrors(newErrors);
|
|
1702
|
-
return Object.keys(newErrors).length === 0;
|
|
1703
|
-
}, [typeInfo, values]);
|
|
1704
|
-
const fields = useMemo(() => {
|
|
1705
|
-
return Object.entries(typeInfo.fields ?? {}).map(([key, field]) => {
|
|
1706
|
-
const { tags } = field;
|
|
1707
|
-
const isPrimary = tags?.primaryField || typeInfo.primaryField === key;
|
|
1708
|
-
return {
|
|
1709
|
-
key,
|
|
1710
|
-
field,
|
|
1711
|
-
label: tags?.label ?? key,
|
|
1712
|
-
required: !field.optional,
|
|
1713
|
-
disabled: field.readonly || getDeniedOperation(typeInfo.tags?.deniedOperations, operation) || getDeniedOperation(tags?.deniedOperations, operation) || operation === "UPDATE" /* UPDATE */ && isPrimary,
|
|
1714
|
-
hidden: !!tags?.hidden,
|
|
1715
|
-
primary: isPrimary,
|
|
1716
|
-
format: tags?.format,
|
|
1717
|
-
constraints: tags?.constraints,
|
|
1718
|
-
value: values[key],
|
|
1719
|
-
onChange: (value) => setFieldValue(key, value),
|
|
1720
|
-
error: errors[key]
|
|
1721
|
-
};
|
|
1722
|
-
});
|
|
1723
|
-
}, [typeInfo, values, errors, setFieldValue, operation]);
|
|
1724
|
-
return {
|
|
1725
|
-
typeInfo,
|
|
1726
|
-
typeTags: typeInfo.tags,
|
|
1727
|
-
operation,
|
|
1728
|
-
values,
|
|
1729
|
-
errors,
|
|
1730
|
-
fields,
|
|
1731
|
-
setFieldValue,
|
|
1732
|
-
validate,
|
|
1733
|
-
setErrors
|
|
1734
|
-
};
|
|
1735
|
-
};
|
|
1736
|
-
var fallbackFormRoot = ({
|
|
1737
|
-
children,
|
|
1738
|
-
onSubmit
|
|
1739
|
-
}) => {
|
|
1740
|
-
const handleSubmit = (event) => {
|
|
1741
|
-
event.preventDefault();
|
|
1742
|
-
onSubmit?.();
|
|
1743
|
-
};
|
|
1744
|
-
return /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children });
|
|
1745
|
-
};
|
|
1746
|
-
var fallbackButton = ({
|
|
1747
|
-
children,
|
|
1748
|
-
disabled,
|
|
1749
|
-
type,
|
|
1750
|
-
onClick
|
|
1751
|
-
}) => {
|
|
1752
|
-
return /* @__PURE__ */ jsx("button", { type: type ?? "button", disabled, onClick, children });
|
|
1753
|
-
};
|
|
1754
|
-
var AutoFormView = ({
|
|
1755
|
-
controller,
|
|
1756
|
-
onSubmit,
|
|
1757
|
-
renderer,
|
|
1758
|
-
submitDisabled,
|
|
1759
|
-
onRelationAction,
|
|
1760
|
-
onCustomTypeAction
|
|
1761
|
-
}) => {
|
|
1762
|
-
const FormRoot = renderer.suite.primitives?.FormRoot ?? fallbackFormRoot;
|
|
1763
|
-
const Button = renderer.suite.primitives?.Button ?? fallbackButton;
|
|
1764
|
-
const AutoField = renderer.AutoField;
|
|
1765
|
-
const submit = () => {
|
|
1766
|
-
if (controller.validate()) {
|
|
1767
|
-
onSubmit(controller.values);
|
|
1768
|
-
}
|
|
1769
|
-
};
|
|
1770
|
-
return /* @__PURE__ */ jsx(FormRoot, { onSubmit: submit, children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1771
|
-
controller.fields.filter((fieldController) => !fieldController.hidden).map((fieldController) => /* @__PURE__ */ jsx(
|
|
1772
|
-
AutoField,
|
|
1773
|
-
{
|
|
1774
|
-
field: fieldController.field,
|
|
1775
|
-
fieldKey: fieldController.key,
|
|
1776
|
-
value: fieldController.value,
|
|
1777
|
-
onChange: fieldController.onChange,
|
|
1778
|
-
error: fieldController.error,
|
|
1779
|
-
onRelationAction,
|
|
1780
|
-
disabled: fieldController.disabled,
|
|
1781
|
-
onCustomTypeAction
|
|
1782
|
-
},
|
|
1783
|
-
fieldController.key
|
|
1784
|
-
)),
|
|
1785
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", onClick: submit, disabled: submitDisabled, children: /* @__PURE__ */ jsx(Fragment, { children: "Submit" }) })
|
|
1786
|
-
] }) });
|
|
1787
|
-
};
|
|
1788
|
-
var AutoForm = ({
|
|
1789
|
-
typeInfo,
|
|
1790
|
-
onSubmit,
|
|
1791
|
-
renderer,
|
|
1792
|
-
initialValues,
|
|
1793
|
-
onValuesChange,
|
|
1794
|
-
onRelationAction,
|
|
1795
|
-
onCustomTypeAction,
|
|
1796
|
-
operation,
|
|
1797
|
-
submitDisabled
|
|
1798
|
-
}) => {
|
|
1799
|
-
const controller = useFormEngine(initialValues, typeInfo, { operation });
|
|
1800
|
-
useEffect(() => {
|
|
1801
|
-
if (onValuesChange) {
|
|
1802
|
-
onValuesChange(controller.values);
|
|
1803
|
-
}
|
|
1804
|
-
}, [controller.values, onValuesChange]);
|
|
1805
|
-
return /* @__PURE__ */ jsx(
|
|
1806
|
-
AutoFormView,
|
|
1807
|
-
{
|
|
1808
|
-
controller,
|
|
1809
|
-
onSubmit,
|
|
1810
|
-
renderer,
|
|
1811
|
-
onRelationAction,
|
|
1812
|
-
onCustomTypeAction,
|
|
1813
|
-
submitDisabled
|
|
1814
|
-
}
|
|
1815
|
-
);
|
|
1816
|
-
};
|
|
1817
559
|
|
|
1818
|
-
export { ApplicationStateContext, ApplicationStateProvider,
|
|
560
|
+
export { ApplicationStateContext, ApplicationStateProvider, TypeInfoORMClient, getApplicationStateIdentifier, getApplicationStateModified, getApplicationStateValue, getApplicationStateValueStructure, getChangedDependencyIndexes, getFullUrl, handleRequest, mergeSuites, requestHandlerFactory, sendServiceRequest, setApplicationStateModified, setApplicationStateValue, useApplicationStateLoader, useApplicationStateValue, useApplicationStateValueStructure, useController, useDebugDependencies, useTypeInfoORMAPI, withRendererOverride };
|