@kensio/yulin 1.21.27 → 1.21.28
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/dist/config/eslint/cffjs2.eslint.config.js +4 -0
- package/dist/service/cloudformation/parameters/sim-cfn-parameter-list-type.d.ts +7 -0
- package/dist/service/cloudformation/parameters/sim-cfn-parameter-list-type.js +9 -0
- package/dist/service/cloudformation/parameters/sim-cfn-parameter-values.d.ts +10 -0
- package/dist/service/cloudformation/parameters/sim-cfn-parameter-values.js +20 -0
- package/dist/service/cloudformation/parameters/sim-cfn-parameters.type.d.ts +7 -5
- package/dist/service/cloudformation/parameters/store/sim-cfn-parameter-store-value-type.js +2 -1
- package/dist/service/cloudformation/template/node/fn/join/sim-cfn-fn-join.d.ts +19 -14
- package/dist/service/cloudformation/template/node/fn/join/sim-cfn-fn-join.js +47 -28
- package/dist/service/cloudformation/template/parse/fn/join/sim-cfn-fn-join-parser.d.ts +7 -4
- package/dist/service/cloudformation/template/parse/fn/join/sim-cfn-fn-join-parser.js +11 -7
- package/docs/serve/README.md +1 -1
- package/docs/services/cloudformation/README.md +28 -5
- package/docs/services/dynamodb/README.md +2 -2
- package/docs/services/s3/README.md +1 -1
- package/docs/services/sqs/README.md +1 -1
- package/package.json +2 -2
|
@@ -13,6 +13,10 @@ export default defineConfig({
|
|
|
13
13
|
files: ["**/*.cff.js"],
|
|
14
14
|
extends: [tseslint.configs.disableTypeChecked],
|
|
15
15
|
languageOptions: {
|
|
16
|
+
// The typescript-eslint rules below read scope information only its own
|
|
17
|
+
// parser produces. Under ESLint's default parser, `no-unused-vars` takes
|
|
18
|
+
// every reference for a type-only one and reports each variable.
|
|
19
|
+
parser: tseslint.parser,
|
|
16
20
|
parserOptions: {
|
|
17
21
|
projectService: false,
|
|
18
22
|
},
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a declared Parameter `Type` holds a list.
|
|
3
|
+
*
|
|
4
|
+
* `CommaDelimitedList` and every `List<...>` type do, whatever the member
|
|
5
|
+
* type. A `Ref` to one resolves to a list of strings, `List<Number>` included.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isSimCfnParameterListType(type: string | undefined): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a declared Parameter `Type` holds a list.
|
|
3
|
+
*
|
|
4
|
+
* `CommaDelimitedList` and every `List<...>` type do, whatever the member
|
|
5
|
+
* type. A `Ref` to one resolves to a list of strings, `List<Number>` included.
|
|
6
|
+
*/
|
|
7
|
+
export function isSimCfnParameterListType(type) {
|
|
8
|
+
return type === "CommaDelimitedList" || (type?.startsWith("List<") ?? false);
|
|
9
|
+
}
|
|
@@ -13,6 +13,9 @@ interface SimCfnParameterValuesProperties {
|
|
|
13
13
|
* the command wins over a template `Default`, and a Parameter declared as a
|
|
14
14
|
* Parameter Store value type reads whichever of the two it ended up with as the
|
|
15
15
|
* name to read.
|
|
16
|
+
*
|
|
17
|
+
* A `CommaDelimitedList` or `List<...>` Parameter is given its value as one
|
|
18
|
+
* comma-separated string, and holds it as the list of members.
|
|
16
19
|
*/
|
|
17
20
|
export declare class SimCfnParameterValues {
|
|
18
21
|
private readonly values;
|
|
@@ -29,5 +32,12 @@ export declare class SimCfnParameterValues {
|
|
|
29
32
|
* `Default`.
|
|
30
33
|
*/
|
|
31
34
|
private recordDefaults;
|
|
35
|
+
/**
|
|
36
|
+
* Split the value of each list-typed Parameter on its commas.
|
|
37
|
+
*
|
|
38
|
+
* Each member is trimmed of the spaces around it, as CloudFormation trims
|
|
39
|
+
* them. A value with no commas is a list of one.
|
|
40
|
+
*/
|
|
41
|
+
private splitLists;
|
|
32
42
|
}
|
|
33
43
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSimCfnParameterListType } from "./sim-cfn-parameter-list-type.js";
|
|
1
2
|
import { SimCfnParameterStoreValues } from "./store/sim-cfn-parameter-store-values.js";
|
|
2
3
|
/**
|
|
3
4
|
* The runtime value of every Parameter a Stack was created with.
|
|
@@ -6,6 +7,9 @@ import { SimCfnParameterStoreValues } from "./store/sim-cfn-parameter-store-valu
|
|
|
6
7
|
* the command wins over a template `Default`, and a Parameter declared as a
|
|
7
8
|
* Parameter Store value type reads whichever of the two it ended up with as the
|
|
8
9
|
* name to read.
|
|
10
|
+
*
|
|
11
|
+
* A `CommaDelimitedList` or `List<...>` Parameter is given its value as one
|
|
12
|
+
* comma-separated string, and holds it as the list of members.
|
|
9
13
|
*/
|
|
10
14
|
export class SimCfnParameterValues {
|
|
11
15
|
values;
|
|
@@ -15,6 +19,7 @@ export class SimCfnParameterValues {
|
|
|
15
19
|
this.storeValues = new SimCfnParameterStoreValues({ store });
|
|
16
20
|
this.values = new Map(Object.entries(supplied));
|
|
17
21
|
this.recordDefaults(definitions);
|
|
22
|
+
this.splitLists(definitions);
|
|
18
23
|
this.storeValues.applyTo(this.values, definitions);
|
|
19
24
|
}
|
|
20
25
|
/** Every Parameter that resolved to a stand-in value. */
|
|
@@ -39,4 +44,19 @@ export class SimCfnParameterValues {
|
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Split the value of each list-typed Parameter on its commas.
|
|
49
|
+
*
|
|
50
|
+
* Each member is trimmed of the spaces around it, as CloudFormation trims
|
|
51
|
+
* them. A value with no commas is a list of one.
|
|
52
|
+
*/
|
|
53
|
+
splitLists(definitions) {
|
|
54
|
+
for (const [parameterName, definition] of definitions) {
|
|
55
|
+
const value = this.values.get(parameterName);
|
|
56
|
+
if (typeof value === "string" &&
|
|
57
|
+
isSimCfnParameterListType(definition.Type)) {
|
|
58
|
+
this.values.set(parameterName, value.split(",").map((member) => member.trim()));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
42
62
|
}
|
|
@@ -5,9 +5,10 @@ import type { SimCfnParameterStoreReader } from "./store/sim-cfn-parameter-store
|
|
|
5
5
|
* defaults and Parameter Store reads have been applied.
|
|
6
6
|
*
|
|
7
7
|
* A Parameter is given its value as a string, because AWS CloudFormation
|
|
8
|
-
* command inputs provide ParameterValue as one. A
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
8
|
+
* command inputs provide ParameterValue as one. A `CommaDelimitedList` or
|
|
9
|
+
* `List<...>` Parameter resolves to that string split into a list. So does an
|
|
10
|
+
* `AWS::SSM::Parameter::Value<List<String>>` Parameter, which is given a
|
|
11
|
+
* parameter name and splits the value stored under it. A resolved value can be
|
|
11
12
|
* either.
|
|
12
13
|
*/
|
|
13
14
|
export type SimCloudFormationParameterValue = string | string[];
|
|
@@ -61,8 +62,9 @@ export type SimCfnParametersContext = Pick<SimCfnParametersProperties, "definiti
|
|
|
61
62
|
*
|
|
62
63
|
* Most fields are recorded for structural typing/documentation. Runtime
|
|
63
64
|
* behavior applies string Default values when a command does not provide an
|
|
64
|
-
* explicit Parameter value,
|
|
65
|
-
* Type
|
|
65
|
+
* explicit Parameter value, splits the value of a `CommaDelimitedList` or
|
|
66
|
+
* `List<...>` Type, and reads an `AWS::SSM::Parameter::Value<...>` Type from
|
|
67
|
+
* simulated Parameter Store.
|
|
66
68
|
*/
|
|
67
69
|
export interface SimCfnParameterDefinition {
|
|
68
70
|
readonly Type?: string | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSimCfnParameterListType } from "../sim-cfn-parameter-list-type.js";
|
|
1
2
|
/** The Parameter type that holds a Parameter Store name. */
|
|
2
3
|
const parameterStoreValuePrefix = "AWS::SSM::Parameter::Value<";
|
|
3
4
|
/**
|
|
@@ -14,6 +15,6 @@ export function simCfnParameterStoreValueType(declaredType) {
|
|
|
14
15
|
}
|
|
15
16
|
const innerType = declaredType.slice(parameterStoreValuePrefix.length, -1);
|
|
16
17
|
return {
|
|
17
|
-
list: innerType
|
|
18
|
+
list: isSimCfnParameterListType(innerType),
|
|
18
19
|
};
|
|
19
20
|
}
|
|
@@ -9,19 +9,25 @@ import type { SimCfnResolveContext } from "../../../resolve/sim-cfn-resolve-cont
|
|
|
9
9
|
* {
|
|
10
10
|
* "Fn::Join": ["-", ["a", "b", { "Ref": "Name" }]]
|
|
11
11
|
* }
|
|
12
|
+
*
|
|
13
|
+
* The values may also come from one function that returns the whole list:
|
|
14
|
+
*
|
|
15
|
+
* {
|
|
16
|
+
* "Fn::Join": [",", { "Fn::GetAtt": ["Zone", "NameServers"] }]
|
|
17
|
+
* }
|
|
12
18
|
*/
|
|
13
19
|
export declare class SimCfnFnJoin extends SimCfnNode {
|
|
14
20
|
private readonly delimiter;
|
|
15
21
|
private readonly values;
|
|
16
|
-
constructor(delimiter: string, values:
|
|
22
|
+
constructor(delimiter: string, values: SimCfnNode);
|
|
17
23
|
/**
|
|
18
|
-
* Resolve
|
|
24
|
+
* Resolve the values and join them with the delimiter.
|
|
19
25
|
*
|
|
20
|
-
* Joining happens only when
|
|
21
|
-
* value is still an unresolved expression (for
|
|
22
|
-
* during the up-front pass before Resources exist),
|
|
23
|
-
* itself in template form. A later resolution pass can
|
|
24
|
-
* referenced Resources are available.
|
|
26
|
+
* Joining happens only when the values have resolved to a list of strings.
|
|
27
|
+
* If the list, or any value in it, is still an unresolved expression (for
|
|
28
|
+
* example a Resource `Ref` during the up-front pass before Resources exist),
|
|
29
|
+
* this node re-emits itself in template form. A later resolution pass can
|
|
30
|
+
* finish it once the referenced Resources are available.
|
|
25
31
|
*
|
|
26
32
|
* A dynamic reference can be assembled out of the joined values, as CDK
|
|
27
33
|
* writes one whenever the secret it reads sits in the same Stack: the
|
|
@@ -32,16 +38,15 @@ export declare class SimCfnFnJoin extends SimCfnNode {
|
|
|
32
38
|
*/
|
|
33
39
|
resolve(context: SimCfnResolveContext): SimCfnTemplateValue;
|
|
34
40
|
/**
|
|
35
|
-
* Collect referenced names from
|
|
41
|
+
* Collect referenced names from the values.
|
|
36
42
|
*/
|
|
37
43
|
referencedNames(): string[];
|
|
38
|
-
private resolveValue;
|
|
39
44
|
/**
|
|
40
|
-
*
|
|
45
|
+
* Refuse a value that can never become a string.
|
|
41
46
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
47
|
+
* A string joins now, and an unresolved expression may join on a later
|
|
48
|
+
* pass. Anything else (a number, a nested list, a plain object) is a type
|
|
49
|
+
* error, as CloudFormation joins a list of strings only.
|
|
45
50
|
*/
|
|
46
|
-
private
|
|
51
|
+
private assertJoinable;
|
|
47
52
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SimCfnNode } from "../../sim-cfn-node.js";
|
|
2
|
+
import { isSimCfnUnresolvedExpression } from "../../../value/sim-cfn-unresolved-expression.js";
|
|
2
3
|
/**
|
|
3
4
|
* Simulated CloudFormation `Fn::Join` intrinsic function.
|
|
4
5
|
*
|
|
@@ -7,6 +8,12 @@ import { SimCfnNode } from "../../sim-cfn-node.js";
|
|
|
7
8
|
* {
|
|
8
9
|
* "Fn::Join": ["-", ["a", "b", { "Ref": "Name" }]]
|
|
9
10
|
* }
|
|
11
|
+
*
|
|
12
|
+
* The values may also come from one function that returns the whole list:
|
|
13
|
+
*
|
|
14
|
+
* {
|
|
15
|
+
* "Fn::Join": [",", { "Fn::GetAtt": ["Zone", "NameServers"] }]
|
|
16
|
+
* }
|
|
10
17
|
*/
|
|
11
18
|
export class SimCfnFnJoin extends SimCfnNode {
|
|
12
19
|
delimiter;
|
|
@@ -17,13 +24,13 @@ export class SimCfnFnJoin extends SimCfnNode {
|
|
|
17
24
|
this.values = values;
|
|
18
25
|
}
|
|
19
26
|
/**
|
|
20
|
-
* Resolve
|
|
27
|
+
* Resolve the values and join them with the delimiter.
|
|
21
28
|
*
|
|
22
|
-
* Joining happens only when
|
|
23
|
-
* value is still an unresolved expression (for
|
|
24
|
-
* during the up-front pass before Resources exist),
|
|
25
|
-
* itself in template form. A later resolution pass can
|
|
26
|
-
* referenced Resources are available.
|
|
29
|
+
* Joining happens only when the values have resolved to a list of strings.
|
|
30
|
+
* If the list, or any value in it, is still an unresolved expression (for
|
|
31
|
+
* example a Resource `Ref` during the up-front pass before Resources exist),
|
|
32
|
+
* this node re-emits itself in template form. A later resolution pass can
|
|
33
|
+
* finish it once the referenced Resources are available.
|
|
27
34
|
*
|
|
28
35
|
* A dynamic reference can be assembled out of the joined values, as CDK
|
|
29
36
|
* writes one whenever the secret it reads sits in the same Stack: the
|
|
@@ -33,37 +40,49 @@ export class SimCfnFnJoin extends SimCfnNode {
|
|
|
33
40
|
* out of its variables.
|
|
34
41
|
*/
|
|
35
42
|
resolve(context) {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
|
|
43
|
+
const values = this.values.resolve(context);
|
|
44
|
+
if (isSimCfnUnresolvedExpression(values)) {
|
|
45
|
+
return { "Fn::Join": [this.delimiter, values] };
|
|
46
|
+
}
|
|
47
|
+
if (!Array.isArray(values)) {
|
|
48
|
+
throw new TypeError(`Sim CloudFormation Fn::Join values must resolve to a list, got ${describe(values)}`);
|
|
49
|
+
}
|
|
50
|
+
for (const value of values) {
|
|
51
|
+
this.assertJoinable(value);
|
|
52
|
+
}
|
|
53
|
+
if (values.every((value) => typeof value === "string")) {
|
|
54
|
+
const joined = values.join(this.delimiter);
|
|
39
55
|
return context.dynamicReferences?.substitute(joined) ?? joined;
|
|
40
56
|
}
|
|
41
|
-
return { "Fn::Join": [this.delimiter,
|
|
57
|
+
return { "Fn::Join": [this.delimiter, values] };
|
|
42
58
|
}
|
|
43
59
|
/**
|
|
44
|
-
* Collect referenced names from
|
|
60
|
+
* Collect referenced names from the values.
|
|
45
61
|
*/
|
|
46
62
|
referencedNames() {
|
|
47
|
-
return this.values.
|
|
48
|
-
}
|
|
49
|
-
resolveValue(value, context) {
|
|
50
|
-
const resolved = value.resolve(context);
|
|
51
|
-
if (typeof resolved === "string") {
|
|
52
|
-
return resolved;
|
|
53
|
-
}
|
|
54
|
-
if (this.isDeferredExpression(resolved)) {
|
|
55
|
-
return resolved;
|
|
56
|
-
}
|
|
57
|
-
throw new TypeError(`Sim CloudFormation Fn::Join values must each resolve to a string, got ${typeof resolved}`);
|
|
63
|
+
return this.values.referencedNames();
|
|
58
64
|
}
|
|
59
65
|
/**
|
|
60
|
-
*
|
|
66
|
+
* Refuse a value that can never become a string.
|
|
61
67
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
68
|
+
* A string joins now, and an unresolved expression may join on a later
|
|
69
|
+
* pass. Anything else (a number, a nested list, a plain object) is a type
|
|
70
|
+
* error, as CloudFormation joins a list of strings only.
|
|
65
71
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
assertJoinable(value) {
|
|
73
|
+
if (typeof value === "string" || isSimCfnUnresolvedExpression(value)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
throw new TypeError(`Sim CloudFormation Fn::Join values must each resolve to a string, got ${describe(value)}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Name a resolved value's type for an error message, telling a list and a
|
|
81
|
+
* null apart from an object.
|
|
82
|
+
*/
|
|
83
|
+
function describe(value) {
|
|
84
|
+
if (Array.isArray(value)) {
|
|
85
|
+
return "list";
|
|
68
86
|
}
|
|
87
|
+
return value === null ? "null" : typeof value;
|
|
69
88
|
}
|
|
@@ -10,10 +10,13 @@ import type { SimCfnValueParser } from "../../value/sim-cfn-value-parser.type.js
|
|
|
10
10
|
* "Fn::Join": ["-", ["a", { "Ref": "Name" }]]
|
|
11
11
|
* }
|
|
12
12
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* The values argument goes through the recursive value parser. It may be a
|
|
14
|
+
* literal list, whose entries may themselves be literals, Refs or other
|
|
15
|
+
* intrinsic functions, or a function that returns a whole list (such as
|
|
16
|
+
* `Fn::GetAtt` on a hosted zone's `NameServers`, or `Fn::Split`). Whether it
|
|
17
|
+
* resolves to a list of strings is a resolution-time question, so it belongs
|
|
18
|
+
* to the node. A string, number or boolean in its place can never become a
|
|
19
|
+
* list, and is refused here.
|
|
17
20
|
*/
|
|
18
21
|
export declare class SimCfnFnJoinParser {
|
|
19
22
|
private readonly valueParser;
|
|
@@ -8,10 +8,13 @@ import { SimCfnFnJoin as SimCfnFunctionJoin } from "../../../node/fn/join/sim-cf
|
|
|
8
8
|
* "Fn::Join": ["-", ["a", { "Ref": "Name" }]]
|
|
9
9
|
* }
|
|
10
10
|
*
|
|
11
|
-
* The
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The values argument goes through the recursive value parser. It may be a
|
|
12
|
+
* literal list, whose entries may themselves be literals, Refs or other
|
|
13
|
+
* intrinsic functions, or a function that returns a whole list (such as
|
|
14
|
+
* `Fn::GetAtt` on a hosted zone's `NameServers`, or `Fn::Split`). Whether it
|
|
15
|
+
* resolves to a list of strings is a resolution-time question, so it belongs
|
|
16
|
+
* to the node. A string, number or boolean in its place can never become a
|
|
17
|
+
* list, and is refused here.
|
|
15
18
|
*/
|
|
16
19
|
export class SimCfnFnJoinParser {
|
|
17
20
|
valueParser;
|
|
@@ -29,9 +32,10 @@ export class SimCfnFnJoinParser {
|
|
|
29
32
|
if (typeof delimiter !== "string") {
|
|
30
33
|
throw new TypeError("Sim CloudFormation Fn::Join delimiter must be a string");
|
|
31
34
|
}
|
|
32
|
-
if (
|
|
33
|
-
throw new TypeError("Sim CloudFormation Fn::Join values must be
|
|
35
|
+
if (typeof values !== "object" || values === null) {
|
|
36
|
+
throw new TypeError("Sim CloudFormation Fn::Join values must be a list or a function " +
|
|
37
|
+
"that returns one");
|
|
34
38
|
}
|
|
35
|
-
return new SimCfnFunctionJoin(delimiter,
|
|
39
|
+
return new SimCfnFunctionJoin(delimiter, this.valueParser.parse(values));
|
|
36
40
|
}
|
|
37
41
|
}
|
package/docs/serve/README.md
CHANGED
|
@@ -415,6 +415,6 @@ service guide lists its supported commands.
|
|
|
415
415
|
- `yulin watch` does not preserve simulated state across a restart or reload changed Lambda and
|
|
416
416
|
CloudFront Function code inside the current process.
|
|
417
417
|
- The shared AWS API endpoint refuses unsupported protocols and operations with `501 Not
|
|
418
|
-
Implemented`.
|
|
418
|
+
Implemented`.
|
|
419
419
|
- Some service functionality is available only through `SimAws` or SDK interception. Check the
|
|
420
420
|
relevant service guide before depending on access through the local endpoint.
|
|
@@ -948,8 +948,20 @@ console.log(
|
|
|
948
948
|
|
|
949
949
|
A parameter with no supplied value takes the template default, when the template has one.
|
|
950
950
|
|
|
951
|
-
A
|
|
952
|
-
|
|
951
|
+
A `CommaDelimitedList` or `List<...>` parameter (`List<String>`, `List<Number>`,
|
|
952
|
+
`List<AWS::EC2::Subnet::Id>` and the rest) is given one comma-separated string. A `Ref` to it
|
|
953
|
+
resolves to the list of members, each trimmed of the spaces around it. `Fn::Join` and `Fn::Select`
|
|
954
|
+
read that list as they read any other:
|
|
955
|
+
|
|
956
|
+
```json
|
|
957
|
+
{ "Fn::Join": ["-", { "Ref": "Names" }] }
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
With `Names` declared as a `CommaDelimitedList` and given `a, b, c`, this resolves to `a-b-c`. The
|
|
961
|
+
members of a `List<Number>` are strings, as CloudFormation gives them.
|
|
962
|
+
|
|
963
|
+
The `AWS::SSM::Parameter::Value<...>` types hold a Parameter Store name and resolve to the value
|
|
964
|
+
stored under it. See
|
|
953
965
|
[reading a parameter through a template Parameter](https://yulinsim.dev/services/ssm/#reading-a-parameter-through-a-template-parameter).
|
|
954
966
|
Every other type is accepted and its value used as written, with no validation of the value against
|
|
955
967
|
the type.
|
|
@@ -1217,6 +1229,17 @@ await simAws.cloudFormation().deployTemplate({
|
|
|
1217
1229
|
});
|
|
1218
1230
|
```
|
|
1219
1231
|
|
|
1232
|
+
The second argument may also be a function that returns the whole list. CDK writes this for
|
|
1233
|
+
`Fn.join(",", zone.hostedZoneNameServers)`:
|
|
1234
|
+
|
|
1235
|
+
```json
|
|
1236
|
+
{ "Fn::Join": [",", { "Fn::GetAtt": ["Zone", "NameServers"] }] }
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
`Fn::Split`, an `Fn::FindInMap` of a list value, `Fn::If` and a `Ref` to a list parameter can supply
|
|
1240
|
+
the list the same way. A list that resolves to anything but strings fails the deployment. That
|
|
1241
|
+
includes a number, and a list nested inside the list (CloudFormation joins one level only).
|
|
1242
|
+
|
|
1220
1243
|
### `Fn::Sub`
|
|
1221
1244
|
|
|
1222
1245
|
```typescript sim-cloudformation-fn-sub
|
|
@@ -4545,9 +4568,9 @@ Each service's own docs describe what its resource types support.
|
|
|
4545
4568
|
would reject as well. The simulator just rejects them later rather than up front.
|
|
4546
4569
|
- `Fn::If` is a condition function inside the `Conditions` section, and is not a value an
|
|
4547
4570
|
`Fn::Equals` can compare. Real CloudFormation allows only `Ref` and `Fn::FindInMap` there.
|
|
4548
|
-
- `Fn::Split` and `Fn::Select` accept any argument that resolves to the type they
|
|
4549
|
-
CloudFormation allows only a named set of functions inside each of them. A template the
|
|
4550
|
-
resolves may still be one CloudFormation rejects.
|
|
4571
|
+
- `Fn::Join`, `Fn::Split` and `Fn::Select` accept any argument that resolves to the type they
|
|
4572
|
+
need. Real CloudFormation allows only a named set of functions inside each of them. A template the
|
|
4573
|
+
simulator resolves may still be one CloudFormation rejects.
|
|
4551
4574
|
- The SAM transform is expanded for `AWS::Serverless::Function`, `AWS::Serverless::SimpleTable`,
|
|
4552
4575
|
`AWS::Serverless::HttpApi` and `AWS::Serverless::Api`. Every other `AWS::Serverless::*` resource
|
|
4553
4576
|
type is recorded as unsupported. `Api`, `HttpApi`, `SQS`, `DynamoDB`, `SNS`, `S3`, `Cognito`,
|
|
@@ -3940,7 +3940,7 @@ is written.
|
|
|
3940
3940
|
`AWS::DynamoDB::Table` path does, with the replica's `TableClass`, `DeletionProtectionEnabled` and
|
|
3941
3941
|
`Tags` read off it, the table's writes and the replica's reads put back together into one
|
|
3942
3942
|
provisioned capacity for the table and for each global secondary index, and `Ref`, `Fn::GetAtt …
|
|
3943
|
-
Arn`, `Fn::GetAtt … StreamArn` and `Fn::GetAtt … TableId` answering. A CDK `TableV2` stack deploys
|
|
3943
|
+
Arn`, `Fn::GetAtt … StreamArn` and `Fn::GetAtt … TableId` answering. A CDK `TableV2` stack deploys
|
|
3944
3944
|
through it without hand-editing.
|
|
3945
3945
|
- SDK interception, and an intercepted `DynamoDBClient` or `DynamoDBStreamsClient` reaches the
|
|
3946
3946
|
simulation.
|
|
@@ -4035,7 +4035,7 @@ Arn`, `Fn::GetAtt … StreamArn` and `Fn::GetAtt … TableId` answering. A CDK `
|
|
|
4035
4035
|
- Time to live expiry is dispatched by moving the clock through `simAws.clock()`, not by real time
|
|
4036
4036
|
elapsing. An item whose window goes by while a running-mode clock tracks the host stays where it
|
|
4037
4037
|
is until something moves the clock. A simulated DynamoDB constructed standalone as `new
|
|
4038
|
-
SimDynamoDb()` has no clock control at all. No item there ever expires.
|
|
4038
|
+
SimDynamoDb()` has no clock control at all. No item there ever expires.
|
|
4039
4039
|
- A Lambda event source mapping is the only simulated service integration that consumes a stream.
|
|
4040
4040
|
Anything else reads one through the Streams API itself. A Kinesis Data Streams destination is
|
|
4041
4041
|
absent.
|
|
@@ -1079,7 +1079,7 @@ A delete on a versioned Bucket raises `s3:ObjectRemoved:DeleteMarkerCreated` rat
|
|
|
1079
1079
|
|
|
1080
1080
|
- MFA delete is refused with `NotImplemented` rather than stored. Nothing here could enforce it, and
|
|
1081
1081
|
a Bucket reporting a protection it does not apply is worse than one that says so. `MFADelete:
|
|
1082
|
-
"Disabled"` is taken, and any other value is refused with `InvalidArgument`.
|
|
1082
|
+
"Disabled"` is taken, and any other value is refused with `InvalidArgument`.
|
|
1083
1083
|
- A `versionId` in a `CopySource` is still refused with `NotImplemented`. A copy reads the current
|
|
1084
1084
|
version.
|
|
1085
1085
|
- `NoncurrentVersionTransitions` is stored and unread, because storage classes are left out. An
|
|
@@ -1214,7 +1214,7 @@ Current documented limitations:
|
|
|
1214
1214
|
- A Lambda event source mapping polls one batch at a time. Real Lambda runs several pollers at once
|
|
1215
1215
|
and scales them with the queue, and what that concurrency does to ordering is invisible here. See
|
|
1216
1216
|
[simulated Lambda](https://yulinsim.dev/services/lambda/#triggering-a-function-from-an-sqs-queue "Simulated Lambda event
|
|
1217
|
-
source mapping docs") for the rest of the mapping limitations.
|
|
1217
|
+
source mapping docs") for the rest of the mapping limitations.
|
|
1218
1218
|
- `AWS::SQS::Queue` and `AWS::SQS::QueuePolicy` are the SQS resource types CloudFormation creates.
|
|
1219
1219
|
Any other is reported as unsupported and skipped. A queue attribute outside the range real SQS
|
|
1220
1220
|
accepts fails the resource, and a property it has no behaviour for is recorded and the queue
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kensio/yulin",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.28",
|
|
4
4
|
"description": "AWS system behaviour simulation for isolated unit testing",
|
|
5
5
|
"repository": "https://github.com/KensioSoftware/yulin",
|
|
6
6
|
"homepage": "https://yulinsim.dev/",
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
"hyparquet": "^1.29.2",
|
|
300
300
|
"hyparquet-writer": "^0.16.9",
|
|
301
301
|
"node-sql-parser": "^5.4.0",
|
|
302
|
-
"oxfmt": "^0.
|
|
302
|
+
"oxfmt": "^0.72.0",
|
|
303
303
|
"oxlint": "^1.77.0",
|
|
304
304
|
"oxlint-tsgolint": "^7.0.2001",
|
|
305
305
|
"semantic-release": "25.0.9",
|