public async Task Only_call_EvaluateCode_method_once() { CustomMethods.Counter = 0; var context = new ScriptContext { ScriptMethods = { new CustomMethods() }, }.Init(); var fn = ScriptCodeUtils.EnsureReturn("chooseColor(`#336699`)"); var ret = await context.EvaluateCodeAsync(fn); Assert.That(ret, Is.EqualTo("#336699")); Assert.That(CustomMethods.Counter, Is.EqualTo(1)); CustomMethods.Counter = 0; fn = ScriptCodeUtils.EnsureReturn("chooseColor"); ret = await context.EvaluateCodeAsync(fn); Assert.That(ret, Is.EqualTo("#ffffff")); Assert.That(CustomMethods.Counter, Is.EqualTo(1)); CustomMethods.Counter = 0; fn = ScriptCodeUtils.EnsureReturn("chooseColor()"); ret = await context.EvaluateCodeAsync(fn); Assert.That(ret, Is.EqualTo("#ffffff")); Assert.That(CustomMethods.Counter, Is.EqualTo(1)); }
public static void AddTypeValidator(List <ITypeValidator> to, IValidateRule attr) { var appHost = HostContext.AppHost; if (!string.IsNullOrEmpty(attr.Condition)) { var evalCode = ScriptCodeUtils.EnsureReturn(attr.Condition); var code = appHost.ScriptContext.CodeSharpPage(evalCode); to.Add(new ScriptValidator(code, attr.Condition).Init(attr)); } else if (!string.IsNullOrEmpty(attr.Validator)) { var ret = appHost.EvalExpression(attr .Validator); //Validators can't be cached due to custom code/msgs if (ret == null) { ThrowNoValidator(attr.Validator); } if (ret is ITypeValidator validator) { to.Add(validator.Init(attr)); } else if (ret is List <object> objs) { foreach (var o in objs) { if (o is ITypeValidator itemValidator) { to.Add(itemValidator.Init(attr)); } else { ThrowInvalidValidator(attr.Validator, nameof(ITypeValidator)); } } } else { ThrowInvalidValidator(attr.Validator, nameof(ITypeValidator)); } } else { ThrowInvalidValidateRequest(); } }
public async Task Any(EvalScript request) { var feature = HostContext.AssertPlugin <DesktopFeature>(); RequestUtils.AssertAccessRole(base.Request, accessRole: feature.AccessRole, authSecret: request.AuthSecret); var appHost = HostContext.AppHost; string script; var method = ((script = request.EvaluateScript) != null ? nameof(request.EvaluateScript) : (script = request.EvaluateCode) != null ? nameof(request.EvaluateCode) : (script = request.EvaluateLisp) != null ? nameof(request.EvaluateLisp) : (script = request.RenderScript) != null ? nameof(request.RenderScript) : (script = request.RenderCode) != null ? nameof(request.RenderCode) : (script = request.RenderLisp) != null ? nameof(request.RenderLisp) : null) ?? ((script = request.EvaluateScriptAsync) != null ? nameof(request.EvaluateScriptAsync) : (script = request.EvaluateCodeAsync) != null ? nameof(request.EvaluateCodeAsync) : (script = request.EvaluateLispAsync) != null ? nameof(request.EvaluateLispAsync) : (script = request.RenderScriptAsync) != null ? nameof(request.RenderScriptAsync) : (script = request.RenderCodeAsync) != null ? nameof(request.RenderCodeAsync) : (script = request.RenderLispAsync) != null ? nameof(request.RenderLispAsync) : null) ?? throw new ArgumentNullException(nameof(request.EvaluateCode)); async Task HandleExceptionAsync(Exception e) { log.Error(e.Message, e); base.Response.StatusCode = 500; base.Response.StatusDescription = e.GetType().Name; base.Response.ContentType = MimeTypes.PlainText; await base.Response.OutputStream.WriteAsync(MemoryProvider.Instance.ToUtf8(e.ToString().AsSpan())); await base.Response.EndRequestAsync(skipHeaders : true); } async Task SetResult(object value, string resultType = " result") { base.Response.ContentType = MimeTypes.Json; base.Response.StatusCode = 200; base.Response.StatusDescription = method + resultType; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); JsonSerializer.SerializeToStream(value, ms); ms.Position = 0; await ms.CopyToAsync(base.Response.OutputStream); }); } async Task SetOutput(PageResult result) { base.Response.StatusCode = 200; base.Response.StatusDescription = method + " result"; base.Response.ContentType = MimeTypes.PlainText; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); await result.RenderToStreamAsync(ms); ms.Position = 0; await ms.CopyToAsync(res.OutputStream); }); } var args = new Dictionary <string, object> { [ScriptConstants.Request] = base.Request, }; if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.EvaluateScript))) { await SetResult(await appHost.ScriptContext.EvaluateAsync(script, args)); } else if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.RenderScript))) { await SetOutput(new PageResult(appHost.ScriptContext.SharpScriptPage(script)).AssignArgs(args)); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.EvaluateCode))) { await SetResult(await appHost.ScriptContext.EvaluateCodeAsync(ScriptCodeUtils.EnsureReturn(script), args)); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.RenderCode))) { await SetOutput(new PageResult(appHost.ScriptContext.CodeSharpPage(script)).AssignArgs(args)); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.EvaluateLisp))) { await SetResult(await appHost.ScriptContext.EvaluateLispAsync(ScriptLispUtils.EnsureReturn(script), args)); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.RenderLisp))) { await SetOutput(new PageResult(appHost.ScriptContext.LispSharpPage(script)).AssignArgs(args)); } if (base.Response.IsClosed) { return; } async Task setResultAsync(Task <object> valueTask, string resultType = " result") { try { base.Response.ContentType = MimeTypes.Json; base.Response.StatusCode = 200; base.Response.StatusDescription = method + resultType; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); JsonSerializer.SerializeToStream(await valueTask, ms); await ms.CopyToAsync(base.Response.OutputStream); }); } catch (Exception e) { await HandleExceptionAsync(e); } } async Task setOutputAsync(PageResult result) { try { base.Response.StatusCode = 200; base.Response.StatusDescription = method + " async result"; base.Response.ContentType = MimeTypes.PlainText; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); await result.RenderToStreamAsync(ms); await ms.CopyToAsync(res.OutputStream); }); } catch (Exception e) { await HandleExceptionAsync(e); } } if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.EvaluateScriptAsync))) { await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateAsync(script, args), " async result")); } else if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.RenderScriptAsync))) { await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.SharpScriptPage(script)).AssignArgs(args))); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.EvaluateCodeAsync))) { await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateCodeAsync(ScriptCodeUtils.EnsureReturn(script), args), " async result")); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.RenderCodeAsync))) { await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.CodeSharpPage(script)).AssignArgs(args))); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.EvaluateLispAsync))) { await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateLispAsync(ScriptLispUtils.EnsureReturn(script), args), " async result")); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.RenderLispAsync))) { await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.LispSharpPage(script)).AssignArgs(args))); } else { throw new NotSupportedException($"Unsupported script API '{method}', supported: " + "EvaluateScript/Async, EvaluateCode/Async, EvaluateLisp/Async"); } }
public static void AddRule(this List <IPropertyValidator> validators, PropertyInfo pi, IValidateRule propRule) { var appHost = HostContext.AppHost; foreach (var ruleFilter in RuleFilters) { ruleFilter(pi, propRule); } IPropertyValidator apply(IPropertyValidator validator) { var errorCode = propRule.ErrorCode; if (!string.IsNullOrEmpty(errorCode)) { validator.Options.ErrorCodeSource = new StaticStringSource(errorCode); } else { if (propRule.Condition != null && ConditionErrorCodes.TryGetValue(propRule.Condition, out errorCode)) { validator.Options.ErrorCodeSource = new StaticStringSource(errorCode); } } if (!string.IsNullOrEmpty(propRule.Message)) { validator.Options.ErrorMessageSource = new StaticStringSource(propRule.Message.Localize()); } else if (errorCode != null && ErrorCodeMessages.TryGetValue(errorCode, out var errorMsg)) { validator.Options.ErrorMessageSource = new StaticStringSource(errorMsg.Localize()); } return(validator); } if (propRule.Validator != null) { var ret = appHost.EvalExpression(propRule .Validator); //Validators can't be cached due to custom code/msgs if (ret == null) { ThrowNoValidator(propRule.Validator); } if (ret is IPropertyValidator validator) { validators.Add(apply(validator)); } else if (ret is List <object> objs) { foreach (var o in objs) { if (o is IPropertyValidator itemValidator) { validators.Add(apply(itemValidator)); } else { ThrowInvalidValidator(propRule.Validator, nameof(IPropertyValidator)); } } } else { ThrowInvalidValidator(propRule.Validator, nameof(IPropertyValidator)); } } else if (!string.IsNullOrEmpty(propRule.Condition)) { var evalCode = ScriptCodeUtils.EnsureReturn(propRule.Condition); var page = appHost.ScriptContext.CodeSharpPage(evalCode); validators.Add(apply(new ScriptConditionValidator(page))); } else { ThrowInvalidValidate(); } }
public static SharpPage ParseCondition(ScriptContext context, string condition) { var evalCode = ScriptCodeUtils.EnsureReturn(condition); return(context.CodeSharpPage(evalCode)); }
public static void AddRule(this List <IPropertyValidator> validators, PropertyInfo pi, IValidateRule propRule) { var appHost = HostContext.AppHost; foreach (var ruleFilter in RuleFilters) { ruleFilter(pi, propRule); } IPropertyValidator apply(IPropertyValidator validator) { var errorCode = propRule.ErrorCode; if (!string.IsNullOrEmpty(errorCode)) { validator.Options.ErrorCodeSource = new StaticStringSource(errorCode); } else { if (propRule.Condition != null && ConditionErrorCodes.TryGetValue(propRule.Condition, out errorCode)) { validator.Options.ErrorCodeSource = new StaticStringSource(errorCode); } } if (!string.IsNullOrEmpty(propRule.Message)) { validator.Options.ErrorMessageSource = new StaticStringSource(appHost.ResolveLocalizedString(propRule.Message)); } else if (errorCode != null && ErrorCodeMessages.TryGetValue(errorCode, out var errorMsg)) { validator.Options.ErrorMessageSource = new StaticStringSource(appHost.ResolveLocalizedString(errorMsg)); } return(validator); } if (propRule.Validator != null) { var ret = appHost.EvalExpression(propRule .Validator); //Validators can't be cached due to custom code/msgs if (ret == null) { throw new NotSupportedException( $"Could not resolve matching '{propRule.Validator}` Validator Script Method. " + $"Ensure it's registered in AppHost.ScriptContext and called with correct number of arguments."); } if (ret is IPropertyValidator validator) { validators.Add(apply(validator)); } else if (ret is List <object> objs) { foreach (var o in objs) { if (o is IPropertyValidator itemValidator) { validators.Add(apply(itemValidator)); } } } else { throw new NotSupportedException($"{propRule.Validator} is not an IPropertyValidator"); } } else if (!string.IsNullOrEmpty(propRule.Condition)) { var evalCode = ScriptCodeUtils.EnsureReturn(propRule.Condition); var page = appHost.ScriptContext.CodeSharpPage(evalCode); validators.Add(apply(new ScriptConditionValidator(page))); } }