mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 22:40:20 +08:00
Refactor to use KV exclusively
This commit is contained in:
parent
5f8b8a2147
commit
21c537fe22
98
src/IPC.js
98
src/IPC.js
@ -185,89 +185,45 @@ window.addEventListener('message', async (event) => {
|
||||
// setItem
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'setItem' && event.data.key && event.data.value){
|
||||
// todo: validate key and value to avoid unnecessary api calls
|
||||
return await $.ajax({
|
||||
url: window.api_origin + "/setItem",
|
||||
type: 'POST',
|
||||
data: JSON.stringify({
|
||||
app: app_uuid,
|
||||
key: event.data.key,
|
||||
value: event.data.value,
|
||||
}),
|
||||
async: true,
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Authorization": "Bearer "+window.auth_token
|
||||
},
|
||||
statusCode: {
|
||||
401: function () {
|
||||
window.logout();
|
||||
},
|
||||
},
|
||||
success: function (fsentry){
|
||||
}
|
||||
puter.kv.set({
|
||||
key: event.data.key,
|
||||
value: event.data.value,
|
||||
app: app_uuid,
|
||||
}).then(() => {
|
||||
// send confirmation to requester window
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
}, '*');
|
||||
})
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// getItem
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'getItem' && event.data.key){
|
||||
// todo: validate key to avoid unnecessary api calls
|
||||
$.ajax({
|
||||
url: window.api_origin + "/getItem",
|
||||
type: 'POST',
|
||||
data: JSON.stringify({
|
||||
key: event.data.key,
|
||||
app: app_uuid,
|
||||
}),
|
||||
async: true,
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Authorization": "Bearer "+window.auth_token
|
||||
},
|
||||
statusCode: {
|
||||
401: function () {
|
||||
window.logout();
|
||||
},
|
||||
},
|
||||
success: function (result){
|
||||
// send confirmation to requester window
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
msg: 'getItemSucceeded',
|
||||
value: result ? result.value : null,
|
||||
}, '*');
|
||||
}
|
||||
puter.kv.get({
|
||||
key: event.data.key,
|
||||
app: app_uuid,
|
||||
}).then((result) => {
|
||||
// send confirmation to requester window
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
msg: 'getItemSucceeded',
|
||||
value: result ?? null,
|
||||
}, '*');
|
||||
})
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// removeItem
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'removeItem' && event.data.key){
|
||||
// todo: validate key to avoid unnecessary api calls
|
||||
$.ajax({
|
||||
url: window.api_origin + "/removeItem",
|
||||
type: 'POST',
|
||||
data: JSON.stringify({
|
||||
key: event.data.key,
|
||||
app: app_uuid,
|
||||
}),
|
||||
async: true,
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Authorization": "Bearer "+window.auth_token
|
||||
},
|
||||
statusCode: {
|
||||
401: function () {
|
||||
window.logout();
|
||||
},
|
||||
},
|
||||
success: function (result){
|
||||
// send confirmation to requester window
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
}, '*');
|
||||
}
|
||||
puter.kv.del({
|
||||
key: event.data.key,
|
||||
app: app_uuid,
|
||||
}).then(() => {
|
||||
// send confirmation to requester window
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
}, '*');
|
||||
})
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
|
@ -540,14 +540,11 @@ async function UIDesktop(options){
|
||||
h += `</div>`;
|
||||
|
||||
// Get window sidebar width
|
||||
window.getItem({
|
||||
key: "window_sidebar_width",
|
||||
success: async function(res){
|
||||
let value = parseInt(res.value);
|
||||
// if value is a valid number
|
||||
if(!isNaN(value) && value > 0){
|
||||
window.window_sidebar_width = value;
|
||||
}
|
||||
puter.kv.get('window_sidebar_width').then(async (val) => {
|
||||
let value = parseInt(val);
|
||||
// if value is a valid number
|
||||
if(!isNaN(value) && value > 0){
|
||||
window.window_sidebar_width = value;
|
||||
}
|
||||
})
|
||||
|
||||
@ -1072,18 +1069,15 @@ async function UIDesktop(options){
|
||||
|
||||
// show referral notice window
|
||||
if(window.show_referral_notice && !window.user.email_confirmed){
|
||||
window.getItem({
|
||||
key: "shown_referral_notice",
|
||||
success: async function(res){
|
||||
if(!res){
|
||||
setTimeout(() => {
|
||||
UIWindowClaimReferral();
|
||||
}, 1000);
|
||||
window.setItem({
|
||||
key: "shown_referral_notice",
|
||||
value: true,
|
||||
})
|
||||
}
|
||||
puter.kv.get('shown_referral_notice').then(async (val) => {
|
||||
if(!val || val === 'false' || val === false){
|
||||
setTimeout(() => {
|
||||
UIWindowClaimReferral();
|
||||
}, 1000);
|
||||
puter.kv.set({
|
||||
key: "shown_referral_notice",
|
||||
value: true,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1776,7 +1776,7 @@ async function UIWindow(options) {
|
||||
$('.window').css('pointer-events', 'initial');
|
||||
const new_width = $(el_window_sidebar).width();
|
||||
// save new width in the cloud, to user's settings
|
||||
window.setItem({key: "window_sidebar_width", value: new_width});
|
||||
puter.kv.set({key: "window_sidebar_width", value: new_width});
|
||||
// save new width locally, to window object
|
||||
window.window_sidebar_width = new_width;
|
||||
}
|
||||
|
303
src/helpers.js
303
src/helpers.js
@ -30,6 +30,7 @@ import content_type_to_icon from './helpers/content_type_to_icon.js';
|
||||
import truncate_filename from './helpers/truncate_filename.js';
|
||||
import UIWindowProgress from './UI/UIWindowProgress.js';
|
||||
import launch_app from "./helpers/launch_app.js";
|
||||
import globToRegExp from "./helpers/globToRegExp.js";
|
||||
|
||||
window.is_auth = ()=>{
|
||||
if(localStorage.getItem("auth_token") === null || window.auth_token === null)
|
||||
@ -162,203 +163,6 @@ window.scrollParentToChild = (parent, child)=>{
|
||||
}
|
||||
}
|
||||
|
||||
window.getItem = async function(options){
|
||||
return $.ajax({
|
||||
url: window.api_origin + "/getItem",
|
||||
type: 'POST',
|
||||
data: JSON.stringify({
|
||||
key: options.key,
|
||||
app: options.app_uid,
|
||||
}),
|
||||
async: true,
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Authorization": "Bearer "+window.auth_token
|
||||
},
|
||||
statusCode: {
|
||||
401: function () {
|
||||
window.logout();
|
||||
},
|
||||
},
|
||||
success: function (result){
|
||||
if(options.success && typeof(options.success) === "function")
|
||||
options.success(result);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.setItem = async function(options){
|
||||
return $.ajax({
|
||||
url: window.api_origin + "/setItem",
|
||||
type: 'POST',
|
||||
data: JSON.stringify({
|
||||
app: options.app_uid,
|
||||
key: options.key,
|
||||
value: options.value,
|
||||
}),
|
||||
async: true,
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Authorization": "Bearer "+window.auth_token
|
||||
},
|
||||
statusCode: {
|
||||
401: function () {
|
||||
window.logout();
|
||||
},
|
||||
},
|
||||
success: function (fsentry){
|
||||
if(options.success && typeof(options.success) === "function")
|
||||
options.success(fsentry)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a glob pattern to a regular expression, with optional extended or globstar matching.
|
||||
*
|
||||
* @param {string} glob - The glob pattern to convert.
|
||||
* @param {Object} [opts] - Optional options for the conversion.
|
||||
* @param {boolean} [opts.extended=false] - If true, enables extended matching with single character matching, character ranges, group matching, etc.
|
||||
* @param {boolean} [opts.globstar=false] - If true, uses globstar matching, where '*' matches zero or more path segments.
|
||||
* @param {string} [opts.flags] - Regular expression flags to include (e.g., 'i' for case-insensitive).
|
||||
* @returns {RegExp} The generated regular expression.
|
||||
* @throws {TypeError} If the provided glob pattern is not a string.
|
||||
*/
|
||||
window.globToRegExp = function (glob, opts) {
|
||||
if (typeof glob !== 'string') {
|
||||
throw new TypeError('Expected a string');
|
||||
}
|
||||
|
||||
var str = String(glob);
|
||||
|
||||
// The regexp we are building, as a string.
|
||||
var reStr = "";
|
||||
|
||||
// Whether we are matching so called "extended" globs (like bash) and should
|
||||
// support single character matching, matching ranges of characters, group
|
||||
// matching, etc.
|
||||
var extended = opts ? !!opts.extended : false;
|
||||
|
||||
// When globstar is _false_ (default), '/foo/*' is translated a regexp like
|
||||
// '^\/foo\/.*$' which will match any string beginning with '/foo/'
|
||||
// When globstar is _true_, '/foo/*' is translated to regexp like
|
||||
// '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
|
||||
// which does not have a '/' to the right of it.
|
||||
// E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
|
||||
// these will not '/foo/bar/baz', '/foo/bar/baz.txt'
|
||||
// Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
|
||||
// globstar is _false_
|
||||
var globstar = opts ? !!opts.globstar : false;
|
||||
|
||||
// If we are doing extended matching, this boolean is true when we are inside
|
||||
// a group (eg {*.html,*.js}), and false otherwise.
|
||||
var inGroup = false;
|
||||
|
||||
// RegExp flags (eg "i" ) to pass in to RegExp constructor.
|
||||
var flags = opts && typeof (opts.flags) === "string" ? opts.flags : "";
|
||||
|
||||
var c;
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
c = str[i];
|
||||
|
||||
switch (c) {
|
||||
case "/":
|
||||
case "$":
|
||||
case "^":
|
||||
case "+":
|
||||
case ".":
|
||||
case "(":
|
||||
case ")":
|
||||
case "=":
|
||||
case "!":
|
||||
case "|":
|
||||
reStr += "\\" + c;
|
||||
break;
|
||||
|
||||
case "?":
|
||||
if (extended) {
|
||||
reStr += ".";
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case "[":
|
||||
case "]":
|
||||
if (extended) {
|
||||
reStr += c;
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case "{":
|
||||
if (extended) {
|
||||
inGroup = true;
|
||||
reStr += "(";
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case "}":
|
||||
if (extended) {
|
||||
inGroup = false;
|
||||
reStr += ")";
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case ",":
|
||||
if (inGroup) {
|
||||
reStr += "|";
|
||||
break;
|
||||
}
|
||||
reStr += "\\" + c;
|
||||
break;
|
||||
|
||||
case "*":
|
||||
// Move over all consecutive "*"'s.
|
||||
// Also store the previous and next characters
|
||||
var prevChar = str[i - 1];
|
||||
var starCount = 1;
|
||||
while (str[i + 1] === "*") {
|
||||
starCount++;
|
||||
i++;
|
||||
}
|
||||
var nextChar = str[i + 1];
|
||||
|
||||
if (!globstar) {
|
||||
// globstar is disabled, so treat any number of "*" as one
|
||||
reStr += ".*";
|
||||
} else {
|
||||
// globstar is enabled, so determine if this is a globstar segment
|
||||
var isGlobstar = starCount > 1 // multiple "*"'s
|
||||
&& (prevChar === "/" || prevChar === undefined) // from the start of the segment
|
||||
&& (nextChar === "/" || nextChar === undefined) // to the end of the segment
|
||||
|
||||
if (isGlobstar) {
|
||||
// it's a globstar, so match zero or more path segments
|
||||
reStr += "((?:[^/]*(?:/|$))*)";
|
||||
i++; // move over the "/"
|
||||
} else {
|
||||
// it's not a globstar, so only match one path segment
|
||||
reStr += "([^/]*)";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
reStr += c;
|
||||
}
|
||||
}
|
||||
|
||||
// When regexp 'g' flag is specified don't
|
||||
// constrain the regular expression with ^ & $
|
||||
if (!flags || !~flags.indexOf('g')) {
|
||||
reStr = "^" + reStr + "$";
|
||||
}
|
||||
|
||||
return new RegExp(reStr, flags);
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates the provided file system entry name.
|
||||
*
|
||||
@ -488,7 +292,7 @@ window.check_fsentry_against_allowed_file_types_string =function (fsentry, allow
|
||||
}
|
||||
|
||||
// MIME types (e.g. text/plain)
|
||||
else if(window.globToRegExp(allowed_file_type).test(fsentry.type?.toLowerCase())){
|
||||
else if(globToRegExp(allowed_file_type).test(fsentry.type?.toLowerCase())){
|
||||
passes_allowed_file_type_filter = true;
|
||||
break;
|
||||
}
|
||||
@ -1014,64 +818,65 @@ window.item_icon = async (fsentry)=>{
|
||||
*/
|
||||
|
||||
window.show_save_account_notice_if_needed = function(message){
|
||||
window.getItem({
|
||||
puter.kv.get({
|
||||
key: "save_account_notice_shown",
|
||||
success: async function(value){
|
||||
if(!value && window.user?.is_temp){
|
||||
window.setItem({key: "save_account_notice_shown", value: true});
|
||||
}).then(async function(value){
|
||||
if(!value && window.user?.is_temp){
|
||||
puter.kv.set({
|
||||
key: "save_account_notice_shown",
|
||||
value: true,
|
||||
});
|
||||
// Show the notice
|
||||
setTimeout(async () => {
|
||||
const alert_resp = await UIAlert({
|
||||
message: message ?? `<strong>Congrats on storing data!</strong><p>Don't forget to save your session! You are in a temporary session. Save session to avoid accidentally losing your work.</p>`,
|
||||
body_icon: window.icons['reminder.svg'],
|
||||
buttons:[
|
||||
{
|
||||
label: i18n('save_session'),
|
||||
value: 'save-session',
|
||||
type: 'primary',
|
||||
},
|
||||
// {
|
||||
// label: 'Log into an existing account',
|
||||
// value: 'login',
|
||||
// },
|
||||
{
|
||||
label: `I'll do it later`,
|
||||
value: 'remind-later',
|
||||
},
|
||||
],
|
||||
window_options: {
|
||||
backdrop: true,
|
||||
close_on_backdrop_click: false,
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
if(alert_resp === 'remind-later'){
|
||||
// TODO
|
||||
}
|
||||
if(alert_resp === 'save-session'){
|
||||
let saved = await UIWindowSaveAccount({
|
||||
send_confirmation_code: false,
|
||||
});
|
||||
|
||||
// Show the notice
|
||||
setTimeout(async () => {
|
||||
const alert_resp = await UIAlert({
|
||||
message: message ?? `<strong>Congrats on storing data!</strong><p>Don't forget to save your session! You are in a temporary session. Save session to avoid accidentally losing your work.</p>`,
|
||||
body_icon: window.icons['reminder.svg'],
|
||||
buttons:[
|
||||
{
|
||||
label: i18n('save_session'),
|
||||
value: 'save-session',
|
||||
type: 'primary',
|
||||
},
|
||||
// {
|
||||
// label: 'Log into an existing account',
|
||||
// value: 'login',
|
||||
// },
|
||||
{
|
||||
label: `I'll do it later`,
|
||||
value: 'remind-later',
|
||||
},
|
||||
],
|
||||
}else if (alert_resp === 'login'){
|
||||
let login_result = await UIWindowLogin({
|
||||
show_signup_button: false,
|
||||
reload_on_success: true,
|
||||
send_confirmation_code: false,
|
||||
window_options: {
|
||||
show_in_taskbar: false,
|
||||
backdrop: true,
|
||||
close_on_backdrop_click: false,
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
if(alert_resp === 'remind-later'){
|
||||
// TODO
|
||||
}
|
||||
if(alert_resp === 'save-session'){
|
||||
let saved = await UIWindowSaveAccount({
|
||||
send_confirmation_code: false,
|
||||
});
|
||||
|
||||
}else if (alert_resp === 'login'){
|
||||
let login_result = await UIWindowLogin({
|
||||
show_signup_button: false,
|
||||
reload_on_success: true,
|
||||
send_confirmation_code: false,
|
||||
window_options: {
|
||||
show_in_taskbar: false,
|
||||
backdrop: true,
|
||||
close_on_backdrop_click: false,
|
||||
}
|
||||
});
|
||||
// FIXME: Report login error.
|
||||
}
|
||||
}, window.desktop_loading_fade_delay + 1000);
|
||||
}
|
||||
});
|
||||
// FIXME: Report login error.
|
||||
}
|
||||
}, window.desktop_loading_fade_delay + 1000);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
window.onpopstate = (event) => {
|
||||
|
174
src/helpers/globToRegExp.js
Normal file
174
src/helpers/globToRegExp.js
Normal file
@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Copyright (C) 2024 Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* globToRegExp is derived from: https://github.com/fitzgen/glob-to-regexp
|
||||
*
|
||||
* Copyright (c) 2013, Nick Fitzgerald All rights reserved.
|
||||
* See full license text here: https://github.com/fitzgen/glob-to-regexp#license
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Converts a glob pattern to a regular expression, with optional extended or globstar matching.
|
||||
*
|
||||
* @param {string} glob - The glob pattern to convert.
|
||||
* @param {Object} [opts] - Optional options for the conversion.
|
||||
* @param {boolean} [opts.extended=false] - If true, enables extended matching with single character matching, character ranges, group matching, etc.
|
||||
* @param {boolean} [opts.globstar=false] - If true, uses globstar matching, where '*' matches zero or more path segments.
|
||||
* @param {string} [opts.flags] - Regular expression flags to include (e.g., 'i' for case-insensitive).
|
||||
* @returns {RegExp} The generated regular expression.
|
||||
* @throws {TypeError} If the provided glob pattern is not a string.
|
||||
*/
|
||||
const globToRegExp = function (glob, opts) {
|
||||
if (typeof glob !== 'string') {
|
||||
throw new TypeError('Expected a string');
|
||||
}
|
||||
|
||||
var str = String(glob);
|
||||
|
||||
// The regexp we are building, as a string.
|
||||
var reStr = "";
|
||||
|
||||
// Whether we are matching so called "extended" globs (like bash) and should
|
||||
// support single character matching, matching ranges of characters, group
|
||||
// matching, etc.
|
||||
var extended = opts ? !!opts.extended : false;
|
||||
|
||||
// When globstar is _false_ (default), '/foo/*' is translated a regexp like
|
||||
// '^\/foo\/.*$' which will match any string beginning with '/foo/'
|
||||
// When globstar is _true_, '/foo/*' is translated to regexp like
|
||||
// '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
|
||||
// which does not have a '/' to the right of it.
|
||||
// E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
|
||||
// these will not '/foo/bar/baz', '/foo/bar/baz.txt'
|
||||
// Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
|
||||
// globstar is _false_
|
||||
var globstar = opts ? !!opts.globstar : false;
|
||||
|
||||
// If we are doing extended matching, this boolean is true when we are inside
|
||||
// a group (eg {*.html,*.js}), and false otherwise.
|
||||
var inGroup = false;
|
||||
|
||||
// RegExp flags (eg "i" ) to pass in to RegExp constructor.
|
||||
var flags = opts && typeof (opts.flags) === "string" ? opts.flags : "";
|
||||
|
||||
var c;
|
||||
for (var i = 0, len = str.length; i < len; i++) {
|
||||
c = str[i];
|
||||
|
||||
switch (c) {
|
||||
case "/":
|
||||
case "$":
|
||||
case "^":
|
||||
case "+":
|
||||
case ".":
|
||||
case "(":
|
||||
case ")":
|
||||
case "=":
|
||||
case "!":
|
||||
case "|":
|
||||
reStr += "\\" + c;
|
||||
break;
|
||||
|
||||
case "?":
|
||||
if (extended) {
|
||||
reStr += ".";
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case "[":
|
||||
case "]":
|
||||
if (extended) {
|
||||
reStr += c;
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case "{":
|
||||
if (extended) {
|
||||
inGroup = true;
|
||||
reStr += "(";
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case "}":
|
||||
if (extended) {
|
||||
inGroup = false;
|
||||
reStr += ")";
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
case ",":
|
||||
if (inGroup) {
|
||||
reStr += "|";
|
||||
break;
|
||||
}
|
||||
reStr += "\\" + c;
|
||||
break;
|
||||
|
||||
case "*":
|
||||
// Move over all consecutive "*"'s.
|
||||
// Also store the previous and next characters
|
||||
var prevChar = str[i - 1];
|
||||
var starCount = 1;
|
||||
while (str[i + 1] === "*") {
|
||||
starCount++;
|
||||
i++;
|
||||
}
|
||||
var nextChar = str[i + 1];
|
||||
|
||||
if (!globstar) {
|
||||
// globstar is disabled, so treat any number of "*" as one
|
||||
reStr += ".*";
|
||||
} else {
|
||||
// globstar is enabled, so determine if this is a globstar segment
|
||||
var isGlobstar = starCount > 1 // multiple "*"'s
|
||||
&& (prevChar === "/" || prevChar === undefined) // from the start of the segment
|
||||
&& (nextChar === "/" || nextChar === undefined) // to the end of the segment
|
||||
|
||||
if (isGlobstar) {
|
||||
// it's a globstar, so match zero or more path segments
|
||||
reStr += "((?:[^/]*(?:/|$))*)";
|
||||
i++; // move over the "/"
|
||||
} else {
|
||||
// it's not a globstar, so only match one path segment
|
||||
reStr += "([^/]*)";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
reStr += c;
|
||||
}
|
||||
}
|
||||
|
||||
// When regexp 'g' flag is specified don't
|
||||
// constrain the regular expression with ^ & $
|
||||
if (!flags || !~flags.indexOf('g')) {
|
||||
reStr = "^" + reStr + "$";
|
||||
}
|
||||
|
||||
return new RegExp(reStr, flags);
|
||||
};
|
||||
|
||||
|
||||
export default globToRegExp;
|
Loading…
Reference in New Issue
Block a user