@infra-blocks/aws-dynamodb 0.62.0 → 0.63.0-alpha.0
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/lib/cjs/commands/attributes/names.d.ts +35 -4
- package/lib/cjs/commands/attributes/names.js +64 -10
- package/lib/cjs/commands/attributes/names.js.map +1 -1
- package/lib/cjs/commands/expressions/operands/index.d.ts +1 -1
- package/lib/cjs/commands/expressions/operands/index.js +2 -1
- package/lib/cjs/commands/expressions/operands/index.js.map +1 -1
- package/lib/cjs/commands/expressions/operands/path.d.ts +34 -4
- package/lib/cjs/commands/expressions/operands/path.js +43 -9
- package/lib/cjs/commands/expressions/operands/path.js.map +1 -1
- package/lib/cjs/commands/index.d.ts +0 -1
- package/lib/cjs/commands/index.js +0 -1
- package/lib/cjs/commands/index.js.map +1 -1
- package/lib/esm/commands/attributes/names.d.ts +35 -4
- package/lib/esm/commands/attributes/names.js +64 -10
- package/lib/esm/commands/attributes/names.js.map +1 -1
- package/lib/esm/commands/expressions/operands/index.d.ts +1 -1
- package/lib/esm/commands/expressions/operands/index.js +1 -1
- package/lib/esm/commands/expressions/operands/index.js.map +1 -1
- package/lib/esm/commands/expressions/operands/path.d.ts +34 -4
- package/lib/esm/commands/expressions/operands/path.js +43 -10
- package/lib/esm/commands/expressions/operands/path.js.map +1 -1
- package/lib/esm/commands/index.d.ts +0 -1
- package/lib/esm/commands/index.js +0 -1
- package/lib/esm/commands/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -28,15 +28,46 @@ export declare class AttributeNames {
|
|
|
28
28
|
* Returns a substitution variable for the given attribute path.
|
|
29
29
|
*
|
|
30
30
|
* If the attribute path is seen for the first time by this object, a new substitution is generated,
|
|
31
|
-
* assigned to the attribute path, and returned.
|
|
31
|
+
* it is assigned to the attribute path, and returned. If the attribute path was previously registered,
|
|
32
|
+
* then the associated substitution is returned instead.
|
|
32
33
|
*
|
|
33
|
-
*
|
|
34
|
+
* The substitution is of the form "#attr<N>", where N is a counter starting at 1 and incremented
|
|
35
|
+
* each time a *new* path is seen. So the first substitution returned by this object will inevitably
|
|
36
|
+
* start with "#attr1".*
|
|
37
|
+
*
|
|
38
|
+
* The substitution's default algorithm goes like this:
|
|
39
|
+
* - Throw if the provided input is empty.
|
|
40
|
+
* - Split all path tokens sperated by dots ('.').
|
|
41
|
+
* - For each of them:
|
|
42
|
+
* - Throw if they are an empty string.
|
|
43
|
+
* - They are indexed if a pair of square brackets can be found ('[]'). *No parsing is done
|
|
44
|
+
* within the brackets*. So, even though "toto[ta[t]a]" is an invalid attribute path for DynamoDB,
|
|
45
|
+
* this function will let it slide. The corresponding expression will be rejected by DynamoDB at runtime
|
|
46
|
+
* mfk. Why would you even? Anyway, if the prefix to the opening bracket is empty, throw again.
|
|
47
|
+
* - Generate a corresponding substitution and append in result
|
|
48
|
+
* - Join result subsitutions with dots and return.
|
|
49
|
+
*
|
|
50
|
+
* If the attribute path is a nested item expression, such as "object.inner.stuff", then the
|
|
51
|
+
* function will return "#attr1.#attr2.#attr3" and have registered 3 paths for future use:
|
|
52
|
+
* "object", "inner", and "stuff".
|
|
53
|
+
*
|
|
54
|
+
* If the attribute path is an indexed item expression, such as "list[2]", then the function
|
|
55
|
+
* will return "#attr1[2]" and have registered one path for future use: "list".
|
|
56
|
+
*
|
|
57
|
+
* Every other attribute path is simply replaced by "#attr<N>" and stored as is for future use.
|
|
58
|
+
*
|
|
59
|
+
* If a user wishes to bypass all the above logic and simply register the path as is, such as
|
|
60
|
+
* could be the case if an attribute's name contains a dot, then the `literal` option can be set
|
|
61
|
+
* to true.
|
|
34
62
|
*
|
|
35
63
|
* @param attribute - The path of the attribute to substitute.
|
|
64
|
+
* @param options - The substitution option.
|
|
36
65
|
*
|
|
37
66
|
* @returns The substitution associated with the attribute path.
|
|
38
67
|
*/
|
|
39
|
-
substitute(attribute: AttributePath
|
|
68
|
+
substitute(attribute: AttributePath, options?: {
|
|
69
|
+
literal?: boolean;
|
|
70
|
+
}): PathSubstitution;
|
|
40
71
|
/**
|
|
41
72
|
* Returns a record where the keys are the substitutions generated by this object
|
|
42
73
|
* and the values are the corresponding attribute paths they where generated for.
|
|
@@ -44,6 +75,6 @@ export declare class AttributeNames {
|
|
|
44
75
|
* @returns A mapping of substitutions generated by this object, undefined if none were.
|
|
45
76
|
*/
|
|
46
77
|
getSubstitutions(): Record<PathSubstitution, AttributePath> | undefined;
|
|
47
|
-
private
|
|
78
|
+
private getOrSetNextSubstituteFor;
|
|
48
79
|
static create(): AttributeNames;
|
|
49
80
|
}
|
|
@@ -26,29 +26,76 @@ class AttributeNames {
|
|
|
26
26
|
constructor() {
|
|
27
27
|
this.names = new Map();
|
|
28
28
|
}
|
|
29
|
+
// TODO: the edge case where the path would be something like literal("hello.toto").otherField is still
|
|
30
|
+
// not covered.
|
|
29
31
|
/**
|
|
30
32
|
* Returns a substitution variable for the given attribute path.
|
|
31
33
|
*
|
|
32
34
|
* If the attribute path is seen for the first time by this object, a new substitution is generated,
|
|
33
|
-
* assigned to the attribute path, and returned.
|
|
35
|
+
* it is assigned to the attribute path, and returned. If the attribute path was previously registered,
|
|
36
|
+
* then the associated substitution is returned instead.
|
|
34
37
|
*
|
|
35
|
-
*
|
|
38
|
+
* The substitution is of the form "#attr<N>", where N is a counter starting at 1 and incremented
|
|
39
|
+
* each time a *new* path is seen. So the first substitution returned by this object will inevitably
|
|
40
|
+
* start with "#attr1".*
|
|
41
|
+
*
|
|
42
|
+
* The substitution's default algorithm goes like this:
|
|
43
|
+
* - Throw if the provided input is empty.
|
|
44
|
+
* - Split all path tokens sperated by dots ('.').
|
|
45
|
+
* - For each of them:
|
|
46
|
+
* - Throw if they are an empty string.
|
|
47
|
+
* - They are indexed if a pair of square brackets can be found ('[]'). *No parsing is done
|
|
48
|
+
* within the brackets*. So, even though "toto[ta[t]a]" is an invalid attribute path for DynamoDB,
|
|
49
|
+
* this function will let it slide. The corresponding expression will be rejected by DynamoDB at runtime
|
|
50
|
+
* mfk. Why would you even? Anyway, if the prefix to the opening bracket is empty, throw again.
|
|
51
|
+
* - Generate a corresponding substitution and append in result
|
|
52
|
+
* - Join result subsitutions with dots and return.
|
|
53
|
+
*
|
|
54
|
+
* If the attribute path is a nested item expression, such as "object.inner.stuff", then the
|
|
55
|
+
* function will return "#attr1.#attr2.#attr3" and have registered 3 paths for future use:
|
|
56
|
+
* "object", "inner", and "stuff".
|
|
57
|
+
*
|
|
58
|
+
* If the attribute path is an indexed item expression, such as "list[2]", then the function
|
|
59
|
+
* will return "#attr1[2]" and have registered one path for future use: "list".
|
|
60
|
+
*
|
|
61
|
+
* Every other attribute path is simply replaced by "#attr<N>" and stored as is for future use.
|
|
62
|
+
*
|
|
63
|
+
* If a user wishes to bypass all the above logic and simply register the path as is, such as
|
|
64
|
+
* could be the case if an attribute's name contains a dot, then the `literal` option can be set
|
|
65
|
+
* to true.
|
|
36
66
|
*
|
|
37
67
|
* @param attribute - The path of the attribute to substitute.
|
|
68
|
+
* @param options - The substitution option.
|
|
38
69
|
*
|
|
39
70
|
* @returns The substitution associated with the attribute path.
|
|
40
71
|
*/
|
|
41
|
-
substitute(attribute) {
|
|
72
|
+
substitute(attribute, options) {
|
|
73
|
+
const { literal = false } = options || {};
|
|
42
74
|
if (attribute.length === 0) {
|
|
43
75
|
throw new Error("error substituting attribute: empty attribute path not allowed");
|
|
44
76
|
}
|
|
45
|
-
|
|
77
|
+
if (literal) {
|
|
78
|
+
return this.getOrSetNextSubstituteFor(attribute);
|
|
79
|
+
}
|
|
46
80
|
const result = [];
|
|
47
|
-
for (const token of
|
|
81
|
+
for (const token of attribute.split(".")) {
|
|
48
82
|
if (token.length === 0) {
|
|
49
83
|
throw new Error(`error substituting attribute ${attribute}: empty path token not allowed`);
|
|
50
84
|
}
|
|
51
|
-
|
|
85
|
+
// If it's indexed.
|
|
86
|
+
const match = INDEX_REGEX.exec(token);
|
|
87
|
+
if (match != null) {
|
|
88
|
+
const indexedToken = token.slice(0, match.index);
|
|
89
|
+
if (indexedToken.length === 0) {
|
|
90
|
+
throw new Error(`error substituting attribute ${attribute}: empty path token not allowed`);
|
|
91
|
+
}
|
|
92
|
+
// #attrN substitution will map to the token before the index brackets.
|
|
93
|
+
const pathSubstitute = this.getOrSetNextSubstituteFor(indexedToken);
|
|
94
|
+
// The substitute will be of the form #attrN[<originalIndex>]
|
|
95
|
+
result.push(`${pathSubstitute}${match[1]}`);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const substitute = this.getOrSetNextSubstituteFor(token);
|
|
52
99
|
result.push(substitute);
|
|
53
100
|
}
|
|
54
101
|
return result.join(".");
|
|
@@ -69,14 +116,21 @@ class AttributeNames {
|
|
|
69
116
|
}
|
|
70
117
|
return result;
|
|
71
118
|
}
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
119
|
+
getOrSetNextSubstituteFor(path) {
|
|
120
|
+
const current = this.names.get(path);
|
|
121
|
+
if (current != null) {
|
|
122
|
+
return current;
|
|
123
|
+
}
|
|
124
|
+
const next = `#attr${this.names.size + 1}`;
|
|
125
|
+
this.names.set(path, next);
|
|
126
|
+
return next;
|
|
76
127
|
}
|
|
77
128
|
static create() {
|
|
78
129
|
return new AttributeNames();
|
|
79
130
|
}
|
|
80
131
|
}
|
|
81
132
|
exports.AttributeNames = AttributeNames;
|
|
133
|
+
// REGEX used to find a pair of matching brackets within an attribute path token.
|
|
134
|
+
// The expression starting with the opening bracket all the way to the end of the token is capture in group 1.
|
|
135
|
+
const INDEX_REGEX = /(\[.*\].*)$/;
|
|
82
136
|
//# sourceMappingURL=names.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../../../src/commands/attributes/names.ts"],"names":[],"mappings":";;;AAOA,yJAAyJ;AACzJ,kEAAkE;AAClE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAa,cAAc;IACR,KAAK,CAAuC;IAE7D;QACE,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC1D,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../../../src/commands/attributes/names.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { type ImplicitOperand, type Operand, operand, type RawOperand, } from "./operand.js";
|
|
2
|
-
export { type ImplicitPath, Path, path, type RawPath } from "./path.js";
|
|
2
|
+
export { type ImplicitPath, literal, Path, path, type RawPath, } from "./path.js";
|
|
3
3
|
export { type ImplicitValue, type RawValue, Value, value, } from "./value.js";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.value = exports.Value = exports.path = exports.Path = exports.operand = void 0;
|
|
3
|
+
exports.value = exports.Value = exports.path = exports.Path = exports.literal = exports.operand = void 0;
|
|
4
4
|
var operand_js_1 = require("./operand.js");
|
|
5
5
|
Object.defineProperty(exports, "operand", { enumerable: true, get: function () { return operand_js_1.operand; } });
|
|
6
6
|
var path_js_1 = require("./path.js");
|
|
7
|
+
Object.defineProperty(exports, "literal", { enumerable: true, get: function () { return path_js_1.literal; } });
|
|
7
8
|
Object.defineProperty(exports, "Path", { enumerable: true, get: function () { return path_js_1.Path; } });
|
|
8
9
|
Object.defineProperty(exports, "path", { enumerable: true, get: function () { return path_js_1.path; } });
|
|
9
10
|
var value_js_1 = require("./value.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/index.ts"],"names":[],"mappings":";;;AAAA,2CAKsB;AAFpB,qGAAA,OAAO,OAAA;AAGT,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/index.ts"],"names":[],"mappings":";;;AAAA,2CAKsB;AAFpB,qGAAA,OAAO,OAAA;AAGT,qCAMmB;AAJjB,kGAAA,OAAO,OAAA;AACP,+FAAA,IAAI,OAAA;AACJ,+FAAA,IAAI,OAAA;AAGN,uCAKoB;AAFlB,iGAAA,KAAK,OAAA;AACL,iGAAA,KAAK,OAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AttributePath } from "../../../types.js";
|
|
1
|
+
import { type AttributeName, type AttributePath } from "../../../types.js";
|
|
2
2
|
import type { AttributeNames } from "../../attributes/names.js";
|
|
3
3
|
import type { IOperand } from "./operand.js";
|
|
4
4
|
/**
|
|
@@ -31,6 +31,7 @@ export type RawPath = AttributePath | Path;
|
|
|
31
31
|
*/
|
|
32
32
|
export declare class Path implements IOperand {
|
|
33
33
|
private readonly path;
|
|
34
|
+
private readonly literal;
|
|
34
35
|
private constructor();
|
|
35
36
|
substitute(params: {
|
|
36
37
|
names: AttributeNames;
|
|
@@ -38,7 +39,9 @@ export declare class Path implements IOperand {
|
|
|
38
39
|
/**
|
|
39
40
|
* @private
|
|
40
41
|
*/
|
|
41
|
-
static from(path: AttributePath
|
|
42
|
+
static from(path: AttributePath, options?: {
|
|
43
|
+
literal?: true;
|
|
44
|
+
}): Path;
|
|
42
45
|
/**
|
|
43
46
|
* Turns {@link RawPath} path into a {@link Path} instance.
|
|
44
47
|
*
|
|
@@ -46,22 +49,49 @@ export declare class Path implements IOperand {
|
|
|
46
49
|
* Otherwise, a new {@link Path} instance will be created from the provided
|
|
47
50
|
* argument.
|
|
48
51
|
*
|
|
49
|
-
* @param
|
|
52
|
+
* @param raw - The path to return as is or convert to a {@link Path} instance.
|
|
50
53
|
*
|
|
51
54
|
* @returns The normalized {@link Path} instance.
|
|
52
55
|
*
|
|
53
56
|
* @private
|
|
54
57
|
*/
|
|
55
|
-
static normalize(
|
|
58
|
+
static normalize(raw: RawPath): Path;
|
|
56
59
|
}
|
|
57
60
|
/**
|
|
58
61
|
* Factory function to create a {@link Path}.
|
|
59
62
|
*
|
|
63
|
+
* Client code can use this function to disambiguate the expression.
|
|
64
|
+
* Normally, strings are treated as paths by default in expression constructs,
|
|
65
|
+
* but it can be clearer to write something like `set(path("toto"), path("tata"))`
|
|
66
|
+
* instead of `set("toto", "tata")`, for example.
|
|
67
|
+
*
|
|
60
68
|
* @param path - The path of the attribute this operand represents.
|
|
61
69
|
*
|
|
62
70
|
* @returns A new {@link Path} instance for the provided path.
|
|
63
71
|
*/
|
|
64
72
|
export declare function path(path: AttributePath): Path;
|
|
73
|
+
/**
|
|
74
|
+
* Factory function to create a literal {@link Path}.
|
|
75
|
+
*
|
|
76
|
+
* A literal path does not get parsed before being stringified into an expression
|
|
77
|
+
* attribute name. It is simply used as is. For example, if the name of
|
|
78
|
+
* an attribute contains a dot, such as "not.a.good.idea", then the client code
|
|
79
|
+
* *must* use a {@link literal} to translate it as the following attribute names:
|
|
80
|
+
* {
|
|
81
|
+
* "#attr1": "not.a.good.idea"
|
|
82
|
+
* }
|
|
83
|
+
* Instead of the default of:
|
|
84
|
+
* {
|
|
85
|
+
* "#attr1": "not",
|
|
86
|
+
* "#attr2": "a",
|
|
87
|
+
* "#attr3": "good",
|
|
88
|
+
* "#attr4": "idea"
|
|
89
|
+
* }
|
|
90
|
+
*
|
|
91
|
+
* @param name - The attribute name, taken literally.
|
|
92
|
+
* @returns A new literal {@link Path} instance for the provided name.
|
|
93
|
+
*/
|
|
94
|
+
export declare function literal(name: AttributeName): Path;
|
|
65
95
|
/**
|
|
66
96
|
* A type guard to assess if something is a {@link RawPath}.
|
|
67
97
|
*
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Path = void 0;
|
|
4
4
|
exports.path = path;
|
|
5
|
+
exports.literal = literal;
|
|
5
6
|
exports.isRawPath = isRawPath;
|
|
6
7
|
const types_js_1 = require("../../../types.js");
|
|
7
8
|
/**
|
|
@@ -13,18 +14,22 @@ const types_js_1 = require("../../../types.js");
|
|
|
13
14
|
*/
|
|
14
15
|
class Path {
|
|
15
16
|
path;
|
|
16
|
-
|
|
17
|
+
literal;
|
|
18
|
+
constructor(params) {
|
|
19
|
+
const { path, literal } = params;
|
|
17
20
|
this.path = path;
|
|
21
|
+
this.literal = literal;
|
|
18
22
|
}
|
|
19
23
|
substitute(params) {
|
|
20
24
|
const { names } = params;
|
|
21
|
-
return names.substitute(this.path);
|
|
25
|
+
return names.substitute(this.path, { literal: this.literal });
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
28
|
* @private
|
|
25
29
|
*/
|
|
26
|
-
static from(path) {
|
|
27
|
-
|
|
30
|
+
static from(path, options) {
|
|
31
|
+
const { literal = false } = options ?? {};
|
|
32
|
+
return new Path({ path, literal });
|
|
28
33
|
}
|
|
29
34
|
/**
|
|
30
35
|
* Turns {@link RawPath} path into a {@link Path} instance.
|
|
@@ -33,23 +38,28 @@ class Path {
|
|
|
33
38
|
* Otherwise, a new {@link Path} instance will be created from the provided
|
|
34
39
|
* argument.
|
|
35
40
|
*
|
|
36
|
-
* @param
|
|
41
|
+
* @param raw - The path to return as is or convert to a {@link Path} instance.
|
|
37
42
|
*
|
|
38
43
|
* @returns The normalized {@link Path} instance.
|
|
39
44
|
*
|
|
40
45
|
* @private
|
|
41
46
|
*/
|
|
42
|
-
static normalize(
|
|
43
|
-
if (
|
|
44
|
-
return
|
|
47
|
+
static normalize(raw) {
|
|
48
|
+
if (raw instanceof Path) {
|
|
49
|
+
return raw;
|
|
45
50
|
}
|
|
46
|
-
return Path.from(
|
|
51
|
+
return Path.from(raw);
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
exports.Path = Path;
|
|
50
55
|
/**
|
|
51
56
|
* Factory function to create a {@link Path}.
|
|
52
57
|
*
|
|
58
|
+
* Client code can use this function to disambiguate the expression.
|
|
59
|
+
* Normally, strings are treated as paths by default in expression constructs,
|
|
60
|
+
* but it can be clearer to write something like `set(path("toto"), path("tata"))`
|
|
61
|
+
* instead of `set("toto", "tata")`, for example.
|
|
62
|
+
*
|
|
53
63
|
* @param path - The path of the attribute this operand represents.
|
|
54
64
|
*
|
|
55
65
|
* @returns A new {@link Path} instance for the provided path.
|
|
@@ -57,6 +67,30 @@ exports.Path = Path;
|
|
|
57
67
|
function path(path) {
|
|
58
68
|
return Path.from(path);
|
|
59
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Factory function to create a literal {@link Path}.
|
|
72
|
+
*
|
|
73
|
+
* A literal path does not get parsed before being stringified into an expression
|
|
74
|
+
* attribute name. It is simply used as is. For example, if the name of
|
|
75
|
+
* an attribute contains a dot, such as "not.a.good.idea", then the client code
|
|
76
|
+
* *must* use a {@link literal} to translate it as the following attribute names:
|
|
77
|
+
* {
|
|
78
|
+
* "#attr1": "not.a.good.idea"
|
|
79
|
+
* }
|
|
80
|
+
* Instead of the default of:
|
|
81
|
+
* {
|
|
82
|
+
* "#attr1": "not",
|
|
83
|
+
* "#attr2": "a",
|
|
84
|
+
* "#attr3": "good",
|
|
85
|
+
* "#attr4": "idea"
|
|
86
|
+
* }
|
|
87
|
+
*
|
|
88
|
+
* @param name - The attribute name, taken literally.
|
|
89
|
+
* @returns A new literal {@link Path} instance for the provided name.
|
|
90
|
+
*/
|
|
91
|
+
function literal(name) {
|
|
92
|
+
return Path.from(name, { literal: true });
|
|
93
|
+
}
|
|
60
94
|
/**
|
|
61
95
|
* A type guard to assess if something is a {@link RawPath}.
|
|
62
96
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/path.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/path.ts"],"names":[],"mappings":";;;AA8FA,oBAEC;AAuBD,0BAEC;AASD,8BAEC;AApID,gDAI2B;AA2B3B;;;;;;GAMG;AACH,MAAa,IAAI;IACE,IAAI,CAAgB;IACpB,OAAO,CAAU;IAElC,YAAoB,MAAiD;QACnE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,MAAiC;QAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QACzB,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,IAAmB,EAAE,OAA4B;QAC3D,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,SAAS,CAAC,GAAY;QAC3B,IAAI,GAAG,YAAY,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;CACF;AA1CD,oBA0CC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,IAAI,CAAC,IAAmB;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,OAAO,CAAC,IAAmB;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,SAAS,CAAC,OAAgB;IACxC,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,cAAc,CAAC,OAAgB;IACtC,OAAO,IAAA,yBAAc,EAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,MAAM,CAAC,OAAgB;IAC9B,OAAO,OAAO,YAAY,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -15,7 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.WriteTransaction = exports.UpdateTimeToLive = exports.UpdateItem = exports.Query = exports.PutItem = exports.GetItem = exports.DeleteTable = exports.DeleteItem = exports.CreateTable = void 0;
|
|
18
|
-
__exportStar(require("./attributes/index.js"), exports);
|
|
19
18
|
var create_table_js_1 = require("./create-table.js");
|
|
20
19
|
Object.defineProperty(exports, "CreateTable", { enumerable: true, get: function () { return create_table_js_1.CreateTable; } });
|
|
21
20
|
var delete_item_js_1 = require("./delete-item.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AACpB,mDAA8C;AAArC,4GAAA,UAAU,OAAA;AACnB,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AACpB,yDAAuC;AACvC,6CAAwC;AAA/B,sGAAA,OAAO,OAAA;AA0BhB,6CAAwC;AAA/B,sGAAA,OAAO,OAAA;AAChB,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AACd,mDAA8C;AAArC,4GAAA,UAAU,OAAA;AACnB,mEAA4D;AAAnD,0HAAA,gBAAgB,OAAA;AACzB,+DAA0D;AAAjD,wHAAA,gBAAgB,OAAA"}
|
|
@@ -28,15 +28,46 @@ export declare class AttributeNames {
|
|
|
28
28
|
* Returns a substitution variable for the given attribute path.
|
|
29
29
|
*
|
|
30
30
|
* If the attribute path is seen for the first time by this object, a new substitution is generated,
|
|
31
|
-
* assigned to the attribute path, and returned.
|
|
31
|
+
* it is assigned to the attribute path, and returned. If the attribute path was previously registered,
|
|
32
|
+
* then the associated substitution is returned instead.
|
|
32
33
|
*
|
|
33
|
-
*
|
|
34
|
+
* The substitution is of the form "#attr<N>", where N is a counter starting at 1 and incremented
|
|
35
|
+
* each time a *new* path is seen. So the first substitution returned by this object will inevitably
|
|
36
|
+
* start with "#attr1".*
|
|
37
|
+
*
|
|
38
|
+
* The substitution's default algorithm goes like this:
|
|
39
|
+
* - Throw if the provided input is empty.
|
|
40
|
+
* - Split all path tokens sperated by dots ('.').
|
|
41
|
+
* - For each of them:
|
|
42
|
+
* - Throw if they are an empty string.
|
|
43
|
+
* - They are indexed if a pair of square brackets can be found ('[]'). *No parsing is done
|
|
44
|
+
* within the brackets*. So, even though "toto[ta[t]a]" is an invalid attribute path for DynamoDB,
|
|
45
|
+
* this function will let it slide. The corresponding expression will be rejected by DynamoDB at runtime
|
|
46
|
+
* mfk. Why would you even? Anyway, if the prefix to the opening bracket is empty, throw again.
|
|
47
|
+
* - Generate a corresponding substitution and append in result
|
|
48
|
+
* - Join result subsitutions with dots and return.
|
|
49
|
+
*
|
|
50
|
+
* If the attribute path is a nested item expression, such as "object.inner.stuff", then the
|
|
51
|
+
* function will return "#attr1.#attr2.#attr3" and have registered 3 paths for future use:
|
|
52
|
+
* "object", "inner", and "stuff".
|
|
53
|
+
*
|
|
54
|
+
* If the attribute path is an indexed item expression, such as "list[2]", then the function
|
|
55
|
+
* will return "#attr1[2]" and have registered one path for future use: "list".
|
|
56
|
+
*
|
|
57
|
+
* Every other attribute path is simply replaced by "#attr<N>" and stored as is for future use.
|
|
58
|
+
*
|
|
59
|
+
* If a user wishes to bypass all the above logic and simply register the path as is, such as
|
|
60
|
+
* could be the case if an attribute's name contains a dot, then the `literal` option can be set
|
|
61
|
+
* to true.
|
|
34
62
|
*
|
|
35
63
|
* @param attribute - The path of the attribute to substitute.
|
|
64
|
+
* @param options - The substitution option.
|
|
36
65
|
*
|
|
37
66
|
* @returns The substitution associated with the attribute path.
|
|
38
67
|
*/
|
|
39
|
-
substitute(attribute: AttributePath
|
|
68
|
+
substitute(attribute: AttributePath, options?: {
|
|
69
|
+
literal?: boolean;
|
|
70
|
+
}): PathSubstitution;
|
|
40
71
|
/**
|
|
41
72
|
* Returns a record where the keys are the substitutions generated by this object
|
|
42
73
|
* and the values are the corresponding attribute paths they where generated for.
|
|
@@ -44,6 +75,6 @@ export declare class AttributeNames {
|
|
|
44
75
|
* @returns A mapping of substitutions generated by this object, undefined if none were.
|
|
45
76
|
*/
|
|
46
77
|
getSubstitutions(): Record<PathSubstitution, AttributePath> | undefined;
|
|
47
|
-
private
|
|
78
|
+
private getOrSetNextSubstituteFor;
|
|
48
79
|
static create(): AttributeNames;
|
|
49
80
|
}
|
|
@@ -23,29 +23,76 @@ export class AttributeNames {
|
|
|
23
23
|
constructor() {
|
|
24
24
|
this.names = new Map();
|
|
25
25
|
}
|
|
26
|
+
// TODO: the edge case where the path would be something like literal("hello.toto").otherField is still
|
|
27
|
+
// not covered.
|
|
26
28
|
/**
|
|
27
29
|
* Returns a substitution variable for the given attribute path.
|
|
28
30
|
*
|
|
29
31
|
* If the attribute path is seen for the first time by this object, a new substitution is generated,
|
|
30
|
-
* assigned to the attribute path, and returned.
|
|
32
|
+
* it is assigned to the attribute path, and returned. If the attribute path was previously registered,
|
|
33
|
+
* then the associated substitution is returned instead.
|
|
31
34
|
*
|
|
32
|
-
*
|
|
35
|
+
* The substitution is of the form "#attr<N>", where N is a counter starting at 1 and incremented
|
|
36
|
+
* each time a *new* path is seen. So the first substitution returned by this object will inevitably
|
|
37
|
+
* start with "#attr1".*
|
|
38
|
+
*
|
|
39
|
+
* The substitution's default algorithm goes like this:
|
|
40
|
+
* - Throw if the provided input is empty.
|
|
41
|
+
* - Split all path tokens sperated by dots ('.').
|
|
42
|
+
* - For each of them:
|
|
43
|
+
* - Throw if they are an empty string.
|
|
44
|
+
* - They are indexed if a pair of square brackets can be found ('[]'). *No parsing is done
|
|
45
|
+
* within the brackets*. So, even though "toto[ta[t]a]" is an invalid attribute path for DynamoDB,
|
|
46
|
+
* this function will let it slide. The corresponding expression will be rejected by DynamoDB at runtime
|
|
47
|
+
* mfk. Why would you even? Anyway, if the prefix to the opening bracket is empty, throw again.
|
|
48
|
+
* - Generate a corresponding substitution and append in result
|
|
49
|
+
* - Join result subsitutions with dots and return.
|
|
50
|
+
*
|
|
51
|
+
* If the attribute path is a nested item expression, such as "object.inner.stuff", then the
|
|
52
|
+
* function will return "#attr1.#attr2.#attr3" and have registered 3 paths for future use:
|
|
53
|
+
* "object", "inner", and "stuff".
|
|
54
|
+
*
|
|
55
|
+
* If the attribute path is an indexed item expression, such as "list[2]", then the function
|
|
56
|
+
* will return "#attr1[2]" and have registered one path for future use: "list".
|
|
57
|
+
*
|
|
58
|
+
* Every other attribute path is simply replaced by "#attr<N>" and stored as is for future use.
|
|
59
|
+
*
|
|
60
|
+
* If a user wishes to bypass all the above logic and simply register the path as is, such as
|
|
61
|
+
* could be the case if an attribute's name contains a dot, then the `literal` option can be set
|
|
62
|
+
* to true.
|
|
33
63
|
*
|
|
34
64
|
* @param attribute - The path of the attribute to substitute.
|
|
65
|
+
* @param options - The substitution option.
|
|
35
66
|
*
|
|
36
67
|
* @returns The substitution associated with the attribute path.
|
|
37
68
|
*/
|
|
38
|
-
substitute(attribute) {
|
|
69
|
+
substitute(attribute, options) {
|
|
70
|
+
const { literal = false } = options || {};
|
|
39
71
|
if (attribute.length === 0) {
|
|
40
72
|
throw new Error("error substituting attribute: empty attribute path not allowed");
|
|
41
73
|
}
|
|
42
|
-
|
|
74
|
+
if (literal) {
|
|
75
|
+
return this.getOrSetNextSubstituteFor(attribute);
|
|
76
|
+
}
|
|
43
77
|
const result = [];
|
|
44
|
-
for (const token of
|
|
78
|
+
for (const token of attribute.split(".")) {
|
|
45
79
|
if (token.length === 0) {
|
|
46
80
|
throw new Error(`error substituting attribute ${attribute}: empty path token not allowed`);
|
|
47
81
|
}
|
|
48
|
-
|
|
82
|
+
// If it's indexed.
|
|
83
|
+
const match = INDEX_REGEX.exec(token);
|
|
84
|
+
if (match != null) {
|
|
85
|
+
const indexedToken = token.slice(0, match.index);
|
|
86
|
+
if (indexedToken.length === 0) {
|
|
87
|
+
throw new Error(`error substituting attribute ${attribute}: empty path token not allowed`);
|
|
88
|
+
}
|
|
89
|
+
// #attrN substitution will map to the token before the index brackets.
|
|
90
|
+
const pathSubstitute = this.getOrSetNextSubstituteFor(indexedToken);
|
|
91
|
+
// The substitute will be of the form #attrN[<originalIndex>]
|
|
92
|
+
result.push(`${pathSubstitute}${match[1]}`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const substitute = this.getOrSetNextSubstituteFor(token);
|
|
49
96
|
result.push(substitute);
|
|
50
97
|
}
|
|
51
98
|
return result.join(".");
|
|
@@ -66,13 +113,20 @@ export class AttributeNames {
|
|
|
66
113
|
}
|
|
67
114
|
return result;
|
|
68
115
|
}
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
116
|
+
getOrSetNextSubstituteFor(path) {
|
|
117
|
+
const current = this.names.get(path);
|
|
118
|
+
if (current != null) {
|
|
119
|
+
return current;
|
|
120
|
+
}
|
|
121
|
+
const next = `#attr${this.names.size + 1}`;
|
|
122
|
+
this.names.set(path, next);
|
|
123
|
+
return next;
|
|
73
124
|
}
|
|
74
125
|
static create() {
|
|
75
126
|
return new AttributeNames();
|
|
76
127
|
}
|
|
77
128
|
}
|
|
129
|
+
// REGEX used to find a pair of matching brackets within an attribute path token.
|
|
130
|
+
// The expression starting with the opening bracket all the way to the end of the token is capture in group 1.
|
|
131
|
+
const INDEX_REGEX = /(\[.*\].*)$/;
|
|
78
132
|
//# sourceMappingURL=names.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../../../src/commands/attributes/names.ts"],"names":[],"mappings":"AAOA,yJAAyJ;AACzJ,kEAAkE;AAClE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,cAAc;IACR,KAAK,CAAuC;IAE7D;QACE,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC1D,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../../../src/commands/attributes/names.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { type ImplicitOperand, type Operand, operand, type RawOperand, } from "./operand.js";
|
|
2
|
-
export { type ImplicitPath, Path, path, type RawPath } from "./path.js";
|
|
2
|
+
export { type ImplicitPath, literal, Path, path, type RawPath, } from "./path.js";
|
|
3
3
|
export { type ImplicitValue, type RawValue, Value, value, } from "./value.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,OAAO,GAER,MAAM,cAAc,CAAC;AACtB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,OAAO,GAER,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,OAAO,EACP,IAAI,EACJ,IAAI,GAEL,MAAM,WAAW,CAAC;AACnB,OAAO,EAGL,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AttributePath } from "../../../types.js";
|
|
1
|
+
import { type AttributeName, type AttributePath } from "../../../types.js";
|
|
2
2
|
import type { AttributeNames } from "../../attributes/names.js";
|
|
3
3
|
import type { IOperand } from "./operand.js";
|
|
4
4
|
/**
|
|
@@ -31,6 +31,7 @@ export type RawPath = AttributePath | Path;
|
|
|
31
31
|
*/
|
|
32
32
|
export declare class Path implements IOperand {
|
|
33
33
|
private readonly path;
|
|
34
|
+
private readonly literal;
|
|
34
35
|
private constructor();
|
|
35
36
|
substitute(params: {
|
|
36
37
|
names: AttributeNames;
|
|
@@ -38,7 +39,9 @@ export declare class Path implements IOperand {
|
|
|
38
39
|
/**
|
|
39
40
|
* @private
|
|
40
41
|
*/
|
|
41
|
-
static from(path: AttributePath
|
|
42
|
+
static from(path: AttributePath, options?: {
|
|
43
|
+
literal?: true;
|
|
44
|
+
}): Path;
|
|
42
45
|
/**
|
|
43
46
|
* Turns {@link RawPath} path into a {@link Path} instance.
|
|
44
47
|
*
|
|
@@ -46,22 +49,49 @@ export declare class Path implements IOperand {
|
|
|
46
49
|
* Otherwise, a new {@link Path} instance will be created from the provided
|
|
47
50
|
* argument.
|
|
48
51
|
*
|
|
49
|
-
* @param
|
|
52
|
+
* @param raw - The path to return as is or convert to a {@link Path} instance.
|
|
50
53
|
*
|
|
51
54
|
* @returns The normalized {@link Path} instance.
|
|
52
55
|
*
|
|
53
56
|
* @private
|
|
54
57
|
*/
|
|
55
|
-
static normalize(
|
|
58
|
+
static normalize(raw: RawPath): Path;
|
|
56
59
|
}
|
|
57
60
|
/**
|
|
58
61
|
* Factory function to create a {@link Path}.
|
|
59
62
|
*
|
|
63
|
+
* Client code can use this function to disambiguate the expression.
|
|
64
|
+
* Normally, strings are treated as paths by default in expression constructs,
|
|
65
|
+
* but it can be clearer to write something like `set(path("toto"), path("tata"))`
|
|
66
|
+
* instead of `set("toto", "tata")`, for example.
|
|
67
|
+
*
|
|
60
68
|
* @param path - The path of the attribute this operand represents.
|
|
61
69
|
*
|
|
62
70
|
* @returns A new {@link Path} instance for the provided path.
|
|
63
71
|
*/
|
|
64
72
|
export declare function path(path: AttributePath): Path;
|
|
73
|
+
/**
|
|
74
|
+
* Factory function to create a literal {@link Path}.
|
|
75
|
+
*
|
|
76
|
+
* A literal path does not get parsed before being stringified into an expression
|
|
77
|
+
* attribute name. It is simply used as is. For example, if the name of
|
|
78
|
+
* an attribute contains a dot, such as "not.a.good.idea", then the client code
|
|
79
|
+
* *must* use a {@link literal} to translate it as the following attribute names:
|
|
80
|
+
* {
|
|
81
|
+
* "#attr1": "not.a.good.idea"
|
|
82
|
+
* }
|
|
83
|
+
* Instead of the default of:
|
|
84
|
+
* {
|
|
85
|
+
* "#attr1": "not",
|
|
86
|
+
* "#attr2": "a",
|
|
87
|
+
* "#attr3": "good",
|
|
88
|
+
* "#attr4": "idea"
|
|
89
|
+
* }
|
|
90
|
+
*
|
|
91
|
+
* @param name - The attribute name, taken literally.
|
|
92
|
+
* @returns A new literal {@link Path} instance for the provided name.
|
|
93
|
+
*/
|
|
94
|
+
export declare function literal(name: AttributeName): Path;
|
|
65
95
|
/**
|
|
66
96
|
* A type guard to assess if something is a {@link RawPath}.
|
|
67
97
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNativeString } from "../../../types.js";
|
|
1
|
+
import { isNativeString, } from "../../../types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Represents an attribute path operand in an expression.
|
|
4
4
|
*
|
|
@@ -8,18 +8,22 @@ import { isNativeString } from "../../../types.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export class Path {
|
|
10
10
|
path;
|
|
11
|
-
|
|
11
|
+
literal;
|
|
12
|
+
constructor(params) {
|
|
13
|
+
const { path, literal } = params;
|
|
12
14
|
this.path = path;
|
|
15
|
+
this.literal = literal;
|
|
13
16
|
}
|
|
14
17
|
substitute(params) {
|
|
15
18
|
const { names } = params;
|
|
16
|
-
return names.substitute(this.path);
|
|
19
|
+
return names.substitute(this.path, { literal: this.literal });
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
22
|
* @private
|
|
20
23
|
*/
|
|
21
|
-
static from(path) {
|
|
22
|
-
|
|
24
|
+
static from(path, options) {
|
|
25
|
+
const { literal = false } = options ?? {};
|
|
26
|
+
return new Path({ path, literal });
|
|
23
27
|
}
|
|
24
28
|
/**
|
|
25
29
|
* Turns {@link RawPath} path into a {@link Path} instance.
|
|
@@ -28,22 +32,27 @@ export class Path {
|
|
|
28
32
|
* Otherwise, a new {@link Path} instance will be created from the provided
|
|
29
33
|
* argument.
|
|
30
34
|
*
|
|
31
|
-
* @param
|
|
35
|
+
* @param raw - The path to return as is or convert to a {@link Path} instance.
|
|
32
36
|
*
|
|
33
37
|
* @returns The normalized {@link Path} instance.
|
|
34
38
|
*
|
|
35
39
|
* @private
|
|
36
40
|
*/
|
|
37
|
-
static normalize(
|
|
38
|
-
if (
|
|
39
|
-
return
|
|
41
|
+
static normalize(raw) {
|
|
42
|
+
if (raw instanceof Path) {
|
|
43
|
+
return raw;
|
|
40
44
|
}
|
|
41
|
-
return Path.from(
|
|
45
|
+
return Path.from(raw);
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
/**
|
|
45
49
|
* Factory function to create a {@link Path}.
|
|
46
50
|
*
|
|
51
|
+
* Client code can use this function to disambiguate the expression.
|
|
52
|
+
* Normally, strings are treated as paths by default in expression constructs,
|
|
53
|
+
* but it can be clearer to write something like `set(path("toto"), path("tata"))`
|
|
54
|
+
* instead of `set("toto", "tata")`, for example.
|
|
55
|
+
*
|
|
47
56
|
* @param path - The path of the attribute this operand represents.
|
|
48
57
|
*
|
|
49
58
|
* @returns A new {@link Path} instance for the provided path.
|
|
@@ -51,6 +60,30 @@ export class Path {
|
|
|
51
60
|
export function path(path) {
|
|
52
61
|
return Path.from(path);
|
|
53
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Factory function to create a literal {@link Path}.
|
|
65
|
+
*
|
|
66
|
+
* A literal path does not get parsed before being stringified into an expression
|
|
67
|
+
* attribute name. It is simply used as is. For example, if the name of
|
|
68
|
+
* an attribute contains a dot, such as "not.a.good.idea", then the client code
|
|
69
|
+
* *must* use a {@link literal} to translate it as the following attribute names:
|
|
70
|
+
* {
|
|
71
|
+
* "#attr1": "not.a.good.idea"
|
|
72
|
+
* }
|
|
73
|
+
* Instead of the default of:
|
|
74
|
+
* {
|
|
75
|
+
* "#attr1": "not",
|
|
76
|
+
* "#attr2": "a",
|
|
77
|
+
* "#attr3": "good",
|
|
78
|
+
* "#attr4": "idea"
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* @param name - The attribute name, taken literally.
|
|
82
|
+
* @returns A new literal {@link Path} instance for the provided name.
|
|
83
|
+
*/
|
|
84
|
+
export function literal(name) {
|
|
85
|
+
return Path.from(name, { literal: true });
|
|
86
|
+
}
|
|
54
87
|
/**
|
|
55
88
|
* A type guard to assess if something is a {@link RawPath}.
|
|
56
89
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/path.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../../../../src/commands/expressions/operands/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,GACf,MAAM,mBAAmB,CAAC;AA2B3B;;;;;;GAMG;AACH,MAAM,OAAO,IAAI;IACE,IAAI,CAAgB;IACpB,OAAO,CAAU;IAElC,YAAoB,MAAiD;QACnE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,MAAiC;QAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QACzB,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,IAAmB,EAAE,OAA4B;QAC3D,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,SAAS,CAAC,GAAY;QAC3B,IAAI,GAAG,YAAY,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,IAAI,CAAC,IAAmB;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,OAAO,CAAC,IAAmB;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,cAAc,CAAC,OAAgB;IACtC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,MAAM,CAAC,OAAgB;IAC9B,OAAO,OAAO,YAAY,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AA0BxC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
|