@xano/xanoscript-language-server 12.16.4 → 12.16.6
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/lexer/db.js +8 -0
- package/lexer/query.js +8 -0
- package/onCompletion/onCompletion.js +1 -1
- package/onDefinition/onDefinition.js +1 -0
- package/onHover/functions.md +14 -0
- package/package.json +1 -1
- package/parser/functions/db/dbIncrementFn.js +71 -0
- package/parser/functions/db/register.js +2 -0
- package/parser/functions/dbFn.js +1 -0
- package/parser/query_parser.js +21 -1
package/lexer/db.js
CHANGED
|
@@ -73,6 +73,12 @@ export const PatchToken = createTokenByName("patch", {
|
|
|
73
73
|
categories: [Identifier],
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
// increment
|
|
77
|
+
export const IncrementToken = createTokenByName("increment", {
|
|
78
|
+
longer_alt: Identifier,
|
|
79
|
+
categories: [Identifier],
|
|
80
|
+
});
|
|
81
|
+
|
|
76
82
|
// schema
|
|
77
83
|
export const SchemaToken = createTokenByName("schema", {
|
|
78
84
|
longer_alt: Identifier,
|
|
@@ -151,6 +157,7 @@ export const DbTokens = [
|
|
|
151
157
|
UpdateToken,
|
|
152
158
|
HasToken,
|
|
153
159
|
PatchToken,
|
|
160
|
+
IncrementToken,
|
|
154
161
|
SchemaToken,
|
|
155
162
|
TransactionToken,
|
|
156
163
|
TruncateToken,
|
|
@@ -186,6 +193,7 @@ export function mapTokenToType(token) {
|
|
|
186
193
|
case UpdateToken.name:
|
|
187
194
|
case HasToken.name:
|
|
188
195
|
case PatchToken.name:
|
|
196
|
+
case IncrementToken.name:
|
|
189
197
|
case TransactionToken.name:
|
|
190
198
|
case TruncateToken.name:
|
|
191
199
|
case DirectQueryToken.name:
|
package/lexer/query.js
CHANGED
|
@@ -40,6 +40,12 @@ export const ResponseTypeToken = createTokenByName("response_type", {
|
|
|
40
40
|
categories: [Identifier], // could also be an identifier
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
+
// external_access
|
|
44
|
+
export const ExternalAccessToken = createTokenByName("external_access", {
|
|
45
|
+
longer_alt: Identifier,
|
|
46
|
+
categories: [Identifier], // could also be an identifier
|
|
47
|
+
});
|
|
48
|
+
|
|
43
49
|
// dblink
|
|
44
50
|
export const DbLinkToken = createTokenByName("dblink", {
|
|
45
51
|
longer_alt: Identifier,
|
|
@@ -60,6 +66,7 @@ export const AddonToken = createTokenByName("addon", {
|
|
|
60
66
|
|
|
61
67
|
export const QueryTokens = [
|
|
62
68
|
ResponseTypeToken,
|
|
69
|
+
ExternalAccessToken,
|
|
63
70
|
QueryToken,
|
|
64
71
|
VerbToken,
|
|
65
72
|
GETToken,
|
|
@@ -81,6 +88,7 @@ export function mapTokenToType(token) {
|
|
|
81
88
|
case QueryToken.name:
|
|
82
89
|
case VerbToken.name:
|
|
83
90
|
case ResponseTypeToken.name:
|
|
91
|
+
case ExternalAccessToken.name:
|
|
84
92
|
return "keyword";
|
|
85
93
|
case GETToken.name:
|
|
86
94
|
case PATCHToken.name:
|
|
@@ -95,7 +95,7 @@ function getWorkspaceCompletions(prefix) {
|
|
|
95
95
|
|
|
96
96
|
// db.* table name context
|
|
97
97
|
if (
|
|
98
|
-
/\b(get|add|edit|delete|query|patch|has|truncate|add_or_edit|schema)\s+("?[^"\s{]*$)/.test(
|
|
98
|
+
/\b(get|add|edit|delete|query|patch|increment|has|truncate|add_or_edit|schema)\s+("?[^"\s{]*$)/.test(
|
|
99
99
|
prefix
|
|
100
100
|
)
|
|
101
101
|
) {
|
package/onHover/functions.md
CHANGED
|
@@ -928,6 +928,20 @@ db.patch user {
|
|
|
928
928
|
|
|
929
929
|
Updates specific fields of an existing record in a database table (e.g., `user`) identified by a field (e.g., `email`) and its value (e.g., `$input.email`). The `data` block specifies the fields to update, and the modified record is stored in `$updated_user`.
|
|
930
930
|
|
|
931
|
+
# db.increment
|
|
932
|
+
|
|
933
|
+
```xs
|
|
934
|
+
db.increment post {
|
|
935
|
+
where = $db.post.id == $input.id
|
|
936
|
+
field_name = "view_count"
|
|
937
|
+
value = 1
|
|
938
|
+
return = {type: "list"}
|
|
939
|
+
output = ["id", "view_count"]
|
|
940
|
+
} as $updated
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
Atomically adds `value` to the numeric column `field_name` (e.g., `view_count`) on every record of a database table (e.g., `post`) matching the `where` clause. A negative `value` (e.g., `-1`, or `$input.qty|multiply:-1`) decrements. `return` selects `list` (default, the updated records) or `count` (the number of updated records), `output` limits the returned columns, and the result is stored in `$updated`.
|
|
944
|
+
|
|
931
945
|
# db.get
|
|
932
946
|
|
|
933
947
|
```xs
|
package/package.json
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { IncrementToken } from "../../../lexer/db.js";
|
|
2
|
+
import { StringLiteral } from "../../../lexer/literal.js";
|
|
3
|
+
import { Identifier } from "../../../lexer/tokens.js";
|
|
4
|
+
import { getVarName } from "../../generic/utils.js";
|
|
5
|
+
import { captureFieldName } from "./captureFieldName.js";
|
|
6
|
+
import { addonSchema } from "./schema.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* db.increment <table> { where, field_name, value, ... } as $var
|
|
10
|
+
*
|
|
11
|
+
* Atomically adds `value` (negative decrements) to the numeric column
|
|
12
|
+
* `field_name` on every row matching `where`. The key set must match the
|
|
13
|
+
* server-side kind schema exactly, or the editor reports false diagnostics.
|
|
14
|
+
*
|
|
15
|
+
* @param {import('../../base_parser.js').XanoBaseParser} $
|
|
16
|
+
*/
|
|
17
|
+
export function dbIncrementFn($) {
|
|
18
|
+
return () => {
|
|
19
|
+
$.sectionStack.push("dbIncrementFn");
|
|
20
|
+
const fnToken = $.CONSUME(IncrementToken); // "increment"
|
|
21
|
+
const nameToken = $.OR({
|
|
22
|
+
DEF: [
|
|
23
|
+
{ ALT: () => $.CONSUME(Identifier) },
|
|
24
|
+
{ ALT: () => $.CONSUME1(StringLiteral) },
|
|
25
|
+
],
|
|
26
|
+
ERR_MSG: "Expected a table name",
|
|
27
|
+
});
|
|
28
|
+
$.addReference("table", getVarName(nameToken), nameToken);
|
|
29
|
+
|
|
30
|
+
const captured = {};
|
|
31
|
+
$.SUBRULE($.schemaParseAttributeFn, {
|
|
32
|
+
ARGS: [
|
|
33
|
+
fnToken,
|
|
34
|
+
{
|
|
35
|
+
"description?": "[string]",
|
|
36
|
+
"disabled?": "[boolean]",
|
|
37
|
+
where: "[query]",
|
|
38
|
+
field_name: "[expression]",
|
|
39
|
+
value: "[expression]",
|
|
40
|
+
"return?": {
|
|
41
|
+
"type?": ["list", "count"],
|
|
42
|
+
},
|
|
43
|
+
"output?": ["[string]"],
|
|
44
|
+
"addon?": [addonSchema],
|
|
45
|
+
"mock?": { "![string]": "[expression]" },
|
|
46
|
+
},
|
|
47
|
+
captured,
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
$.ACTION(() => {
|
|
52
|
+
captureFieldName($, captured);
|
|
53
|
+
// Extract addon name references (mirrors db.query)
|
|
54
|
+
if (captured.addon?.value && Array.isArray(captured.addon.value)) {
|
|
55
|
+
for (const item of captured.addon.value) {
|
|
56
|
+
const nameEntry = item.name;
|
|
57
|
+
if (nameEntry?.value) {
|
|
58
|
+
$.addReference(
|
|
59
|
+
"function",
|
|
60
|
+
getVarName(nameEntry.value),
|
|
61
|
+
nameEntry.value
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
$.SUBRULE($.asVariable, { ARGS: [fnToken] });
|
|
69
|
+
$.sectionStack.pop();
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -13,6 +13,7 @@ import { dbExternalDirectQueryFn } from "./dbExternalDirectQueryFn.js";
|
|
|
13
13
|
import { dbExternalFn } from "./dbExternalFn.js";
|
|
14
14
|
import { dbGetFn } from "./dbGetFn.js";
|
|
15
15
|
import { dbHasFn } from "./dbHasFn.js";
|
|
16
|
+
import { dbIncrementFn } from "./dbIncrementFn.js";
|
|
16
17
|
import { dbPatchFn } from "./dbPatchFn.js";
|
|
17
18
|
import { dbQueryFn } from "./dbQueryFn.js";
|
|
18
19
|
import { dbSchemaFn } from "./dbSchemaFn.js";
|
|
@@ -41,6 +42,7 @@ export const register = ($) => {
|
|
|
41
42
|
$.dbExternalFn = $.RULE("dbExternalFn", dbExternalFn($));
|
|
42
43
|
$.dbGetFn = $.RULE("dbGetFn", dbGetFn($));
|
|
43
44
|
$.dbHasFn = $.RULE("dbHasnpmFn", dbHasFn($));
|
|
45
|
+
$.dbIncrementFn = $.RULE("dbIncrementFn", dbIncrementFn($));
|
|
44
46
|
$.dbPatchFn = $.RULE("dbPatchFn", dbPatchFn($));
|
|
45
47
|
$.dbQueryFn = $.RULE("dbQueryFn", dbQueryFn($));
|
|
46
48
|
$.dbSchemaFn = $.RULE("dbSchemaFn", dbSchemaFn($));
|
package/parser/functions/dbFn.js
CHANGED
|
@@ -23,6 +23,7 @@ export function dbFn($) {
|
|
|
23
23
|
{ ALT: () => $.SUBRULE($.dbTruncateFn) }, // "db.truncate"
|
|
24
24
|
{ ALT: () => $.SUBRULE($.dbTransactionFn) }, // "db.transaction"
|
|
25
25
|
{ ALT: () => $.SUBRULE($.dbPatchFn) }, // "db.patch"
|
|
26
|
+
{ ALT: () => $.SUBRULE($.dbIncrementFn) }, // "db.increment"
|
|
26
27
|
{ ALT: () => $.SUBRULE($.dbBulkFn) }, // "db.bulk"
|
|
27
28
|
{ ALT: () => $.SUBRULE($.dbAddOrEditFn) }, // db.add_or_edit
|
|
28
29
|
]);
|
package/parser/query_parser.js
CHANGED
|
@@ -4,6 +4,7 @@ import { EqualToken, LCurly, RCurly } from "../lexer/control.js";
|
|
|
4
4
|
import { StringLiteral } from "../lexer/literal.js";
|
|
5
5
|
import {
|
|
6
6
|
DELETEToken,
|
|
7
|
+
ExternalAccessToken,
|
|
7
8
|
GETToken,
|
|
8
9
|
PATCHToken,
|
|
9
10
|
POSTToken,
|
|
@@ -12,7 +13,13 @@ import {
|
|
|
12
13
|
ResponseTypeToken,
|
|
13
14
|
VerbToken,
|
|
14
15
|
} from "../lexer/query.js";
|
|
15
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
AuthToken,
|
|
18
|
+
FalseToken,
|
|
19
|
+
Identifier,
|
|
20
|
+
NewlineToken,
|
|
21
|
+
TrueToken,
|
|
22
|
+
} from "../lexer/tokens.js";
|
|
16
23
|
import { getVarName } from "./generic/utils.js";
|
|
17
24
|
|
|
18
25
|
export function queryDeclaration($) {
|
|
@@ -30,6 +37,7 @@ export function queryDeclaration($) {
|
|
|
30
37
|
let hasTags = false;
|
|
31
38
|
let hasApiGroup = false;
|
|
32
39
|
let hasResponseType = false;
|
|
40
|
+
let hasExternalAccess = false;
|
|
33
41
|
let responseType = "standard";
|
|
34
42
|
|
|
35
43
|
const testNames = [];
|
|
@@ -120,6 +128,18 @@ export function queryDeclaration($) {
|
|
|
120
128
|
$.CONSUME3(StringLiteral);
|
|
121
129
|
},
|
|
122
130
|
},
|
|
131
|
+
{
|
|
132
|
+
GATE: () => !hasExternalAccess,
|
|
133
|
+
ALT: () => {
|
|
134
|
+
hasExternalAccess = true;
|
|
135
|
+
$.CONSUME(ExternalAccessToken); // "external_access"
|
|
136
|
+
$.CONSUME3(EqualToken); // "="
|
|
137
|
+
$.OR3([
|
|
138
|
+
{ ALT: () => $.CONSUME(TrueToken) }, // true
|
|
139
|
+
{ ALT: () => $.CONSUME(FalseToken) }, // false
|
|
140
|
+
]);
|
|
141
|
+
},
|
|
142
|
+
},
|
|
123
143
|
{
|
|
124
144
|
GATE: () => !hasDocs,
|
|
125
145
|
ALT: () => {
|