@vef-framework/core 1.0.128 → 1.0.130
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/cjs/api/api-client.cjs +1 -546
- package/cjs/api/api-context.cjs +1 -97
- package/cjs/api/index.cjs +1 -16
- package/cjs/api/query-client.cjs +1 -32
- package/cjs/api/request-client.cjs +1 -252
- package/cjs/auth/auth-context.cjs +1 -38
- package/cjs/auth/index.cjs +1 -8
- package/cjs/expr/compiler.cjs +1 -301
- package/cjs/expr/helpers.cjs +1 -92
- package/cjs/index.cjs +1 -23
- package/cjs/middleware/dispatcher.cjs +1 -32
- package/esm/api/api-client.js +1 -543
- package/esm/api/api-context.js +1 -94
- package/esm/api/index.js +1 -5
- package/esm/api/query-client.js +1 -30
- package/esm/api/request-client.js +1 -249
- package/esm/auth/auth-context.js +1 -35
- package/esm/auth/index.js +1 -3
- package/esm/expr/compiler.js +1 -299
- package/esm/expr/helpers.js +1 -86
- package/esm/index.js +1 -9
- package/esm/middleware/dispatcher.js +1 -28
- package/package.json +2 -2
|
@@ -1,250 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import
|
|
3
|
-
import axios, { CanceledError } from 'axios';
|
|
4
|
-
import qs from 'qs';
|
|
5
|
-
|
|
6
|
-
"use strict";
|
|
7
|
-
var __typeError = (msg) => {
|
|
8
|
-
throw TypeError(msg);
|
|
9
|
-
};
|
|
10
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
11
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
12
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
14
|
-
var _axiosInstance;
|
|
15
|
-
const pathParamRegex = /\{\w+\}/;
|
|
16
|
-
class RequestClient {
|
|
17
|
-
constructor(options) {
|
|
18
|
-
this.options = options;
|
|
19
|
-
/**
|
|
20
|
-
* The axios instance.
|
|
21
|
-
*/
|
|
22
|
-
__privateAdd(this, _axiosInstance);
|
|
23
|
-
const {
|
|
24
|
-
baseUrl,
|
|
25
|
-
timeout,
|
|
26
|
-
getAccessToken,
|
|
27
|
-
successCode = 0,
|
|
28
|
-
unauthorizedCode = 1e3,
|
|
29
|
-
accessDeniedCode = 1002,
|
|
30
|
-
tokenExpiredCode = 1001,
|
|
31
|
-
onUnauthorized,
|
|
32
|
-
onAccessDenied
|
|
33
|
-
} = options;
|
|
34
|
-
__privateSet(this, _axiosInstance, axios.create({
|
|
35
|
-
baseURL: baseUrl,
|
|
36
|
-
timeout: timeout ?? 1e3 * 30,
|
|
37
|
-
headers: {
|
|
38
|
-
"Content-Type": "application/json"
|
|
39
|
-
},
|
|
40
|
-
paramsSerializer: (params) => qs.stringify(
|
|
41
|
-
params,
|
|
42
|
-
{
|
|
43
|
-
arrayFormat: "repeat",
|
|
44
|
-
skipNulls: true,
|
|
45
|
-
charset: "utf-8"
|
|
46
|
-
}
|
|
47
|
-
),
|
|
48
|
-
responseType: "json",
|
|
49
|
-
validateStatus: () => true
|
|
50
|
-
}));
|
|
51
|
-
__privateGet(this, _axiosInstance).interceptors.request.use((config) => {
|
|
52
|
-
const token = getAccessToken?.();
|
|
53
|
-
if (token) {
|
|
54
|
-
config.headers.Authorization = `Bearer ${token}`;
|
|
55
|
-
}
|
|
56
|
-
const { url } = config;
|
|
57
|
-
if (url && pathParamRegex.test(url)) {
|
|
58
|
-
config.url = url.replace(pathParamRegex, (_, key) => {
|
|
59
|
-
const value = config.params?.[key];
|
|
60
|
-
if (isNullish(value)) {
|
|
61
|
-
throw new Error(`Path parameter ${key} is nil`);
|
|
62
|
-
}
|
|
63
|
-
return value;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return config;
|
|
67
|
-
});
|
|
68
|
-
__privateGet(this, _axiosInstance).interceptors.response.use(
|
|
69
|
-
async (response) => {
|
|
70
|
-
const { code, message } = response.data;
|
|
71
|
-
if (code === successCode) {
|
|
72
|
-
return response;
|
|
73
|
-
} else if (code === unauthorizedCode) {
|
|
74
|
-
await onUnauthorized?.();
|
|
75
|
-
} else if (code === tokenExpiredCode) {
|
|
76
|
-
showInfoMessage("登录已失效");
|
|
77
|
-
await onUnauthorized?.();
|
|
78
|
-
} else if (code === accessDeniedCode) {
|
|
79
|
-
showWarningMessage(`${message},请联系管理员为您开通`);
|
|
80
|
-
await onAccessDenied?.();
|
|
81
|
-
} else {
|
|
82
|
-
showWarningMessage(message);
|
|
83
|
-
}
|
|
84
|
-
throw new VefError(code, message);
|
|
85
|
-
},
|
|
86
|
-
(error) => {
|
|
87
|
-
if (error instanceof CanceledError) {
|
|
88
|
-
return Promise.reject(error);
|
|
89
|
-
}
|
|
90
|
-
const { response, message } = error;
|
|
91
|
-
if (response?.data) {
|
|
92
|
-
const errorMessage = `处理请求响应信息异常:${message ?? "无"}`;
|
|
93
|
-
return Promise.reject(new VefError(response.status, errorMessage));
|
|
94
|
-
} else {
|
|
95
|
-
let errorMessage = message ?? (isString(error) ? error : "");
|
|
96
|
-
if (errorMessage === "Network Error") {
|
|
97
|
-
errorMessage = "接口连接异常可能原因:网络不通或存在跨域问题。";
|
|
98
|
-
} else if (errorMessage.includes("timeout")) {
|
|
99
|
-
errorMessage = "接口请求超时";
|
|
100
|
-
} else if (errorMessage.includes("Request failed with status code")) {
|
|
101
|
-
const code = message.substring(message.length - 3);
|
|
102
|
-
errorMessage = `接口状态码异常:${code}`;
|
|
103
|
-
} else {
|
|
104
|
-
errorMessage = "接口未知异常";
|
|
105
|
-
}
|
|
106
|
-
showErrorMessage(errorMessage);
|
|
107
|
-
return Promise.reject(new VefError(-1, errorMessage));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Perform a GET request.
|
|
114
|
-
*
|
|
115
|
-
* @param url - The url.
|
|
116
|
-
* @param options - The request options.
|
|
117
|
-
* @returns The response data promise.
|
|
118
|
-
*/
|
|
119
|
-
async get(url, options) {
|
|
120
|
-
const response = await __privateGet(this, _axiosInstance).get(url, {
|
|
121
|
-
params: options?.params,
|
|
122
|
-
headers: options?.headers,
|
|
123
|
-
signal: options?.signal
|
|
124
|
-
});
|
|
125
|
-
return response.data;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Perform a POST request.
|
|
129
|
-
*
|
|
130
|
-
* @param url - The url.
|
|
131
|
-
* @param data - The request data.
|
|
132
|
-
* @param options - The request options.
|
|
133
|
-
* @returns The response data promise.
|
|
134
|
-
*/
|
|
135
|
-
async post(url, data, options) {
|
|
136
|
-
const response = await __privateGet(this, _axiosInstance).post(url, data, {
|
|
137
|
-
params: options?.params,
|
|
138
|
-
headers: options?.headers,
|
|
139
|
-
signal: options?.signal
|
|
140
|
-
});
|
|
141
|
-
return response.data;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Perform a PUT request.
|
|
145
|
-
*
|
|
146
|
-
* @param url - The url.
|
|
147
|
-
* @param data - The request data.
|
|
148
|
-
* @param options - The request options.
|
|
149
|
-
* @returns The response data promise.
|
|
150
|
-
*/
|
|
151
|
-
async put(url, data, options) {
|
|
152
|
-
const response = await __privateGet(this, _axiosInstance).put(url, data, {
|
|
153
|
-
params: options?.params,
|
|
154
|
-
headers: options?.headers,
|
|
155
|
-
signal: options?.signal
|
|
156
|
-
});
|
|
157
|
-
return response.data;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Perform a DELETE request.
|
|
161
|
-
*
|
|
162
|
-
* @param url - The url.
|
|
163
|
-
* @param options - The request options.
|
|
164
|
-
* @returns The response data promise.
|
|
165
|
-
*/
|
|
166
|
-
async delete(url, options) {
|
|
167
|
-
const response = await __privateGet(this, _axiosInstance).delete(url, {
|
|
168
|
-
params: options?.params,
|
|
169
|
-
headers: options?.headers,
|
|
170
|
-
signal: options?.signal
|
|
171
|
-
});
|
|
172
|
-
return response.data;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Perform a file upload request.
|
|
176
|
-
*
|
|
177
|
-
* @param url - The url.
|
|
178
|
-
* @param data - The file data.
|
|
179
|
-
* @param options - The request options.
|
|
180
|
-
* @returns The response data promise.
|
|
181
|
-
*/
|
|
182
|
-
async upload(url, data, options) {
|
|
183
|
-
const response = await __privateGet(this, _axiosInstance).postForm(
|
|
184
|
-
url,
|
|
185
|
-
data,
|
|
186
|
-
{
|
|
187
|
-
params: options?.params,
|
|
188
|
-
headers: options?.headers,
|
|
189
|
-
signal: options?.signal,
|
|
190
|
-
onUploadProgress: isFunction(options?.onProgress) ? (progressEvent) => {
|
|
191
|
-
const total = progressEvent.lengthComputable ? progressEvent.total ?? 0 : 0;
|
|
192
|
-
const { loaded } = progressEvent;
|
|
193
|
-
const percent = Math.round(loaded / total * 100);
|
|
194
|
-
options.onProgress?.(percent);
|
|
195
|
-
} : void 0
|
|
196
|
-
}
|
|
197
|
-
);
|
|
198
|
-
return response.data;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Perform a file download request.
|
|
202
|
-
*
|
|
203
|
-
* @param url - The url.
|
|
204
|
-
* @param options - The request options.
|
|
205
|
-
*/
|
|
206
|
-
async download(url, options) {
|
|
207
|
-
const { data, headers } = await __privateGet(this, _axiosInstance).get(
|
|
208
|
-
url,
|
|
209
|
-
{
|
|
210
|
-
params: options?.params,
|
|
211
|
-
headers: options?.headers,
|
|
212
|
-
responseType: "blob",
|
|
213
|
-
onDownloadProgress: isFunction(options?.onProgress) ? (progressEvent) => {
|
|
214
|
-
const total = progressEvent.lengthComputable ? progressEvent.total ?? 0 : 0;
|
|
215
|
-
const { loaded } = progressEvent;
|
|
216
|
-
const percent = Math.round(loaded / total * 100);
|
|
217
|
-
options.onProgress?.(percent);
|
|
218
|
-
} : void 0
|
|
219
|
-
}
|
|
220
|
-
);
|
|
221
|
-
let response = null;
|
|
222
|
-
try {
|
|
223
|
-
response = JSON.parse(await data.text());
|
|
224
|
-
} catch {
|
|
225
|
-
}
|
|
226
|
-
if (response && response.code !== 0) {
|
|
227
|
-
throw new VefError(response.code, response.message);
|
|
228
|
-
}
|
|
229
|
-
const contentDisposition = headers.get("content-disposition");
|
|
230
|
-
if (isString(contentDisposition)) {
|
|
231
|
-
const fileNameRegex = /filename[^;=\n]*=(?<name>(?<quote>['"]).*?\2|[^;\n]*)/;
|
|
232
|
-
const matches = fileNameRegex.exec(contentDisposition);
|
|
233
|
-
if (matches && matches.groups) {
|
|
234
|
-
const { name } = matches.groups;
|
|
235
|
-
const fileName = decodeURIComponent(name);
|
|
236
|
-
const a = document.createElement("a");
|
|
237
|
-
a.href = URL.createObjectURL(data);
|
|
238
|
-
a.download = isFunction(options?.fileName) ? options.fileName(fileName) : options?.fileName ?? fileName;
|
|
239
|
-
a.click();
|
|
240
|
-
URL.revokeObjectURL(a.href);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
_axiosInstance = new WeakMap();
|
|
246
|
-
function createRequestClient(options) {
|
|
247
|
-
return Object.freeze(new RequestClient(options));
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export { RequestClient, createRequestClient };
|
|
2
|
+
import{isNullish as k,VefError as f,showInfoMessage as N,showWarningMessage as b,isString as v,showErrorMessage as q,isFunction as y}from"@vef-framework/shared";import M,{CanceledError as T}from"axios";import x from"qs";var E=s=>{throw TypeError(s)},P=(s,a,e)=>a.has(s)||E("Cannot "+e),u=(s,a,e)=>(P(s,a,"read from private field"),e?e.call(s):a.get(s)),z=(s,a,e)=>a.has(s)?E("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(s):a.set(s,e),L=(s,a,e,t)=>(P(s,a,"write to private field"),t?t.call(s,e):a.set(s,e),e),d;const U=/\{\w+\}/;class j{constructor(a){this.options=a,z(this,d);const{baseUrl:e,timeout:t,getAccessToken:h,successCode:l=0,unauthorizedCode:g=1e3,accessDeniedCode:i=1002,tokenExpiredCode:w=1001,onUnauthorized:m,onAccessDenied:p}=a;L(this,d,M.create({baseURL:e,timeout:t??1e3*30,headers:{"Content-Type":"application/json"},paramsSerializer:r=>x.stringify(r,{arrayFormat:"repeat",skipNulls:!0,charset:"utf-8"}),responseType:"json",validateStatus:()=>!0})),u(this,d).interceptors.request.use(r=>{const c=h?.();c&&(r.headers.Authorization=`Bearer ${c}`);const{url:o}=r;return o&&U.test(o)&&(r.url=o.replace(U,(n,C)=>{const R=r.params?.[C];if(k(R))throw new Error(`Path parameter ${C} is nil`);return R})),r}),u(this,d).interceptors.response.use(async r=>{const{code:c,message:o}=r.data;if(c===l)return r;throw c===g?await m?.():c===w?(N("登录已失效"),await m?.()):c===i?(b(`${o},请联系管理员为您开通`),await p?.()):b(o),new f(c,o)},r=>{if(r instanceof T)return Promise.reject(r);const{response:c,message:o}=r;if(c?.data){const n=`处理请求响应信息异常:${o??"无"}`;return Promise.reject(new f(c.status,n))}else{let n=o??(v(r)?r:"");return n==="Network Error"?n="接口连接异常可能原因:网络不通或存在跨域问题。":n.includes("timeout")?n="接口请求超时":n.includes("Request failed with status code")?n=`接口状态码异常:${o.substring(o.length-3)}`:n="接口未知异常",q(n),Promise.reject(new f(-1,n))}})}async get(a,e){return(await u(this,d).get(a,{params:e?.params,headers:e?.headers,signal:e?.signal})).data}async post(a,e,t){return(await u(this,d).post(a,e,{params:t?.params,headers:t?.headers,signal:t?.signal})).data}async put(a,e,t){return(await u(this,d).put(a,e,{params:t?.params,headers:t?.headers,signal:t?.signal})).data}async delete(a,e){return(await u(this,d).delete(a,{params:e?.params,headers:e?.headers,signal:e?.signal})).data}async upload(a,e,t){return(await u(this,d).postForm(a,e,{params:t?.params,headers:t?.headers,signal:t?.signal,onUploadProgress:y(t?.onProgress)?h=>{const l=h.lengthComputable?h.total??0:0,{loaded:g}=h,i=Math.round(g/l*100);t.onProgress?.(i)}:void 0})).data}async download(a,e){const{data:t,headers:h}=await u(this,d).get(a,{params:e?.params,headers:e?.headers,responseType:"blob",onDownloadProgress:y(e?.onProgress)?i=>{const w=i.lengthComputable?i.total??0:0,{loaded:m}=i,p=Math.round(m/w*100);e.onProgress?.(p)}:void 0});let l=null;try{l=JSON.parse(await t.text())}catch{}if(l&&l.code!==0)throw new f(l.code,l.message);const g=h.get("content-disposition");if(v(g)){const i=/filename[^;=\n]*=(?<name>(?<quote>['"]).*?\2|[^;\n]*)/.exec(g);if(i&&i.groups){const{name:w}=i.groups,m=decodeURIComponent(w),p=document.createElement("a");p.href=URL.createObjectURL(t),p.download=y(e?.fileName)?e.fileName(m):e?.fileName??m,p.click(),URL.revokeObjectURL(p.href)}}}}d=new WeakMap;function O(s){return Object.freeze(new j(s))}export{j as RequestClient,O as createRequestClient};
|
package/esm/auth/auth-context.js
CHANGED
|
@@ -1,36 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import
|
|
3
|
-
import { createContext, useMemo, createElement, useContext } from 'react';
|
|
4
|
-
|
|
5
|
-
"use strict";
|
|
6
|
-
const Context = createContext(null);
|
|
7
|
-
const AuthContextProvider = ({
|
|
8
|
-
permissionChecker,
|
|
9
|
-
children
|
|
10
|
-
}) => {
|
|
11
|
-
const authContext = useMemo(() => ({
|
|
12
|
-
checkPermission: (token) => {
|
|
13
|
-
if (!permissionChecker) {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
if (isString(token)) {
|
|
17
|
-
return permissionChecker(token);
|
|
18
|
-
}
|
|
19
|
-
return permissionChecker(token.key);
|
|
20
|
-
}
|
|
21
|
-
}), [permissionChecker]);
|
|
22
|
-
return createElement(
|
|
23
|
-
Context.Provider,
|
|
24
|
-
{ value: authContext },
|
|
25
|
-
children
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
function useAuthContext() {
|
|
29
|
-
const context = useContext(Context);
|
|
30
|
-
if (context === null) {
|
|
31
|
-
throw new VefError(-1, "useAuthContext must be used within a AuthContextProvider");
|
|
32
|
-
}
|
|
33
|
-
return context;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export { AuthContextProvider, useAuthContext };
|
|
2
|
+
import{isString as s,VefError as i}from"@vef-framework/shared";import{createContext as u,useMemo as c,createElement as h,useContext as m}from"react";const r=u(null),C=({permissionChecker:e,children:n})=>{const o=c(()=>({checkPermission:t=>e?s(t)?e(t):e(t.key):!0}),[e]);return h(r.Provider,{value:o},n)};function a(){const e=m(r);if(e===null)throw new i(-1,"useAuthContext must be used within a AuthContextProvider");return e}export{C as AuthContextProvider,a as useAuthContext};
|
package/esm/auth/index.js
CHANGED
package/esm/expr/compiler.js
CHANGED
|
@@ -1,300 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
"use strict";
|
|
5
|
-
function compile(expr) {
|
|
6
|
-
let provideTokens;
|
|
7
|
-
const requirements = /* @__PURE__ */ new Set();
|
|
8
|
-
const x = function expand(operand, tokens) {
|
|
9
|
-
return typeof operand === "function" ? operand(tokens) : operand;
|
|
10
|
-
};
|
|
11
|
-
const operatorRegistry = [
|
|
12
|
-
{
|
|
13
|
-
"&&": (l, r, t) => x(l, t) && x(r, t),
|
|
14
|
-
"||": (l, r, t) => x(l, t) || x(r, t)
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"===": (l, r, t) => !!(x(l, t) === x(r, t)),
|
|
18
|
-
"!==": (l, r, t) => !!(x(l, t) !== x(r, t)),
|
|
19
|
-
// eslint-disable-next-line eqeqeq
|
|
20
|
-
"==": (l, r, t) => !!(x(l, t) == x(r, t)),
|
|
21
|
-
// eslint-disable-next-line eqeqeq
|
|
22
|
-
"!=": (l, r, t) => !!(x(l, t) != x(r, t)),
|
|
23
|
-
">=": (l, r, t) => !!(x(l, t) >= x(r, t)),
|
|
24
|
-
"<=": (l, r, t) => !!(x(l, t) <= x(r, t)),
|
|
25
|
-
">": (l, r, t) => !!(x(l, t) > x(r, t)),
|
|
26
|
-
"<": (l, r, t) => !!(x(l, t) < x(r, t))
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"+": (l, r, t) => x(l, t) + x(r, t),
|
|
30
|
-
"-": (l, r, t) => x(l, t) - x(r, t)
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"*": (l, r, t) => x(l, t) * x(r, t),
|
|
34
|
-
"/": (l, r, t) => x(l, t) / x(r, t),
|
|
35
|
-
"%": (l, r, t) => x(l, t) % x(r, t)
|
|
36
|
-
}
|
|
37
|
-
];
|
|
38
|
-
const operatorSymbols = operatorRegistry.reduce((s, g) => s.concat(Object.keys(g)), []);
|
|
39
|
-
const operatorChars = new Set(operatorSymbols.map((key) => key.charAt(0)));
|
|
40
|
-
function getOp(symbols, char, p, expression) {
|
|
41
|
-
const candidates = symbols.filter((s) => s.startsWith(char));
|
|
42
|
-
if (!candidates.length) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
return candidates.find((symbol) => {
|
|
46
|
-
if (expression.length >= p + symbol.length) {
|
|
47
|
-
const nextChars = expression.substring(p, p + symbol.length);
|
|
48
|
-
if (nextChars === symbol) {
|
|
49
|
-
return symbol;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
function getStep(p, expression, direction = 1) {
|
|
56
|
-
let next = direction ? expression.substring(p + 1).trim() : expression.substring(0, p).trim();
|
|
57
|
-
if (!next.length) {
|
|
58
|
-
return -1;
|
|
59
|
-
}
|
|
60
|
-
if (!direction) {
|
|
61
|
-
const reversed = next.split("").reverse();
|
|
62
|
-
const start = reversed.findIndex((char2) => operatorChars.has(char2));
|
|
63
|
-
next = reversed.slice(start).join("");
|
|
64
|
-
}
|
|
65
|
-
const [char] = next;
|
|
66
|
-
return operatorRegistry.findIndex((operators) => {
|
|
67
|
-
const symbols = Object.keys(operators);
|
|
68
|
-
return !!getOp(symbols, char, 0, next);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
function getTail(pos, expression) {
|
|
72
|
-
let tail = "";
|
|
73
|
-
const { length } = expression;
|
|
74
|
-
let depth = 0;
|
|
75
|
-
for (let p = pos; p < length; p++) {
|
|
76
|
-
const char = expression.charAt(p);
|
|
77
|
-
if (char === "(") {
|
|
78
|
-
depth++;
|
|
79
|
-
} else if (char === ")") {
|
|
80
|
-
depth--;
|
|
81
|
-
} else if (depth === 0 && char === " ") {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (depth === 0 && getOp(operatorSymbols, char, p, expression)) {
|
|
85
|
-
return [tail, p - 1];
|
|
86
|
-
} else {
|
|
87
|
-
tail += char;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return [tail, expression.length - 1];
|
|
91
|
-
}
|
|
92
|
-
function compileExpr(expression, step = 0) {
|
|
93
|
-
const operators = operatorRegistry[step];
|
|
94
|
-
const { length } = expression;
|
|
95
|
-
const symbols = Object.keys(operators);
|
|
96
|
-
let depth = 0;
|
|
97
|
-
let quote = false;
|
|
98
|
-
let op = null;
|
|
99
|
-
let operand = "";
|
|
100
|
-
let left = null;
|
|
101
|
-
let operation;
|
|
102
|
-
let lastChar;
|
|
103
|
-
let char = "";
|
|
104
|
-
let parenthetical = "";
|
|
105
|
-
let parenQuote = "";
|
|
106
|
-
let startP = 0;
|
|
107
|
-
const addTo = (depth2, char2) => {
|
|
108
|
-
if (depth2) {
|
|
109
|
-
parenthetical += char2;
|
|
110
|
-
} else {
|
|
111
|
-
operand += char2;
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
for (let p = 0; p < length; p++) {
|
|
115
|
-
lastChar = char;
|
|
116
|
-
char = expression.charAt(p);
|
|
117
|
-
if ((char === "'" || char === '"') && lastChar !== "\\" && (depth === 0 && !quote || depth && !parenQuote)) {
|
|
118
|
-
if (depth) {
|
|
119
|
-
parenQuote = char;
|
|
120
|
-
} else {
|
|
121
|
-
quote = char;
|
|
122
|
-
}
|
|
123
|
-
addTo(depth, char);
|
|
124
|
-
continue;
|
|
125
|
-
} else if (quote && (char !== quote || lastChar === "\\") || parenQuote && (char !== parenQuote || lastChar === "\\")) {
|
|
126
|
-
addTo(depth, char);
|
|
127
|
-
continue;
|
|
128
|
-
} else if (quote === char) {
|
|
129
|
-
quote = false;
|
|
130
|
-
addTo(depth, char);
|
|
131
|
-
continue;
|
|
132
|
-
} else if (parenQuote === char) {
|
|
133
|
-
parenQuote = false;
|
|
134
|
-
addTo(depth, char);
|
|
135
|
-
continue;
|
|
136
|
-
} else if (char === " ") {
|
|
137
|
-
continue;
|
|
138
|
-
} else if (char === "(") {
|
|
139
|
-
if (depth === 0) {
|
|
140
|
-
startP = p;
|
|
141
|
-
} else {
|
|
142
|
-
parenthetical += char;
|
|
143
|
-
}
|
|
144
|
-
depth++;
|
|
145
|
-
} else if (char === ")") {
|
|
146
|
-
depth--;
|
|
147
|
-
if (depth === 0) {
|
|
148
|
-
const fn = typeof operand === "string" && operand.startsWith("$") ? operand : void 0;
|
|
149
|
-
const hasTail = fn && expression.charAt(p + 1) === ".";
|
|
150
|
-
let tail = "";
|
|
151
|
-
if (hasTail) {
|
|
152
|
-
[tail, p] = getTail(p + 2, expression);
|
|
153
|
-
}
|
|
154
|
-
const lStep = op ? step : getStep(startP, expression, 0);
|
|
155
|
-
const rStep = getStep(p, expression);
|
|
156
|
-
if (lStep === -1 && rStep === -1) {
|
|
157
|
-
operand = evaluate(parenthetical, -1, fn, tail);
|
|
158
|
-
if (typeof operand === "string") {
|
|
159
|
-
operand = parenthetical;
|
|
160
|
-
}
|
|
161
|
-
} else if (op && (lStep >= rStep || rStep === -1) && step === lStep) {
|
|
162
|
-
left = op.bind(null, evaluate(parenthetical, -1, fn, tail));
|
|
163
|
-
op = null;
|
|
164
|
-
operand = "";
|
|
165
|
-
} else if (rStep > lStep && step === rStep) {
|
|
166
|
-
operand = evaluate(parenthetical, -1, fn, tail);
|
|
167
|
-
} else {
|
|
168
|
-
operand += `(${parenthetical})${hasTail ? `.${tail}` : ""}`;
|
|
169
|
-
}
|
|
170
|
-
parenthetical = "";
|
|
171
|
-
} else {
|
|
172
|
-
parenthetical += char;
|
|
173
|
-
}
|
|
174
|
-
} else if (depth === 0 && (operation = getOp(symbols, char, p, expression))) {
|
|
175
|
-
if (p === 0) {
|
|
176
|
-
console.error(103, [operation, expression]);
|
|
177
|
-
}
|
|
178
|
-
p += operation.length - 1;
|
|
179
|
-
if (p === expression.length - 1) {
|
|
180
|
-
console.error(104, [operation, expression]);
|
|
181
|
-
}
|
|
182
|
-
if (!op) {
|
|
183
|
-
if (left) {
|
|
184
|
-
op = operators[operation].bind(null, evaluate(left, step));
|
|
185
|
-
left = null;
|
|
186
|
-
} else {
|
|
187
|
-
op = operators[operation].bind(null, evaluate(operand, step));
|
|
188
|
-
operand = "";
|
|
189
|
-
}
|
|
190
|
-
} else if (operand) {
|
|
191
|
-
left = op.bind(null, evaluate(operand, step));
|
|
192
|
-
op = operators[operation].bind(null, left);
|
|
193
|
-
operand = "";
|
|
194
|
-
}
|
|
195
|
-
continue;
|
|
196
|
-
} else {
|
|
197
|
-
addTo(depth, char);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
if (operand && op) {
|
|
201
|
-
op = op.bind(null, evaluate(operand, step));
|
|
202
|
-
}
|
|
203
|
-
op = !op && left ? left : op;
|
|
204
|
-
if (!op && operand) {
|
|
205
|
-
op = (v, t) => typeof v === "function" ? v(t) : v;
|
|
206
|
-
op = op.bind(null, evaluate(operand, step));
|
|
207
|
-
}
|
|
208
|
-
if (!op && !operand) {
|
|
209
|
-
console.error(105, expression);
|
|
210
|
-
}
|
|
211
|
-
return op;
|
|
212
|
-
}
|
|
213
|
-
function evaluate(operand, step, fnToken, tail) {
|
|
214
|
-
if (fnToken) {
|
|
215
|
-
const fn = evaluate(fnToken, operatorRegistry.length);
|
|
216
|
-
let userFuncReturn;
|
|
217
|
-
let tailCall = tail ? compile(`$${tail}`) : false;
|
|
218
|
-
if (typeof fn === "function") {
|
|
219
|
-
const args = parseArgs(String(operand)).map(
|
|
220
|
-
(arg) => evaluate(arg, -1)
|
|
221
|
-
);
|
|
222
|
-
return (tokens) => {
|
|
223
|
-
const userFunc = fn(tokens);
|
|
224
|
-
if (typeof userFunc !== "function") {
|
|
225
|
-
console.warn(150, fnToken);
|
|
226
|
-
return userFunc;
|
|
227
|
-
}
|
|
228
|
-
userFuncReturn = userFunc(
|
|
229
|
-
...args.map(
|
|
230
|
-
(arg) => typeof arg === "function" ? arg(tokens) : arg
|
|
231
|
-
)
|
|
232
|
-
);
|
|
233
|
-
if (tailCall) {
|
|
234
|
-
tailCall = tailCall.provide((subTokens) => {
|
|
235
|
-
const rootTokens = provideTokens(subTokens);
|
|
236
|
-
const t = subTokens.reduce(
|
|
237
|
-
(tokenSet, token) => {
|
|
238
|
-
const isTail = token === tail || tail?.startsWith(`${token}(`);
|
|
239
|
-
if (isTail) {
|
|
240
|
-
const value = getAt(userFuncReturn, token);
|
|
241
|
-
tokenSet[token] = () => value;
|
|
242
|
-
} else {
|
|
243
|
-
tokenSet[token] = rootTokens[token];
|
|
244
|
-
}
|
|
245
|
-
return tokenSet;
|
|
246
|
-
},
|
|
247
|
-
{}
|
|
248
|
-
);
|
|
249
|
-
return t;
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
return tailCall ? tailCall() : userFuncReturn;
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
} else if (typeof operand === "string") {
|
|
256
|
-
if (operand === "true") {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
if (operand === "false") {
|
|
260
|
-
return false;
|
|
261
|
-
}
|
|
262
|
-
if (operand === "undefined") {
|
|
263
|
-
return void 0;
|
|
264
|
-
}
|
|
265
|
-
if (isQuotedString(operand)) {
|
|
266
|
-
return rmEscapes(operand.substring(1, operand.length - 1));
|
|
267
|
-
}
|
|
268
|
-
if (!Number.isNaN(+operand)) {
|
|
269
|
-
return Number(operand);
|
|
270
|
-
}
|
|
271
|
-
if (step < operatorRegistry.length - 1) {
|
|
272
|
-
return compileExpr(operand, step + 1);
|
|
273
|
-
} else {
|
|
274
|
-
if (operand.startsWith("$")) {
|
|
275
|
-
const cleaned = operand.substring(1);
|
|
276
|
-
requirements.add(cleaned);
|
|
277
|
-
return function getToken(tokens) {
|
|
278
|
-
return cleaned in tokens ? tokens[cleaned]() : void 0;
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
return operand;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return operand;
|
|
285
|
-
}
|
|
286
|
-
const compiled = compileExpr(expr);
|
|
287
|
-
const identifiers = Array.from(requirements);
|
|
288
|
-
function provide(callback) {
|
|
289
|
-
provideTokens = callback;
|
|
290
|
-
return Object.assign(
|
|
291
|
-
compiled.bind(null, callback(identifiers)),
|
|
292
|
-
{ provide }
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
return Object.assign(compiled, {
|
|
296
|
-
provide
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export { compile };
|
|
2
|
+
import{parseArgs as z,getAt as B,isQuotedString as D,rmEscapes as G}from"./helpers.js";function L(Q){let S;const W=new Set,i=function(t,e){return typeof t=="function"?t(e):t},$=[{"&&":(t,e,n)=>i(t,n)&&i(e,n),"||":(t,e,n)=>i(t,n)||i(e,n)},{"===":(t,e,n)=>i(t,n)===i(e,n),"!==":(t,e,n)=>i(t,n)!==i(e,n),"==":(t,e,n)=>i(t,n)==i(e,n),"!=":(t,e,n)=>i(t,n)!=i(e,n),">=":(t,e,n)=>i(t,n)>=i(e,n),"<=":(t,e,n)=>i(t,n)<=i(e,n),">":(t,e,n)=>i(t,n)>i(e,n),"<":(t,e,n)=>i(t,n)<i(e,n)},{"+":(t,e,n)=>i(t,n)+i(e,n),"-":(t,e,n)=>i(t,n)-i(e,n)},{"*":(t,e,n)=>i(t,n)*i(e,n),"/":(t,e,n)=>i(t,n)/i(e,n),"%":(t,e,n)=>i(t,n)%i(e,n)}],k=$.reduce((t,e)=>t.concat(Object.keys(e)),[]),R=new Set(k.map(t=>t.charAt(0)));function N(t,e,n,a){const c=t.filter(r=>r.startsWith(e));return c.length?c.find(r=>a.length>=n+r.length&&a.substring(n,n+r.length)===r?r:!1):!1}function w(t,e,n=1){let a=n?e.substring(t+1).trim():e.substring(0,t).trim();if(!a.length)return-1;if(!n){const r=a.split("").reverse(),l=r.findIndex(s=>R.has(s));a=r.slice(l).join("")}const[c]=a;return $.findIndex(r=>{const l=Object.keys(r);return!!N(l,c,0,a)})}function T(t,e){let n="";const{length:a}=e;let c=0;for(let r=t;r<a;r++){const l=e.charAt(r);if(l==="(")c++;else if(l===")")c--;else if(c===0&&l===" ")continue;if(c===0&&N(k,l,r,e))return[n,r-1];n+=l}return[n,e.length-1]}function x(t,e=0){const n=$[e],{length:a}=t,c=Object.keys(n);let r=0,l=!1,s=null,o="",h=null,d,m,u="",g="",y="",C=0;const A=(f,b)=>{f?g+=b:o+=b};for(let f=0;f<a;f++)if(m=u,u=t.charAt(f),(u==="'"||u==='"')&&m!=="\\"&&(r===0&&!l||r&&!y)){r?y=u:l=u,A(r,u);continue}else if(l&&(u!==l||m==="\\")||y&&(u!==y||m==="\\")){A(r,u);continue}else if(l===u){l=!1,A(r,u);continue}else if(y===u){y=!1,A(r,u);continue}else{if(u===" ")continue;if(u==="(")r===0?C=f:g+=u,r++;else if(u===")")if(r--,r===0){const b=typeof o=="string"&&o.startsWith("$")?o:void 0,F=b&&t.charAt(f+1)===".";let j="";F&&([j,f]=T(f+2,t));const O=s?e:w(C,t,0),v=w(f,t);O===-1&&v===-1?(o=p(g,-1,b,j),typeof o=="string"&&(o=g)):s&&(O>=v||v===-1)&&e===O?(h=s.bind(null,p(g,-1,b,j)),s=null,o=""):v>O&&e===v?o=p(g,-1,b,j):o+=`(${g})${F?`.${j}`:""}`,g=""}else g+=u;else if(r===0&&(d=N(c,u,f,t))){f===0&&console.error(103,[d,t]),f+=d.length-1,f===t.length-1&&console.error(104,[d,t]),s?o&&(h=s.bind(null,p(o,e)),s=n[d].bind(null,h),o=""):h?(s=n[d].bind(null,p(h,e)),h=null):(s=n[d].bind(null,p(o,e)),o="");continue}else A(r,u)}return o&&s&&(s=s.bind(null,p(o,e))),s=!s&&h?h:s,!s&&o&&(s=(f,b)=>typeof f=="function"?f(b):f,s=s.bind(null,p(o,e))),!s&&!o&&console.error(105,t),s}function p(t,e,n,a){if(n){const c=p(n,$.length);let r,l=a?L(`$${a}`):!1;if(typeof c=="function"){const s=z(String(t)).map(o=>p(o,-1));return o=>{const h=c(o);return typeof h!="function"?(console.warn(150,n),h):(r=h(...s.map(d=>typeof d=="function"?d(o):d)),l&&(l=l.provide(d=>{const m=S(d);return d.reduce((u,g)=>{if(g===a||a?.startsWith(`${g}(`)){const y=B(r,g);u[g]=()=>y}else u[g]=m[g];return u},{})})),l?l():r)}}}else if(typeof t=="string"){if(t==="true")return!0;if(t==="false")return!1;if(t==="undefined")return;if(D(t))return G(t.substring(1,t.length-1));if(!Number.isNaN(+t))return Number(t);if(e<$.length-1)return x(t,e+1);if(t.startsWith("$")){const c=t.substring(1);return W.add(c),function(r){return c in r?r[c]():void 0}}return t}return t}const I=x(Q),q=Array.from(W);function E(t){return S=t,Object.assign(I.bind(null,t(q)),{provide:E})}return Object.assign(I,{provide:E})}export{L as compile};
|