forked from FINAKON/HelpProject
1. Initial Commit - a boiler plate code and POC to realize the concept of context sensitive help 2. Frontend code written in ReactJS 3. Backend code written in Java, Spring Boot Framework 4. Frontend Start: pre-requisites : node, npm npm run dev ==> to start the frontend vite server 5. Backend Start: pre-requisites : java, mvn mvn spring-boot:run ==> to start the backend server 6. Visit http://localhost:5173/ for basic demo of help, press F1 in textboxes 7. Visit http://localhost:5173/editor and enter "admin123" to add/modify texts. Happy Coding !!! Thank you, Bhargava.
255 lines
6.6 KiB
JavaScript
255 lines
6.6 KiB
JavaScript
//#region src/utils.ts
|
|
const postfixRE = /[?#].*$/;
|
|
function cleanUrl(url) {
|
|
return url.replace(postfixRE, "");
|
|
}
|
|
function extractQueryWithoutFragment(url) {
|
|
const questionMarkIndex = url.indexOf("?");
|
|
if (questionMarkIndex === -1) return "";
|
|
const fragmentIndex = url.indexOf("#", questionMarkIndex);
|
|
if (fragmentIndex === -1) return url.substring(questionMarkIndex);
|
|
else return url.substring(questionMarkIndex, fragmentIndex);
|
|
}
|
|
|
|
//#endregion
|
|
//#region src/composable-filters.ts
|
|
var And = class {
|
|
kind;
|
|
args;
|
|
constructor(...args) {
|
|
if (args.length === 0) throw new Error("`And` expects at least one operand");
|
|
this.args = args;
|
|
this.kind = "and";
|
|
}
|
|
};
|
|
var Or = class {
|
|
kind;
|
|
args;
|
|
constructor(...args) {
|
|
if (args.length === 0) throw new Error("`Or` expects at least one operand");
|
|
this.args = args;
|
|
this.kind = "or";
|
|
}
|
|
};
|
|
var Not = class {
|
|
kind;
|
|
expr;
|
|
constructor(expr) {
|
|
this.expr = expr;
|
|
this.kind = "not";
|
|
}
|
|
};
|
|
var Id = class {
|
|
kind;
|
|
pattern;
|
|
params;
|
|
constructor(pattern, params) {
|
|
this.pattern = pattern;
|
|
this.kind = "id";
|
|
this.params = params ?? { cleanUrl: false };
|
|
}
|
|
};
|
|
var ModuleType = class {
|
|
kind;
|
|
pattern;
|
|
constructor(pattern) {
|
|
this.pattern = pattern;
|
|
this.kind = "moduleType";
|
|
}
|
|
};
|
|
var Code = class {
|
|
kind;
|
|
pattern;
|
|
constructor(expr) {
|
|
this.pattern = expr;
|
|
this.kind = "code";
|
|
}
|
|
};
|
|
var Query = class {
|
|
kind;
|
|
key;
|
|
pattern;
|
|
constructor(key, pattern) {
|
|
this.pattern = pattern;
|
|
this.key = key;
|
|
this.kind = "query";
|
|
}
|
|
};
|
|
var Include = class {
|
|
kind;
|
|
expr;
|
|
constructor(expr) {
|
|
this.expr = expr;
|
|
this.kind = "include";
|
|
}
|
|
};
|
|
var Exclude = class {
|
|
kind;
|
|
expr;
|
|
constructor(expr) {
|
|
this.expr = expr;
|
|
this.kind = "exclude";
|
|
}
|
|
};
|
|
function and(...args) {
|
|
return new And(...args);
|
|
}
|
|
function or(...args) {
|
|
return new Or(...args);
|
|
}
|
|
function not(expr) {
|
|
return new Not(expr);
|
|
}
|
|
function id(pattern, params) {
|
|
return new Id(pattern, params);
|
|
}
|
|
function moduleType(pattern) {
|
|
return new ModuleType(pattern);
|
|
}
|
|
function code(pattern) {
|
|
return new Code(pattern);
|
|
}
|
|
function query(key, pattern) {
|
|
return new Query(key, pattern);
|
|
}
|
|
function include(expr) {
|
|
return new Include(expr);
|
|
}
|
|
function exclude(expr) {
|
|
return new Exclude(expr);
|
|
}
|
|
/**
|
|
* convert a queryObject to FilterExpression like
|
|
* ```js
|
|
* and(query(k1, v1), query(k2, v2))
|
|
* ```
|
|
* @param queryFilterObject The query filter object needs to be matched.
|
|
* @returns a `And` FilterExpression
|
|
*/
|
|
function queries(queryFilter) {
|
|
let arr = Object.entries(queryFilter).map(([key, value]) => {
|
|
return new Query(key, value);
|
|
});
|
|
return and(...arr);
|
|
}
|
|
function interpreter(exprs, code$1, id$1, moduleType$1) {
|
|
let arr = [];
|
|
if (Array.isArray(exprs)) arr = exprs;
|
|
else arr = [exprs];
|
|
return interpreterImpl(arr, code$1, id$1, moduleType$1);
|
|
}
|
|
function interpreterImpl(expr, code$1, id$1, moduleType$1, ctx = {}) {
|
|
let hasInclude = false;
|
|
for (const e of expr) switch (e.kind) {
|
|
case "include": {
|
|
hasInclude = true;
|
|
if (exprInterpreter(e.expr, code$1, id$1, moduleType$1, ctx)) return true;
|
|
break;
|
|
}
|
|
case "exclude": {
|
|
if (exprInterpreter(e.expr, code$1, id$1, moduleType$1)) return false;
|
|
break;
|
|
}
|
|
}
|
|
return !hasInclude;
|
|
}
|
|
function exprInterpreter(expr, code$1, id$1, moduleType$1, ctx = {}) {
|
|
switch (expr.kind) {
|
|
case "and": return expr.args.every((e) => exprInterpreter(e, code$1, id$1, moduleType$1, ctx));
|
|
case "or": return expr.args.some((e) => exprInterpreter(e, code$1, id$1, moduleType$1, ctx));
|
|
case "not": return !exprInterpreter(expr.expr, code$1, id$1, moduleType$1, ctx);
|
|
case "id": {
|
|
if (id$1 === void 0) throw new Error("`id` is required for `id` expression");
|
|
if (expr.params.cleanUrl) id$1 = cleanUrl(id$1);
|
|
return typeof expr.pattern === "string" ? id$1 === expr.pattern : expr.pattern.test(id$1);
|
|
}
|
|
case "moduleType": {
|
|
if (moduleType$1 === void 0) throw new Error("`moduleType` is required for `moduleType` expression");
|
|
return moduleType$1 === expr.pattern;
|
|
}
|
|
case "code": {
|
|
if (code$1 === void 0) throw new Error("`code` is required for `code` expression");
|
|
return typeof expr.pattern === "string" ? code$1.includes(expr.pattern) : expr.pattern.test(code$1);
|
|
}
|
|
case "query": {
|
|
if (id$1 === void 0) throw new Error("`id` is required for `Query` expression");
|
|
if (!ctx.urlSearchParamsCache) {
|
|
let queryString = extractQueryWithoutFragment(id$1);
|
|
ctx.urlSearchParamsCache = new URLSearchParams(queryString);
|
|
}
|
|
let urlParams = ctx.urlSearchParamsCache;
|
|
if (typeof expr.pattern === "boolean") if (expr.pattern) return urlParams.has(expr.key);
|
|
else return !urlParams.has(expr.key);
|
|
else if (typeof expr.pattern === "string") return urlParams.get(expr.key) === expr.pattern;
|
|
else return expr.pattern.test(urlParams.get(expr.key) ?? "");
|
|
}
|
|
default: throw new Error(`Expression ${JSON.stringify(expr)} is not expected.`);
|
|
}
|
|
}
|
|
|
|
//#endregion
|
|
//#region src/simple-filters.ts
|
|
/**
|
|
* Constructs a RegExp that matches the exact string specified.
|
|
*
|
|
* This is useful for plugin hook filters.
|
|
*
|
|
* @param str the string to match.
|
|
* @param flags flags for the RegExp.
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* import { exactRegex } from '@rolldown/pluginutils';
|
|
* const plugin = {
|
|
* name: 'plugin',
|
|
* resolveId: {
|
|
* filter: { id: exactRegex('foo') },
|
|
* handler(id) {} // will only be called for `foo`
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
function exactRegex(str, flags) {
|
|
return new RegExp(`^${escapeRegex(str)}$`, flags);
|
|
}
|
|
/**
|
|
* Constructs a RegExp that matches a value that has the specified prefix.
|
|
*
|
|
* This is useful for plugin hook filters.
|
|
*
|
|
* @param str the string to match.
|
|
* @param flags flags for the RegExp.
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* import { prefixRegex } from '@rolldown/pluginutils';
|
|
* const plugin = {
|
|
* name: 'plugin',
|
|
* resolveId: {
|
|
* filter: { id: prefixRegex('foo') },
|
|
* handler(id) {} // will only be called for IDs starting with `foo`
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
function prefixRegex(str, flags) {
|
|
return new RegExp(`^${escapeRegex(str)}`, flags);
|
|
}
|
|
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g;
|
|
function escapeRegex(str) {
|
|
return str.replace(escapeRegexRE, "\\$&");
|
|
}
|
|
function makeIdFiltersToMatchWithQuery(input) {
|
|
if (!Array.isArray(input)) return makeIdFilterToMatchWithQuery(input);
|
|
return input.map((i) => makeIdFilterToMatchWithQuery(i));
|
|
}
|
|
function makeIdFilterToMatchWithQuery(input) {
|
|
if (typeof input === "string") return `${input}{?*,}`;
|
|
return makeRegexIdFilterToMatchWithQuery(input);
|
|
}
|
|
function makeRegexIdFilterToMatchWithQuery(input) {
|
|
return new RegExp(input.source.replace(/(?<!\\)\$/g, "(?:\\?.*)?$"), input.flags);
|
|
}
|
|
|
|
//#endregion
|
|
export { and, code, exactRegex, exclude, exprInterpreter, id, include, interpreter, interpreterImpl, makeIdFiltersToMatchWithQuery, moduleType, not, or, prefixRegex, queries, query }; |