@jsenv/server 16.0.2 → 16.0.4
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/js/formidable_index.js +2 -2
- package/dist/js/ws.js +190 -2268
- package/dist/jsenv_server.js +74 -31
- package/package.json +5 -5
- /package/dist/{js/vendors.js → jsenv_server_node_modules.js} +0 -0
package/dist/jsenv_server.js
CHANGED
|
@@ -3600,6 +3600,13 @@ const applyPattern = ({ url, pattern }) => {
|
|
|
3600
3600
|
};
|
|
3601
3601
|
};
|
|
3602
3602
|
|
|
3603
|
+
/**
|
|
3604
|
+
* Core pattern matching function that processes patterns against strings
|
|
3605
|
+
* @param {string} pattern - The pattern with special syntax (*,**,/) to match against
|
|
3606
|
+
* @param {string} string - The string to test against the pattern
|
|
3607
|
+
* @returns {Object} Result containing match status and capture groups
|
|
3608
|
+
* @private
|
|
3609
|
+
*/
|
|
3603
3610
|
const applyMatching = (pattern, string) => {
|
|
3604
3611
|
const groups = [];
|
|
3605
3612
|
let patternIndex = 0;
|
|
@@ -3624,22 +3631,6 @@ const applyMatching = (pattern, string) => {
|
|
|
3624
3631
|
return consumeString(remainingString.length);
|
|
3625
3632
|
};
|
|
3626
3633
|
|
|
3627
|
-
let matched;
|
|
3628
|
-
const iterate = () => {
|
|
3629
|
-
const patternIndexBefore = patternIndex;
|
|
3630
|
-
const indexBefore = index;
|
|
3631
|
-
matched = matchOne();
|
|
3632
|
-
if (matched === undefined) {
|
|
3633
|
-
consumePattern(1);
|
|
3634
|
-
consumeString(1);
|
|
3635
|
-
iterate();
|
|
3636
|
-
return;
|
|
3637
|
-
}
|
|
3638
|
-
if (matched === false && restoreIndexes) {
|
|
3639
|
-
patternIndex = patternIndexBefore;
|
|
3640
|
-
index = indexBefore;
|
|
3641
|
-
}
|
|
3642
|
-
};
|
|
3643
3634
|
const matchOne = () => {
|
|
3644
3635
|
// pattern consumed
|
|
3645
3636
|
if (remainingPattern === "") {
|
|
@@ -3649,12 +3640,11 @@ const applyMatching = (pattern, string) => {
|
|
|
3649
3640
|
if (remainingString[0] === "?") {
|
|
3650
3641
|
// match search params
|
|
3651
3642
|
consumeRemainingString();
|
|
3652
|
-
|
|
3653
3643
|
return true;
|
|
3654
3644
|
}
|
|
3655
|
-
// if remainingString
|
|
3656
3645
|
return false; // fails because string longer than expect
|
|
3657
3646
|
}
|
|
3647
|
+
|
|
3658
3648
|
// -- from this point pattern is not consumed --
|
|
3659
3649
|
// string consumed, pattern not consumed
|
|
3660
3650
|
if (remainingString === "") {
|
|
@@ -3668,6 +3658,7 @@ const applyMatching = (pattern, string) => {
|
|
|
3668
3658
|
}
|
|
3669
3659
|
return false; // fail because string shorter than expect
|
|
3670
3660
|
}
|
|
3661
|
+
|
|
3671
3662
|
// -- from this point pattern and string are not consumed --
|
|
3672
3663
|
// fast path trailing slash
|
|
3673
3664
|
if (remainingPattern === "/") {
|
|
@@ -3679,25 +3670,30 @@ const applyMatching = (pattern, string) => {
|
|
|
3679
3670
|
}
|
|
3680
3671
|
return false;
|
|
3681
3672
|
}
|
|
3673
|
+
|
|
3682
3674
|
// fast path trailing '**'
|
|
3683
3675
|
if (remainingPattern === "**") {
|
|
3684
3676
|
consumePattern(2);
|
|
3685
3677
|
consumeRemainingString();
|
|
3686
3678
|
return true;
|
|
3687
3679
|
}
|
|
3680
|
+
|
|
3688
3681
|
if (remainingPattern.slice(0, 4) === "/**/") {
|
|
3689
3682
|
consumePattern(3); // consumes "/**/"
|
|
3690
|
-
const skipResult =
|
|
3683
|
+
const skipResult = skipUntilMatchIterative({
|
|
3691
3684
|
pattern: remainingPattern,
|
|
3692
3685
|
string: remainingString,
|
|
3693
3686
|
canSkipSlash: true,
|
|
3694
3687
|
});
|
|
3695
|
-
|
|
3688
|
+
for (let i = 0; i < skipResult.groups.length; i++) {
|
|
3689
|
+
groups.push(skipResult.groups[i]);
|
|
3690
|
+
}
|
|
3696
3691
|
consumePattern(skipResult.patternIndex);
|
|
3697
3692
|
consumeRemainingString();
|
|
3698
3693
|
restoreIndexes = false;
|
|
3699
3694
|
return skipResult.matched;
|
|
3700
3695
|
}
|
|
3696
|
+
|
|
3701
3697
|
// pattern leading **
|
|
3702
3698
|
if (remainingPattern.slice(0, 2) === "**") {
|
|
3703
3699
|
consumePattern(2); // consumes "**"
|
|
@@ -3707,7 +3703,7 @@ const applyMatching = (pattern, string) => {
|
|
|
3707
3703
|
// when remainingPattern was preceeded by "**/"
|
|
3708
3704
|
// and remainingString have no "/"
|
|
3709
3705
|
// then skip is not allowed, a regular match will be performed
|
|
3710
|
-
if (
|
|
3706
|
+
if (remainingString.includes("/")) {
|
|
3711
3707
|
skipAllowed = false;
|
|
3712
3708
|
}
|
|
3713
3709
|
}
|
|
@@ -3717,18 +3713,21 @@ const applyMatching = (pattern, string) => {
|
|
|
3717
3713
|
return true;
|
|
3718
3714
|
}
|
|
3719
3715
|
if (skipAllowed) {
|
|
3720
|
-
const skipResult =
|
|
3716
|
+
const skipResult = skipUntilMatchIterative({
|
|
3721
3717
|
pattern: remainingPattern,
|
|
3722
3718
|
string: remainingString,
|
|
3723
3719
|
canSkipSlash: true,
|
|
3724
3720
|
});
|
|
3725
|
-
|
|
3721
|
+
for (let i = 0; i < skipResult.groups.length; i++) {
|
|
3722
|
+
groups.push(skipResult.groups[i]);
|
|
3723
|
+
}
|
|
3726
3724
|
consumePattern(skipResult.patternIndex);
|
|
3727
3725
|
consumeRemainingString();
|
|
3728
3726
|
restoreIndexes = false;
|
|
3729
3727
|
return skipResult.matched;
|
|
3730
3728
|
}
|
|
3731
3729
|
}
|
|
3730
|
+
|
|
3732
3731
|
if (remainingPattern[0] === "*") {
|
|
3733
3732
|
consumePattern(1); // consumes "*"
|
|
3734
3733
|
if (remainingPattern === "") {
|
|
@@ -3748,23 +3747,53 @@ const applyMatching = (pattern, string) => {
|
|
|
3748
3747
|
patternIndex = patternIndex - 1;
|
|
3749
3748
|
return false;
|
|
3750
3749
|
}
|
|
3751
|
-
const skipResult =
|
|
3750
|
+
const skipResult = skipUntilMatchIterative({
|
|
3752
3751
|
pattern: remainingPattern,
|
|
3753
3752
|
string: remainingString,
|
|
3754
3753
|
canSkipSlash: false,
|
|
3755
3754
|
});
|
|
3756
|
-
groups.push(skipResult.group
|
|
3755
|
+
groups.push(skipResult.group);
|
|
3756
|
+
for (let i = 0; i < skipResult.groups.length; i++) {
|
|
3757
|
+
groups.push(skipResult.groups[i]);
|
|
3758
|
+
}
|
|
3757
3759
|
consumePattern(skipResult.patternIndex);
|
|
3758
3760
|
consumeString(skipResult.index);
|
|
3759
3761
|
restoreIndexes = false;
|
|
3760
3762
|
return skipResult.matched;
|
|
3761
3763
|
}
|
|
3764
|
+
|
|
3762
3765
|
if (remainingPattern[0] !== remainingString[0]) {
|
|
3763
3766
|
return false;
|
|
3764
3767
|
}
|
|
3768
|
+
|
|
3765
3769
|
return undefined;
|
|
3766
3770
|
};
|
|
3767
|
-
|
|
3771
|
+
|
|
3772
|
+
// Replace recursive iterate() with iterative approach
|
|
3773
|
+
let matched;
|
|
3774
|
+
let continueIteration = true;
|
|
3775
|
+
|
|
3776
|
+
while (continueIteration) {
|
|
3777
|
+
const patternIndexBefore = patternIndex;
|
|
3778
|
+
const indexBefore = index;
|
|
3779
|
+
|
|
3780
|
+
matched = matchOne();
|
|
3781
|
+
|
|
3782
|
+
if (matched === undefined) {
|
|
3783
|
+
consumePattern(1);
|
|
3784
|
+
consumeString(1);
|
|
3785
|
+
// Continue the loop instead of recursion
|
|
3786
|
+
continue;
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
if (matched === false && restoreIndexes) {
|
|
3790
|
+
patternIndex = patternIndexBefore;
|
|
3791
|
+
index = indexBefore;
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3794
|
+
// End the loop
|
|
3795
|
+
continueIteration = false;
|
|
3796
|
+
}
|
|
3768
3797
|
|
|
3769
3798
|
return {
|
|
3770
3799
|
matched,
|
|
@@ -3774,7 +3803,15 @@ const applyMatching = (pattern, string) => {
|
|
|
3774
3803
|
};
|
|
3775
3804
|
};
|
|
3776
3805
|
|
|
3777
|
-
|
|
3806
|
+
/**
|
|
3807
|
+
* Iterative version of skipUntilMatch that avoids recursion
|
|
3808
|
+
* @param {Object} params
|
|
3809
|
+
* @param {string} params.pattern - The pattern to match
|
|
3810
|
+
* @param {string} params.string - The string to test against
|
|
3811
|
+
* @param {boolean} params.canSkipSlash - Whether slash characters can be skipped
|
|
3812
|
+
* @returns {Object} Result of the matching attempt
|
|
3813
|
+
*/
|
|
3814
|
+
const skipUntilMatchIterative = ({ pattern, string, canSkipSlash }) => {
|
|
3778
3815
|
let index = 0;
|
|
3779
3816
|
let remainingString = string;
|
|
3780
3817
|
let longestAttemptRange = null;
|
|
@@ -3792,8 +3829,10 @@ const skipUntilMatch = ({ pattern, string, canSkipSlash }) => {
|
|
|
3792
3829
|
};
|
|
3793
3830
|
};
|
|
3794
3831
|
|
|
3795
|
-
|
|
3832
|
+
// Loop until a match is found or all attempts fail
|
|
3833
|
+
while (true) {
|
|
3796
3834
|
const matchAttempt = applyMatching(pattern, remainingString);
|
|
3835
|
+
|
|
3797
3836
|
if (matchAttempt.matched) {
|
|
3798
3837
|
return {
|
|
3799
3838
|
matched: true,
|
|
@@ -3808,6 +3847,7 @@ const skipUntilMatch = ({ pattern, string, canSkipSlash }) => {
|
|
|
3808
3847
|
},
|
|
3809
3848
|
};
|
|
3810
3849
|
}
|
|
3850
|
+
|
|
3811
3851
|
const attemptIndex = matchAttempt.index;
|
|
3812
3852
|
const attemptRange = {
|
|
3813
3853
|
patternIndex: matchAttempt.patternIndex,
|
|
@@ -3815,19 +3855,23 @@ const skipUntilMatch = ({ pattern, string, canSkipSlash }) => {
|
|
|
3815
3855
|
length: attemptIndex,
|
|
3816
3856
|
groups: matchAttempt.groups,
|
|
3817
3857
|
};
|
|
3858
|
+
|
|
3818
3859
|
if (
|
|
3819
3860
|
!longestAttemptRange ||
|
|
3820
3861
|
longestAttemptRange.length < attemptRange.length
|
|
3821
3862
|
) {
|
|
3822
3863
|
longestAttemptRange = attemptRange;
|
|
3823
3864
|
}
|
|
3865
|
+
|
|
3824
3866
|
if (isLastAttempt) {
|
|
3825
3867
|
return failure();
|
|
3826
3868
|
}
|
|
3869
|
+
|
|
3827
3870
|
const nextIndex = attemptIndex + 1;
|
|
3828
3871
|
if (nextIndex >= remainingString.length) {
|
|
3829
3872
|
return failure();
|
|
3830
3873
|
}
|
|
3874
|
+
|
|
3831
3875
|
if (remainingString[0] === "/") {
|
|
3832
3876
|
if (!canSkipSlash) {
|
|
3833
3877
|
return failure();
|
|
@@ -3837,12 +3881,11 @@ const skipUntilMatch = ({ pattern, string, canSkipSlash }) => {
|
|
|
3837
3881
|
isLastAttempt = true;
|
|
3838
3882
|
}
|
|
3839
3883
|
}
|
|
3884
|
+
|
|
3840
3885
|
// search against the next unattempted string
|
|
3841
3886
|
index += nextIndex;
|
|
3842
3887
|
remainingString = remainingString.slice(nextIndex);
|
|
3843
|
-
|
|
3844
|
-
};
|
|
3845
|
-
return tryToMatch();
|
|
3888
|
+
}
|
|
3846
3889
|
};
|
|
3847
3890
|
|
|
3848
3891
|
const applyPatternMatching = ({ url, pattern }) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/server",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.4",
|
|
4
4
|
"description": "A modern Node.js HTTP server with declarative routing, content negotiation, and WebSocket support",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"launch-editor": "2.10.0",
|
|
43
43
|
"@jsenv/abort": "4.3.1",
|
|
44
44
|
"@jsenv/humanize": "1.3.1",
|
|
45
|
-
"@jsenv/url-meta": "8.5.
|
|
45
|
+
"@jsenv/url-meta": "8.5.5",
|
|
46
46
|
"@jsenv/utils": "2.2.1",
|
|
47
|
-
"ws": "8.18.
|
|
47
|
+
"ws": "8.18.1",
|
|
48
48
|
"formidable": "3.5.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"eventsource": "3.0.
|
|
52
|
-
"undici": "7.
|
|
51
|
+
"eventsource": "3.0.5",
|
|
52
|
+
"undici": "7.5.0"
|
|
53
53
|
}
|
|
54
54
|
}
|
|
File without changes
|