@hybridly/core 0.4.1 → 0.4.3
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/dist/index.cjs +110 -56
- package/dist/index.d.cts +490 -0
- package/dist/index.d.mts +490 -0
- package/dist/index.d.ts +23 -36
- package/dist/index.mjs +108 -51
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const qs = require('qs');
|
|
5
4
|
const utils = require('@hybridly/utils');
|
|
6
5
|
const axios = require('axios');
|
|
7
6
|
const superjson = require('superjson');
|
|
8
|
-
const qs = require('qs');
|
|
9
7
|
|
|
10
|
-
function
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
9
|
|
|
12
|
-
const
|
|
13
|
-
const
|
|
10
|
+
const qs__default = /*#__PURE__*/_interopDefaultCompat(qs);
|
|
11
|
+
const axios__default = /*#__PURE__*/_interopDefaultCompat(axios);
|
|
14
12
|
|
|
15
13
|
const STORAGE_EXTERNAL_KEY = "hybridly:external";
|
|
16
14
|
const HYBRIDLY_HEADER = "x-hybrid";
|
|
@@ -27,18 +25,18 @@ const SCROLL_REGION_ATTRIBUTE = "scroll-region";
|
|
|
27
25
|
|
|
28
26
|
const constants = {
|
|
29
27
|
__proto__: null,
|
|
30
|
-
|
|
31
|
-
HYBRIDLY_HEADER: HYBRIDLY_HEADER,
|
|
32
|
-
EXTERNAL_NAVIGATION_HEADER: EXTERNAL_NAVIGATION_HEADER,
|
|
33
|
-
PARTIAL_COMPONENT_HEADER: PARTIAL_COMPONENT_HEADER,
|
|
34
|
-
ONLY_DATA_HEADER: ONLY_DATA_HEADER,
|
|
28
|
+
CONTEXT_HEADER: CONTEXT_HEADER,
|
|
35
29
|
DIALOG_KEY_HEADER: DIALOG_KEY_HEADER,
|
|
36
30
|
DIALOG_REDIRECT_HEADER: DIALOG_REDIRECT_HEADER,
|
|
37
|
-
EXCEPT_DATA_HEADER: EXCEPT_DATA_HEADER,
|
|
38
|
-
CONTEXT_HEADER: CONTEXT_HEADER,
|
|
39
|
-
VERSION_HEADER: VERSION_HEADER,
|
|
40
31
|
ERROR_BAG_HEADER: ERROR_BAG_HEADER,
|
|
41
|
-
|
|
32
|
+
EXCEPT_DATA_HEADER: EXCEPT_DATA_HEADER,
|
|
33
|
+
EXTERNAL_NAVIGATION_HEADER: EXTERNAL_NAVIGATION_HEADER,
|
|
34
|
+
HYBRIDLY_HEADER: HYBRIDLY_HEADER,
|
|
35
|
+
ONLY_DATA_HEADER: ONLY_DATA_HEADER,
|
|
36
|
+
PARTIAL_COMPONENT_HEADER: PARTIAL_COMPONENT_HEADER,
|
|
37
|
+
SCROLL_REGION_ATTRIBUTE: SCROLL_REGION_ATTRIBUTE,
|
|
38
|
+
STORAGE_EXTERNAL_KEY: STORAGE_EXTERNAL_KEY,
|
|
39
|
+
VERSION_HEADER: VERSION_HEADER
|
|
42
40
|
};
|
|
43
41
|
|
|
44
42
|
class NotAHybridResponseError extends Error {
|
|
@@ -245,6 +243,7 @@ function setHistoryState(options = {}) {
|
|
|
245
243
|
utils.debug.history("Setting history state:", {
|
|
246
244
|
method,
|
|
247
245
|
context
|
|
246
|
+
// serialized,
|
|
248
247
|
});
|
|
249
248
|
try {
|
|
250
249
|
window.history[method](serialized, "", context.url);
|
|
@@ -360,10 +359,59 @@ function createSerializer(options) {
|
|
|
360
359
|
};
|
|
361
360
|
}
|
|
362
361
|
|
|
362
|
+
function getUrlRegexForRoute(name) {
|
|
363
|
+
const routing = getRouting();
|
|
364
|
+
const definition = getRouteDefinition(name);
|
|
365
|
+
const path = definition.uri.replaceAll("/", "\\/");
|
|
366
|
+
const domain = definition.domain;
|
|
367
|
+
const protocolPrefix = routing.url.match(/^\w+:\/\//)?.[0];
|
|
368
|
+
const origin = domain ? `${protocolPrefix}${domain}${routing.port ? `:${routing.port}` : ""}`.replaceAll("/", "\\/") : routing.url.replaceAll("/", "\\/");
|
|
369
|
+
const urlPathRegexPattern = path.length > 0 ? `\\/${path.replace(/\/$/g, "")}` : "";
|
|
370
|
+
let urlRegexPattern = `^${origin.replaceAll(".", "\\.")}${urlPathRegexPattern}\\/?(\\?.*)?$`;
|
|
371
|
+
urlRegexPattern = urlRegexPattern.replace(/(\\\/?){([^}?]+)(\??)}/g, (_, slash, parameterName, optional) => {
|
|
372
|
+
const where = definition.wheres?.[parameterName];
|
|
373
|
+
let regexTemplate = where?.replace(/(^\^)|(\$$)/g, "") || "[^/?]+";
|
|
374
|
+
regexTemplate = `(?<${parameterName}>${regexTemplate})`;
|
|
375
|
+
if (optional) {
|
|
376
|
+
return `(${slash ? "\\/?" : ""}${regexTemplate})?`;
|
|
377
|
+
}
|
|
378
|
+
return (slash ? "\\/" : "") + regexTemplate;
|
|
379
|
+
});
|
|
380
|
+
return RegExp(urlRegexPattern);
|
|
381
|
+
}
|
|
382
|
+
function urlMatchesRoute(url, name, routeParameters) {
|
|
383
|
+
const parameters = routeParameters || {};
|
|
384
|
+
const definition = getRouting().routes[name];
|
|
385
|
+
if (!definition) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
const matches = getUrlRegexForRoute(name).exec(url);
|
|
389
|
+
if (!matches) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
for (const k in matches.groups) {
|
|
393
|
+
matches.groups[k] = typeof matches.groups[k] === "string" ? decodeURIComponent(matches.groups[k]) : matches.groups[k];
|
|
394
|
+
}
|
|
395
|
+
return Object.keys(parameters).every((parameterName) => {
|
|
396
|
+
let value = parameters[parameterName];
|
|
397
|
+
const bindingProperty = definition.bindings?.[parameterName];
|
|
398
|
+
if (bindingProperty && typeof value === "object") {
|
|
399
|
+
value = value[bindingProperty];
|
|
400
|
+
}
|
|
401
|
+
return matches.groups?.[parameterName] === value.toString();
|
|
402
|
+
});
|
|
403
|
+
}
|
|
363
404
|
function generateRouteFromName(name, parameters, absolute, shouldThrow) {
|
|
364
405
|
const url = getUrlFromName(name, parameters, shouldThrow);
|
|
365
406
|
return absolute === false ? url.toString().replace(url.origin, "") : url.toString();
|
|
366
407
|
}
|
|
408
|
+
function getNameFromUrl(url, parameters) {
|
|
409
|
+
const routing = getRouting();
|
|
410
|
+
const routes = Object.values(routing.routes).map((x) => x.name);
|
|
411
|
+
return routes.find((routeName) => {
|
|
412
|
+
return urlMatchesRoute(url, routeName, parameters);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
367
415
|
function getUrlFromName(name, parameters, shouldThrow) {
|
|
368
416
|
const routing = getRouting();
|
|
369
417
|
const definition = getRouteDefinition(name);
|
|
@@ -376,32 +424,39 @@ function getUrlFromName(name, parameters, shouldThrow) {
|
|
|
376
424
|
}));
|
|
377
425
|
return url;
|
|
378
426
|
}
|
|
379
|
-
function
|
|
427
|
+
function getRouteParameterValue(routeName, parameterName, routeParameters) {
|
|
380
428
|
const routing = getRouting();
|
|
429
|
+
const definition = getRouteDefinition(routeName);
|
|
430
|
+
const parameters = routeParameters || {};
|
|
431
|
+
const value = (() => {
|
|
432
|
+
const value2 = parameters[parameterName];
|
|
433
|
+
const bindingProperty = definition.bindings?.[parameterName];
|
|
434
|
+
if (bindingProperty && value2 != null && typeof value2 === "object") {
|
|
435
|
+
return value2[bindingProperty];
|
|
436
|
+
}
|
|
437
|
+
return value2;
|
|
438
|
+
})();
|
|
439
|
+
if (value) {
|
|
440
|
+
const where = definition.wheres?.[parameterName];
|
|
441
|
+
if (where && !new RegExp(where).test(value)) {
|
|
442
|
+
console.warn(`[hybridly:routing] Parameter [${parameterName}] does not match the required format [${where}] for route [${routeName}].`);
|
|
443
|
+
}
|
|
444
|
+
return value;
|
|
445
|
+
}
|
|
446
|
+
if (routing.defaults?.[parameterName]) {
|
|
447
|
+
return routing.defaults?.[parameterName];
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function getRouteTransformable(routeName, routeParameters, shouldThrow) {
|
|
381
451
|
const definition = getRouteDefinition(routeName);
|
|
382
452
|
const parameters = routeParameters || {};
|
|
383
453
|
const missing = Object.keys(parameters);
|
|
384
|
-
const replaceParameter = (match, parameterName) => {
|
|
385
|
-
const
|
|
386
|
-
const value = (() => {
|
|
387
|
-
const value2 = parameters[parameterName];
|
|
388
|
-
const bindingProperty = definition.bindings?.[parameterName];
|
|
389
|
-
if (bindingProperty && typeof value2 === "object") {
|
|
390
|
-
return value2[bindingProperty];
|
|
391
|
-
}
|
|
392
|
-
return value2;
|
|
393
|
-
})();
|
|
454
|
+
const replaceParameter = (match, parameterName, optional) => {
|
|
455
|
+
const value = getRouteParameterValue(routeName, parameterName, parameters);
|
|
394
456
|
missing.splice(missing.indexOf(parameterName), 1);
|
|
395
457
|
if (value) {
|
|
396
|
-
const where = definition.wheres?.[parameterName];
|
|
397
|
-
if (where && !new RegExp(where).test(value)) {
|
|
398
|
-
console.warn(`[hybridly:routing] Parameter [${parameterName}] does not match the required format [${where}] for route [${routeName}].`);
|
|
399
|
-
}
|
|
400
458
|
return value;
|
|
401
459
|
}
|
|
402
|
-
if (routing.defaults?.[parameterName]) {
|
|
403
|
-
return routing.defaults?.[parameterName];
|
|
404
|
-
}
|
|
405
460
|
if (optional) {
|
|
406
461
|
return "";
|
|
407
462
|
}
|
|
@@ -410,8 +465,8 @@ function getRouteTransformable(routeName, routeParameters, shouldThrow) {
|
|
|
410
465
|
}
|
|
411
466
|
throw new MissingRouteParameter(parameterName, routeName);
|
|
412
467
|
};
|
|
413
|
-
const path = definition.uri.replace(/{([^}?]+)\??}/g, replaceParameter);
|
|
414
|
-
const domain = definition.domain?.replace(/{([^}?]+)\??}/g, replaceParameter);
|
|
468
|
+
const path = definition.uri.replace(/{([^}?]+)(\??)}/g, replaceParameter);
|
|
469
|
+
const domain = definition.domain?.replace(/{([^}?]+)(\??)}/g, replaceParameter);
|
|
415
470
|
const remaining = Object.keys(parameters).filter((key) => missing.includes(key)).reduce((obj, key) => ({
|
|
416
471
|
...obj,
|
|
417
472
|
[key]: parameters[key]
|
|
@@ -441,30 +496,28 @@ function getRouting() {
|
|
|
441
496
|
}
|
|
442
497
|
return routing;
|
|
443
498
|
}
|
|
444
|
-
|
|
445
|
-
function isCurrentFromName(name, parameters, mode = "loose") {
|
|
446
|
-
const location = window.location;
|
|
447
|
-
const matchee = (() => {
|
|
448
|
-
try {
|
|
449
|
-
return makeUrl(generateRouteFromName(name, parameters, true, false));
|
|
450
|
-
} catch (error) {
|
|
451
|
-
}
|
|
452
|
-
})();
|
|
453
|
-
if (!matchee) {
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
if (mode === "strict") {
|
|
457
|
-
return location.href === matchee.href;
|
|
458
|
-
}
|
|
459
|
-
return location.href.startsWith(matchee.href);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
499
|
function route(name, parameters, absolute) {
|
|
463
500
|
return generateRouteFromName(name, parameters, absolute);
|
|
464
501
|
}
|
|
465
|
-
|
|
466
|
-
|
|
502
|
+
|
|
503
|
+
function getCurrentUrl() {
|
|
504
|
+
if (typeof window === "undefined") {
|
|
505
|
+
return getInternalRouterContext().url;
|
|
506
|
+
}
|
|
507
|
+
return window.location.toString();
|
|
508
|
+
}
|
|
509
|
+
function currentRouteMatches(name, parameters) {
|
|
510
|
+
const namePattern = name.replaceAll(".", "\\.").replaceAll("*", ".*");
|
|
511
|
+
const possibleRoutes = Object.values(getRouting().routes).filter((x) => x.method.includes("GET") && RegExp(namePattern).test(x.name)).map((x) => x.name);
|
|
512
|
+
const currentUrl = getCurrentUrl();
|
|
513
|
+
return possibleRoutes.some((routeName) => {
|
|
514
|
+
return urlMatchesRoute(currentUrl, routeName, parameters);
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
function getCurrentRouteName() {
|
|
518
|
+
return getNameFromUrl(getCurrentUrl());
|
|
467
519
|
}
|
|
520
|
+
|
|
468
521
|
function updateRoutingConfiguration(routing) {
|
|
469
522
|
if (!routing) {
|
|
470
523
|
return;
|
|
@@ -655,6 +708,8 @@ const router = {
|
|
|
655
708
|
const method = getRouteDefinition(name).method.at(0);
|
|
656
709
|
return await performHybridNavigation({ url, ...options, method });
|
|
657
710
|
},
|
|
711
|
+
matches: (name, parameters) => currentRouteMatches(name, parameters),
|
|
712
|
+
current: () => getCurrentRouteName(),
|
|
658
713
|
dialog: {
|
|
659
714
|
close: (options) => closeDialog(options)
|
|
660
715
|
},
|
|
@@ -956,7 +1011,6 @@ function can(resource, action) {
|
|
|
956
1011
|
exports.can = can;
|
|
957
1012
|
exports.constants = constants;
|
|
958
1013
|
exports.createRouter = createRouter;
|
|
959
|
-
exports.current = current;
|
|
960
1014
|
exports.definePlugin = definePlugin;
|
|
961
1015
|
exports.getRouterContext = getRouterContext;
|
|
962
1016
|
exports.makeUrl = makeUrl;
|