datastar/site/routes_errors_runtime.templ

551 lines
20 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package site
import "strings"
import "regexp"
templ AttrValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("attr")
@attrError()
}
}
templ BindKeyAndValueProvided(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyAndValueProvided("bind")
@bindError()
}
}
templ BindKeyOrValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyOrValueRequired("bind")
@bindError()
}
}
templ BindSelectMultiple(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>The <code>data-bind</code> attribute was added to a <code>select</code> element with a <code>multiple</code> attribute. For this to work, the signal must be predefined as an array.</p>
@attributeDocs("bind")
}
}
templ BindUnsupportedSignalType(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>The <code>data-bind</code> attribute was bound to a signal that is unsupported. The <code>data-bind</code> attribute may only be used with signals of the following type: <code>number</code>, <code>string</code>, <code>boolean</code>, <code>array</code>.</p>
@attributeDocs("bind")
}
}
templ ClassValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("class")
@classError()
}
}
templ ClipboardNotAvailable(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>The Clipboard API is not available in this browser.</p>
}
}
templ ComputedKeyRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyRequired("computed")
@computedError()
}
}
templ ComputedValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("computed")
@computedError()
}
}
templ CustomValidityInvalidElement(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>The <code>data-custom-validity</code> attribute was used on an element that is not a <code>HTMLInputElement</code>, <code>HTMLSelectElement</code> or <code>HTMLTextAreaElement</code>. The <code>data-custom-validity</code> attribute can only be used on input, select and textarea elements.</p>
@customValidityError()
}
}
templ CustomValidityInvalidExpression(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>An invalid expression was provided to the <code>data-custom-validity</code> attribute.</p>
@customValidityError()
}
}
templ CustomValidityKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("custom-validity", info.Expression.Key)
@customValidityError()
}
}
templ CustomValidityValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("custom-validity")
@customValidityError()
}
}
templ ExecuteExpression(name string, info *RuntimeErrorInfo) {
{{
var isSignalRe = regexp.MustCompile(`^(\$\S*) is not defined`)
isSignalMatches := isSignalRe.FindAllStringSubmatch(info.Error, -1)
}}
@RuntimeErrorView(name, info) {
if len(isSignalMatches) > 0 {
{{
signalMatch := isSignalMatches[0][1][1:]
}}
<p>The signal <code class="text-primary">${ signalMatch }</code> is not valid. Ensure that the signal has been defined and that you only access leaf nodes when using namespaced signals.</p>
if (len(info.Expression.ValidSignals) > 0) {
{{
suggestedSignals := []string{}
for _, signal := range info.Expression.ValidSignals {
if signal == signalMatch || strings.HasPrefix(signal, signalMatch + ".") {
suggestedSignals = append(suggestedSignals, signal)
}
}
}}
if len(suggestedSignals) > 0 {
<div>
The following valid signals match the <code class="text-primary">${ signalMatch }</code> namespace:
@signalNames(suggestedSignals...)
</div>
}
<div>
All current valid signals:
@signalNames(info.Expression.ValidSignals...)
</div>
} else {
<p>No valid signals exist.</p>
}
<p>In the following example, <code>$foo</code> is <em>not</em> a valid signal, since only the leaf nodes in nested signals are actually signals.</p>
@sampleCode("Example", "html", `<div data-signals="{foo: {bar: 1, baz: 2}}">
<div data-text="$foo.woof"></div>
</div>`)
} else {
{{
var isUndefinedStringRe = regexp.MustCompile(`^(\S*) is not defined`)
isStringMatches := isUndefinedStringRe.FindAllStringSubmatch(info.Error, -1)
}}
if len(isStringMatches) > 0 {
{{
stringMatch := isStringMatches[0][1]
}}
<p>The variable <code class="text-primary">{ stringMatch }</code> is not defined. Ensure that the variable has been defined or, if you intended it to be a string, that you wrap it in quotes.</p>
@sampleCode("Example", "html", `<div data-text="'foo'"></div>`)
} else {
<p>An unknown error occurred while executing an expression.</p>
}
}
@expressionDocs()
}
}
templ GenerateExpression(name string, info *RuntimeErrorInfo) {
{{
var isMultilineReturnRe = regexp.MustCompile(`return \([\s\S]*\n[\s\S]*\);`)
isMultilineReturnMatches := isMultilineReturnRe.FindAllStringSubmatch(info.Expression.FnContent, -1)
}}
@RuntimeErrorView(name, info) {
<p>A valid expression could not be generated.</p>
if len(isMultilineReturnMatches) > 0 {
<p>Multiple statements can be used in a single expression by separating them with a semicolon Expressions may span multiple lines, but a semicolon must be used to separate statements.</p>
@sampleCode("Example", "html", `<div data-signals-foo="1">
<div data-on-click="
$foo++;
@post('/endpoint')
"></div>
</div>`)
} else {
<pre>{ info.Expression.FnContent }</pre>
}
@expressionDocs()
}
}
templ IndicatorKeyAndValueProvided(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyAndValueProvided("indicator")
@indicatorError()
}
}
templ IndicatorKeyOrValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyOrValueRequired("indicator")
@indicatorError()
}
}
templ IntersectsKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("intersects", info.Expression.Key)
@intersectsError()
}
}
templ IntersectsValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("intersects")
@intersectsError()
}
}
templ InvalidContentType(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
if info.URL == "" {
<p>An invalid content type was provided in the response. The content type must be <code>text/event-stream</code>.</p>
} else {
<p>An invalid content type was provided in the response from <code>{ info.URL }</code>. The content type must be <code>text/event-stream</code>.</p>
}
}
}
templ InvalidDataUri(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>Reading the file data URI failed.</p>
}
}
templ InvalidFileResultType(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
if info.ResultType == "" {
<p>Reading the file contents failed.</p>
} else {
<p>Reading the file contents of type <code>{ info.ResultType }</code> failed.</p>
}
}
}
templ OnKeyRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyRequired("on")
@onError()
}
}
templ OnValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("on")
@onError()
}
}
templ PersistKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("persist", info.Expression.Key)
<p>The <code>data-persist</code> attribute must <em>not</em> have a key. If one or more space-separated values are provided as a string, only those signals are persisted.</p>
@sampleCode("Example", "html", `<div data-persist="foo bar"></div>`)
@attributeDocs("persist")
}
}
templ RefKeyAndValueProvided(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyAndValueProvided("ref")
@refError()
}
}
templ RefKeyOrValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyOrValueRequired("ref")
@refError()
}
}
templ ReplaceUrlKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("replace-url", info.Expression.Key)
@replaceUrlError()
}
}
templ ReplaceUrlValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("replace-url")
@replaceUrlError()
}
}
templ ScrollIntoViewInvalidElement(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>The <code>data-scroll-into-view</code> attribute was placed on an invalid element. It may only be placed on an HTML element or an SVG element.</p>
@sampleCode("Example", "html", `<div data-scroll-into-view></div>`)
@attributeDocs("scroll-into-view")
}
}
templ ScrollIntoViewKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("scroll-into-view", info.Expression.Key)
@scrollIntoViewError()
}
}
templ ScrollIntoViewValueNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueNotAllowed("scroll-into-view", info.Expression.Value)
@scrollIntoViewError()
}
}
templ ShowKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("show", info.Expression.Key)
@showError()
}
}
templ ShowValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("show")
@showError()
}
}
templ SignalsValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("signals")
@signalsError()
}
}
templ SseClosestFormNotFound(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
{{
action := getValue(info.Action, "get")
}}
<p>No closest form could be found in the DOM. When setting the <code>contentType</code> option to <code>form</code>, the element must have a wrapping form, otherwise a <code>selector</code> must be provided to a form that exists in the DOM.</p>
@sampleCode("Example using a wrapping form", "html", `<form>
<button data-on-click={ "@" + action + "('/endpoint', {contentType: 'form'})" }></button>
</form>`)
@sampleCode("Example using a selector", "html", `<button data-on-click={ "@" + action + "('/endpoint', {contentType: 'form', selector: '#myform'})" }></button>`)
@actionDocs(action)
}
}
templ SseFetchFailed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
if info.Method == "" || info.URL == "" {
<p>An error was encountered when sending a request.</p>
} else {
<p>The following error was encountered when sending a <code>{ info.Method }</code> request to <code>{ info.URL }</code>.</p>
@code(`text`, info.Error)
}
}
}
templ SseFormNotFound(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
{{
action := getValue(info.Action, "get")
}}
if info.Selector == "" {
<p>No form with the provided selector could be found in the DOM. When specifying a form selector using the <code>selector</code> option in the <code>{ "@" + action }()</code> action, the form must already exist in the DOM.</p>
} else {
<p>No form with the selector <code>{ info.Selector }</code> could be found in the DOM. When specifying a form selector using the <code>selector</code> option in the <code>{ "@" + action }()</code> action, the form must already exist in the DOM.</p>
}
@sampleCode("Example", "html", `<button data-on-click={ "@" + action + "('/endpoint', {contentType: 'form', selector: '#myform'})" }></button>`)
@actionDocs(action)
}
}
templ SseInvalidContentType(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
{{
action := getValue(info.Action, "get")
}}
if info.ContentType == "" {
<p>An invalid content type was provided. The content type must be either <code>json</code> (the default) or <code>form</code>.</p>
} else {
<p>An invalid content type <code>{ info.ContentType }</code> was provided to the <code>{ "@" + action }()</code> action. The content type must be either <code>json</code> (the default) or <code>form</code>.</p>
}
@sampleCode("Example", "html", `<button data-on-click={ "@" + action + "('/endpoint', {contentType: 'form'})" }></button>`)
@actionDocs(action)
}
}
templ SseNoUrlProvided(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
{{
action := getValue(info.Action, "get")
}}
<p>No URL was provided to the <code>{ "@" + action }()</code> action. A valid URL must be provided as the first argument.</p>
@sampleCode("Example", "html", `<button data-on-click={ "@" + action + "('/endpoint')" }></button>`)
@actionDocs(action)
}
}
templ TextInvalidElement(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
<p>The <code>data-text</code> attribute was placed on an invalid element. It may only be placed on an HTML element.</p>
@sampleCode("Example", "html", `<div data-text="$foo"></div>`)
@attributeDocs("text")
}
}
templ TextKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("text", info.Expression.Key)
@textError()
}
}
templ TextValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("text")
@textError()
}
}
templ ViewTransitionKeyNotAllowed(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@keyNotAllowed("view-transition", info.Expression.Key)
@viewTransitionError()
}
}
templ ViewTransitionValueRequired(name string, info *RuntimeErrorInfo) {
@RuntimeErrorView(name, info) {
@valueRequired("view-transition")
@viewTransitionError()
}
}
templ attrError() {
<p>The <code>data-attr</code> attribute <em>must</em> have a value, representing either an expression (if a key is provided), or an object of key-value pairs, where the keys are attribute names and the values are expressions.</p>
@sampleCode("Example", "html", `<div data-attr-disabled="$foo"></div>`)
@sampleCode("Alternative syntax", "html", `<div data-attr="{disabled: foo}"></div>`)
@attributeDocs("attr")
}
templ bindError() {
<p>The <code>data-bind</code> attribute must have either a key <em>or</em> a value, representing the signal name to create and enable two-way binding with the elements value.</p>
@sampleCode("Example", "html", `<input data-bind-signalname/>`)
@sampleCode("Alternative syntax", "html", `<input data-bind="signalname" />`)
@attributeDocs("bind")
}
templ classError() {
<p>The <code>data-class</code> attribute <em>must</em> have a value, representing either an expression (if a key is provided), or an object of key-value pairs, where the keys are class names and the values are expressions.</p>
@sampleCode("Example", "html", `<div data-class-hidden="$foo"></div>`)
@sampleCode("Alternative syntax", "html", `<div data-class="{hidden: foo}"></div>`)
@attributeDocs("class")
}
templ computedError() {
<p>The <code>data-computed</code> attribute <em>must</em> have both a key, representing the signal name to create, and a value, representing the expression to assign to the signal.</p>
@sampleCode("Example", "html", `<div data-computed-blinker="count % 2 === 0"></div>`)
@attributeDocs("computed")
}
templ customValidityError() {
<p>The <code>data-intersects</code> attribute must <em>only</em> have a value, representing an expression that must evaluate to a string that will be set as the custom validity message. If the string is empty, the input is considered valid. If the string is non-empty, the input is considered invalid and the string is used as the reported message.</p>
@sampleCode("Example", "html", `<form>
<input data-bind-foo name="foo" />
<input data-bind-bar name="bar"
data-custom-validity="$foo === $bar ? '' : 'Field values must be the same.'"
/>
<button>
Submit form
</button>
</form>`)
@attributeDocs("custom-validity")
}
templ indicatorError() {
<p>The <code>data-indicator</code> attribute must have either a key <em>or</em> a value, representing the name of a signal. The signal will be assigned the <code>value</code> true when an SSE request is in-flight, otherwise it will be <code>false</code>.</p>
@sampleCode("Example", "html", `<div data-indicator-foo></div>`)
@sampleCode("Alternative syntax", "html", `<div data-indicator="foo"></div>`)
@attributeDocs("indicator")
}
templ intersectsError() {
<p>The <code>data-intersects</code> attribute must <em>only</em> have a value, representing an expression to run when the element intersects with the viewport.</p>
@sampleCode("Example", "html", `<div data-intersects="console.log('I am intersecting!')"></div>`)
@attributeDocs("intersects")
}
templ onError() {
<p>The <code>data-on</code> attribute <em>must</em> have a key representing the event listener to attach to the element, and a value representing an expression to execute when the event listener is triggered.</p>
@sampleCode("Example", "html", `<button data-on-click="alert($foo)">Click Me</button>`)
@attributeDocs("on")
}
templ refError() {
<p>The <code>data-ref</code> attribute must have either a key <em>or</em> a value, representing the name of a signal. The signal will be assigned the element as its value.</p>
@sampleCode("Example", "html", `<div data-ref-foo></div>`)
@attributeDocs("ref")
}
templ replaceUrlError() {
<p>The <code>data-replace-url</code> attribute must <em>only</em> have a value, representing an expression that evaluates to a URL to replace in the browser without reloading the page.</p>
@sampleCode("Example", "html", `<div data-replace-url="'?page=1'"></div>`)
@attributeDocs("replace-url")
}
templ scrollIntoViewError() {
<p>The <code>data-scroll-into-view</code> attribute must <em>not</em> have a key <em>nor</em> a value.</p>
@sampleCode("Example", "html", `<div data-scroll-into-view></div>`)
@attributeDocs("scroll-into-view")
}
templ showError() {
<p> The <code>data-show</code> attribute must <em>only</em> have a value, representing an expression evaluating to <code>true</code> or <code>false</code>, which determines whether to show or hide the element, respectively.</p>
@sampleCode("Example", "html", `<div data-show="$foo"></div>`)
@attributeDocs("show")
}
templ signalsError() {
<p>The <code>data-signalsError</code> attribute <em>must</em> have a value, representing either an expression (if a key is provided), or an object of key-value pairs, where the keys are signal names and the values are expressions.</p>
@sampleCode("Example", "html", `<div data-signals-foo="1"></div>`)
@sampleCode("Alternative syntax", "html", `<div data-signals="{foo: 1}"></div>`)
@attributeDocs("signals")
}
templ textError() {
<p>The <code>data-text</code> attribute must <em>only</em> have a value, representing an expression that is evaluated and used as the text content of the element.</p>
@sampleCode("Example", "html", `<div data-text="$foo"></div>`)
@attributeDocs("text")
}
templ viewTransitionError() {
<p>The <code>data-view-transition</code> attribute must <em>only</em> have a value, representing a <code>view-transition-name</code>.</p>
@sampleCode("Example", "html", `<div data-view-transition="$foo"></div>`)
@attributeDocs("view-transition")
}
templ keyNotAllowed(pluginName string, key string) {
<p>The key { key } was provided to the <code>data-{ pluginName }</code> attribute.</p>
}
templ keyRequired(pluginName string) {
<p>No key was provided to the <code>data-{ pluginName }</code> attribute.</p>
}
templ valueNotAllowed(pluginName string, value string) {
<p>The value { value } was provided to the <code>data-{ pluginName }</code> attribute.</p>
}
templ valueRequired(pluginName string) {
<p>No value was provided to the <code>data-{ pluginName }</code> attribute.</p>
}
templ keyAndValueProvided(pluginName string) {
<p>Both a key and a value were provided to the <code>data-{ pluginName }</code> attribute.</p>
}
templ keyOrValueRequired(pluginName string) {
<p>No key or value was provided to the <code>data-{ pluginName }</code> attribute.</p>
}