@kensio/yulin 1.21.6 → 1.21.7

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.
Files changed (37) hide show
  1. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-creator.js +1 -0
  2. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.d.ts +4 -0
  3. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.js +26 -1
  4. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-creator.js +3 -1
  5. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.d.ts +0 -7
  6. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.js +0 -20
  7. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.d.ts +13 -0
  8. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.js +59 -0
  9. package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.d.ts +1 -1
  10. package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.js +1 -1
  11. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +1 -1
  12. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.d.ts +3 -2
  13. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +25 -3
  14. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-creator.js +1 -0
  15. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.d.ts +9 -4
  16. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.js +18 -6
  17. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.d.ts +10 -0
  18. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.js +16 -1
  19. package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-creator.js +1 -1
  20. package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.d.ts +11 -6
  21. package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.js +18 -9
  22. package/docs/README.md +33 -4
  23. package/docs/ai-skill/README.md +52 -54
  24. package/docs/cli/README.md +84 -94
  25. package/docs/factories/README.md +42 -54
  26. package/docs/lint/README.md +41 -67
  27. package/docs/non-aws-dependencies/README.md +72 -168
  28. package/docs/sdk/README.md +97 -98
  29. package/docs/serve/README.md +192 -898
  30. package/docs/services/eventbridge/README.md +10 -2
  31. package/docs/services/lambda/README.md +7 -1
  32. package/docs/services/sns/README.md +13 -7
  33. package/docs/services/ssm/README.md +6 -4
  34. package/docs/terraform/README.md +108 -126
  35. package/docs/time/README.md +80 -120
  36. package/llms.txt +1 -1
  37. package/package.json +1 -1
@@ -24,6 +24,7 @@ export class SimCfnEventBusCreator {
24
24
  properties,
25
25
  });
26
26
  busProperties.refuseUnsimulated();
27
+ busProperties.recordIgnoredProperties();
27
28
  const name = busProperties.name();
28
29
  const description = busProperties.description();
29
30
  return await simCfnEventBridgeResourceCreation(eventBusResourceType, resource.logicalId, async () => {
@@ -27,6 +27,10 @@ export declare class SimCfnEventBusProperties {
27
27
  * Refuse what this simulation does not model, naming the property.
28
28
  */
29
29
  refuseUnsimulated(): void;
30
+ /**
31
+ * Record the properties the bus is created without acting on.
32
+ */
33
+ recordIgnoredProperties(): void;
30
34
  private propertyError;
31
35
  }
32
36
  export {};
@@ -19,8 +19,23 @@ const unsimulatedProperties = [
19
19
  ["EventSourceName", "partner event buses are not simulated"],
20
20
  ["KmsKeyIdentifier", "events are not encrypted with a customer managed key"],
21
21
  ["LogConfig", "event bus logging is not simulated"],
22
- ["Tags", "event bus tags are not simulated"],
23
22
  ];
23
+ /**
24
+ * What a template can say about an event bus that this simulation has nothing
25
+ * to act on, and why.
26
+ *
27
+ * `Tags` is the whole list, and it is recorded rather than refused. A bus
28
+ * behaves the same way with a tag and without one, and a CDK app calling
29
+ * `Tags.of(app).add(...)` tags every bus in it.
30
+ */
31
+ const ignoredPropertyReasons = new Map([
32
+ [
33
+ "Tags",
34
+ `${eventBusResourceType} property Tags is not simulated, so the bus is ` +
35
+ "created without them. Nothing reads them back and nothing is grouped " +
36
+ "or billed by them.",
37
+ ],
38
+ ]);
24
39
  /**
25
40
  * Reads AWS::Events::EventBus properties into the shape CreateEventBus takes.
26
41
  */
@@ -71,6 +86,16 @@ export class SimCfnEventBusProperties {
71
86
  }
72
87
  }
73
88
  }
89
+ /**
90
+ * Record the properties the bus is created without acting on.
91
+ */
92
+ recordIgnoredProperties() {
93
+ for (const [property, reason] of ignoredPropertyReasons) {
94
+ if (this.properties.has(property)) {
95
+ this.resource.ignoreProperty(property, reason);
96
+ }
97
+ }
98
+ }
74
99
  propertyError(reason) {
75
100
  return simCfnEventBridgeResourceError(eventBusResourceType, this.resource.logicalId, reason);
76
101
  }
@@ -2,6 +2,7 @@ import { assertDefined } from "../../../../util/type-guard/defined.js";
2
2
  import { simCfnEventBridgeResourceCreation } from "../sim-cfn-event-bridge-resource-error.js";
3
3
  import { eventRuleResourceType } from "../sim-cfn-event-bridge-resource-types.js";
4
4
  import { SimCfnEventRuleProperties } from "./sim-cfn-event-rule-properties.js";
5
+ import { recordIgnoredEventRuleProperties, refuseUnsimulatedEventRuleProperties, } from "./sim-cfn-event-rule-unsimulated-properties.js";
5
6
  /**
6
7
  * Creates simulated rules from AWS::Events::Rule Resources.
7
8
  *
@@ -27,7 +28,8 @@ export class SimCfnEventRuleCreator {
27
28
  resource,
28
29
  properties,
29
30
  });
30
- ruleProperties.refuseUnsimulated();
31
+ refuseUnsimulatedEventRuleProperties(resource, properties);
32
+ recordIgnoredEventRuleProperties(resource, properties);
31
33
  const name = ruleProperties.name();
32
34
  const busName = ruleProperties.busName();
33
35
  const targets = ruleProperties.targets();
@@ -48,13 +48,6 @@ export declare class SimCfnEventRuleProperties {
48
48
  * The rule's inline targets.
49
49
  */
50
50
  targets(): readonly SimCfnEventRuleTarget[];
51
- /**
52
- * Refuse what this simulation does not model, naming the property.
53
- *
54
- * Both are asked by key rather than by value, so a template writing `null`
55
- * for one is refused rather than read as having left it out.
56
- */
57
- refuseUnsimulated(): void;
58
51
  private stringProperty;
59
52
  private propertyError;
60
53
  }
@@ -89,26 +89,6 @@ export class SimCfnEventRuleProperties {
89
89
  targets() {
90
90
  return simCfnEventRuleTargets(this.properties.get("Targets"), (reason) => this.propertyError(reason));
91
91
  }
92
- /**
93
- * Refuse what this simulation does not model, naming the property.
94
- *
95
- * Both are asked by key rather than by value, so a template writing `null`
96
- * for one is refused rather than read as having left it out.
97
- */
98
- refuseUnsimulated() {
99
- if (this.properties.has("RoleArn")) {
100
- throw this.propertyError("RoleArn is not simulated, so the Resource is refused rather than " +
101
- "deployed without it: a rule reaches its target as the EventBridge " +
102
- "service principal, admitted by the target's own resource policy");
103
- }
104
- // Rule tags never reach PutRule, which is the one place that would
105
- // otherwise refuse them, so a tagged rule would deploy and quietly lose
106
- // its tags.
107
- if (this.properties.has("Tags")) {
108
- throw this.propertyError("Tags are not simulated, so the Resource is refused rather than " +
109
- "deployed without them");
110
- }
111
- }
112
92
  stringProperty(name) {
113
93
  const value = this.properties.get(name);
114
94
  if (value === undefined) {
@@ -0,0 +1,13 @@
1
+ import type { SimCfnResource } from "../../../cloudformation/resource/sim-cfn-resource.js";
2
+ import type { SimCfnTemplateValueRecord } from "../../../cloudformation/template/value/sim-cfn-template-value.js";
3
+ /**
4
+ * Refuse what this simulation does not model, naming the property.
5
+ *
6
+ * Asked by key rather than by value, so a template writing `null` for one of
7
+ * these is refused rather than read as having left it out.
8
+ */
9
+ export declare function refuseUnsimulatedEventRuleProperties(resource: SimCfnResource, properties: SimCfnTemplateValueRecord): void;
10
+ /**
11
+ * Record the properties the rule is created without acting on.
12
+ */
13
+ export declare function recordIgnoredEventRuleProperties(resource: SimCfnResource, properties: SimCfnTemplateValueRecord): void;
@@ -0,0 +1,59 @@
1
+ import { simCfnEventBridgeResourceError } from "../sim-cfn-event-bridge-resource-error.js";
2
+ import { eventRuleResourceType } from "../sim-cfn-event-bridge-resource-types.js";
3
+ /**
4
+ * What a template can say about a rule that this simulation does not model,
5
+ * and why each one fails the Resource.
6
+ *
7
+ * `RoleArn` is the whole list. A rule reaches its target as the EventBridge
8
+ * service principal, admitted by the target's own resource policy, so a rule
9
+ * deployed with a role would sit in a test looking as though the role decided
10
+ * something.
11
+ */
12
+ const refusedPropertyReasons = new Map([
13
+ [
14
+ "RoleArn",
15
+ "RoleArn is not simulated, so the Resource is refused rather than " +
16
+ "deployed without it: a rule reaches its target as the EventBridge " +
17
+ "service principal, admitted by the target's own resource policy",
18
+ ],
19
+ ]);
20
+ /**
21
+ * What a template can say about a rule that this simulation has nothing to act
22
+ * on, and why each one is recorded rather than refused.
23
+ *
24
+ * `Tags` is the whole list. Rule tags never reach `PutRule`, so the record is
25
+ * the only place a tagged rule says it lost them. A rule routes the same
26
+ * events with a tag and without one, and a CDK app calling
27
+ * `Tags.of(app).add(...)` tags every rule in it.
28
+ */
29
+ const ignoredPropertyReasons = new Map([
30
+ [
31
+ "Tags",
32
+ `${eventRuleResourceType} property Tags is not simulated, so the rule is ` +
33
+ "created without them. Nothing reads them back and nothing is grouped " +
34
+ "or billed by them.",
35
+ ],
36
+ ]);
37
+ /**
38
+ * Refuse what this simulation does not model, naming the property.
39
+ *
40
+ * Asked by key rather than by value, so a template writing `null` for one of
41
+ * these is refused rather than read as having left it out.
42
+ */
43
+ export function refuseUnsimulatedEventRuleProperties(resource, properties) {
44
+ for (const [property, reason] of refusedPropertyReasons) {
45
+ if (Object.hasOwn(properties, property)) {
46
+ throw simCfnEventBridgeResourceError(eventRuleResourceType, resource.logicalId, reason);
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Record the properties the rule is created without acting on.
52
+ */
53
+ export function recordIgnoredEventRuleProperties(resource, properties) {
54
+ for (const [property, reason] of ignoredPropertyReasons) {
55
+ if (Object.hasOwn(properties, property)) {
56
+ resource.ignoreProperty(property, reason);
57
+ }
58
+ }
59
+ }
@@ -15,7 +15,7 @@ export declare function simCfnEventBridgeResourceError(resourceType: string, log
15
15
  * Every Resource type here goes through the ordinary EventBridge commands, so
16
16
  * what a template may ask for is decided once, by simulated EventBridge, rather
17
17
  * than again in the CloudFormation layer. What that leaves out is where the
18
- * request came from: a deployment failing with `Rule tags are not simulated`
18
+ * request came from: a deployment failing with `Rule pattern is not valid`
19
19
  * says nothing about which Resource asked for it. Only EventBridge's own errors
20
20
  * are renamed, so a refusal the CloudFormation layer decided keeps the wording
21
21
  * it was written with.
@@ -20,7 +20,7 @@ export function simCfnEventBridgeResourceError(resourceType, logicalId, reason,
20
20
  * Every Resource type here goes through the ordinary EventBridge commands, so
21
21
  * what a template may ask for is decided once, by simulated EventBridge, rather
22
22
  * than again in the CloudFormation layer. What that leaves out is where the
23
- * request came from: a deployment failing with `Rule tags are not simulated`
23
+ * request came from: a deployment failing with `Rule pattern is not valid`
24
24
  * says nothing about which Resource asked for it. Only EventBridge's own errors
25
25
  * are renamed, so a refusal the CloudFormation layer decided keeps the wording
26
26
  * it was written with.
@@ -31,7 +31,7 @@ export class SimCfnLambdaEventSourceMappingProperties {
31
31
  */
32
32
  createInput() {
33
33
  const eventSourceArn = this.parser.requiredString(this.resource, this.properties["EventSourceArn"], "EventSourceArn");
34
- assertSimulatedEventSourceMappingProperties(this.resource.logicalId, this.properties);
34
+ assertSimulatedEventSourceMappingProperties(this.resource, this.properties);
35
35
  return {
36
36
  EventSourceArn: eventSourceArn,
37
37
  FunctionName: simCfnLambdaTargetFunctionName(this.parser.requiredString(this.resource, this.properties["FunctionName"], "FunctionName")),
@@ -1,3 +1,4 @@
1
+ import type { SimCfnResource } from "../../../cloudformation/resource/sim-cfn-resource.js";
1
2
  import type { SimCfnTemplateValueRecord } from "../../../cloudformation/template/value/sim-cfn-template-value.js";
2
3
  /**
3
4
  * Build the error a property of an AWS::Lambda::EventSourceMapping Resource is
@@ -11,6 +12,6 @@ import type { SimCfnTemplateValueRecord } from "../../../cloudformation/template
11
12
  export declare function eventSourceMappingPropertyError(logicalId: string, reason: string): Error;
12
13
  /**
13
14
  * Refuse everything about an AWS::Lambda::EventSourceMapping Resource that is
14
- * not simulated.
15
+ * not simulated, and record what the mapping is created without.
15
16
  */
16
- export declare function assertSimulatedEventSourceMappingProperties(logicalId: string, properties: SimCfnTemplateValueRecord): void;
17
+ export declare function assertSimulatedEventSourceMappingProperties(resource: SimCfnResource, properties: SimCfnTemplateValueRecord): void;
@@ -44,10 +44,26 @@ const unsimulatedPropertyNames = new Set([
44
44
  "SelfManagedEventSource",
45
45
  "SelfManagedKafkaEventSourceConfig",
46
46
  "SourceAccessConfigurations",
47
- "Tags",
48
47
  "Topics",
49
48
  "TumblingWindowInSeconds",
50
49
  ]);
50
+ /**
51
+ * Real AWS::Lambda::EventSourceMapping properties this simulation has nothing
52
+ * to act on and no reason to fail a stack over.
53
+ *
54
+ * `Tags` is the whole list. The mapping is created without them and the
55
+ * omission is recorded against the Resource. A mapping delivers the same
56
+ * records with a tag and without one, and a CDK app calling
57
+ * `Tags.of(app).add(...)` tags every mapping in it.
58
+ */
59
+ const ignoredPropertyReasons = new Map([
60
+ [
61
+ "Tags",
62
+ "AWS::Lambda::EventSourceMapping property Tags is not simulated, so the " +
63
+ "mapping is created without them. Nothing reads them back and nothing " +
64
+ "is grouped or billed by them.",
65
+ ],
66
+ ]);
51
67
  /**
52
68
  * Build the error a property of an AWS::Lambda::EventSourceMapping Resource is
53
69
  * refused with.
@@ -62,10 +78,16 @@ export function eventSourceMappingPropertyError(logicalId, reason) {
62
78
  }
63
79
  /**
64
80
  * Refuse everything about an AWS::Lambda::EventSourceMapping Resource that is
65
- * not simulated.
81
+ * not simulated, and record what the mapping is created without.
66
82
  */
67
- export function assertSimulatedEventSourceMappingProperties(logicalId, properties) {
83
+ export function assertSimulatedEventSourceMappingProperties(resource, properties) {
84
+ const logicalId = resource.logicalId;
68
85
  for (const name of Object.keys(properties)) {
86
+ const ignoredReason = ignoredPropertyReasons.get(name);
87
+ if (ignoredReason !== undefined) {
88
+ resource.ignoreProperty(name, ignoredReason);
89
+ continue;
90
+ }
69
91
  if (unsimulatedPropertyNames.has(name)) {
70
92
  throw eventSourceMappingPropertyError(logicalId, `${name} is a real AWS::Lambda::EventSourceMapping property that ` +
71
93
  "this simulation does not simulate, so it is refused rather than " +
@@ -23,6 +23,7 @@ export class SimCfnSnsTopicCreator {
23
23
  resource,
24
24
  properties,
25
25
  });
26
+ topicProperties.recordIgnoredProperties();
26
27
  const name = topicProperties.name();
27
28
  const attributes = topicProperties.attributes();
28
29
  const inline = topicProperties.inlineSubscriptions();
@@ -43,13 +43,18 @@ export declare class SimCfnSnsTopicProperties {
43
43
  * The subscriptions the topic declares inside itself.
44
44
  */
45
45
  inlineSubscriptions(): readonly SimCfnSnsInlineSubscription[];
46
+ /**
47
+ * Record the properties the topic is created without acting on.
48
+ */
49
+ recordIgnoredProperties(): void;
46
50
  /**
47
51
  * Whether a property is handed to CreateTopic as an attribute.
48
52
  *
49
- * The two properties the CloudFormation layer reads itself are not. The rest
50
- * are refused as they are reached: the ones with a reason of their own with
51
- * that reason, and anything else as a property AWS::SNS::Topic does not have,
52
- * which is how real CloudFormation answers one too.
53
+ * The two properties the CloudFormation layer reads itself are not, and
54
+ * neither are the ones recorded as ignored. The rest are refused as they are
55
+ * reached: the ones with a reason of their own with that reason, and
56
+ * anything else as a property AWS::SNS::Topic does not have, which is how
57
+ * real CloudFormation answers one too.
53
58
  */
54
59
  private isAttributeProperty;
55
60
  private propertyError;
@@ -3,7 +3,7 @@ import { simCfnSnsResourceError } from "../sim-cfn-sns-resource-error.js";
3
3
  import { snsTopicResourceType } from "../sim-cfn-sns-resource-types.js";
4
4
  import { simCfnSnsInlineSubscriptions, } from "./sim-cfn-sns-inline-subscriptions.js";
5
5
  import { SimCfnSnsTopicName } from "./sim-cfn-sns-topic-name.js";
6
- import { attributePropertyNames, topicNamePropertyName, topicSubscriptionPropertyName, unsimulatedPropertyReasons, } from "./sim-cfn-sns-topic-property-names.js";
6
+ import { attributePropertyNames, ignoredPropertyReasons, topicNamePropertyName, topicSubscriptionPropertyName, unsimulatedPropertyReasons, } from "./sim-cfn-sns-topic-property-names.js";
7
7
  /**
8
8
  * Reads AWS::SNS::Topic CloudFormation properties into the shape CreateTopic
9
9
  * takes.
@@ -63,17 +63,29 @@ export class SimCfnSnsTopicProperties {
63
63
  inlineSubscriptions() {
64
64
  return simCfnSnsInlineSubscriptions(this.resource.logicalId, this.properties.get(topicSubscriptionPropertyName));
65
65
  }
66
+ /**
67
+ * Record the properties the topic is created without acting on.
68
+ */
69
+ recordIgnoredProperties() {
70
+ for (const [property, reason] of ignoredPropertyReasons) {
71
+ if (this.properties.has(property)) {
72
+ this.resource.ignoreProperty(property, reason);
73
+ }
74
+ }
75
+ }
66
76
  /**
67
77
  * Whether a property is handed to CreateTopic as an attribute.
68
78
  *
69
- * The two properties the CloudFormation layer reads itself are not. The rest
70
- * are refused as they are reached: the ones with a reason of their own with
71
- * that reason, and anything else as a property AWS::SNS::Topic does not have,
72
- * which is how real CloudFormation answers one too.
79
+ * The two properties the CloudFormation layer reads itself are not, and
80
+ * neither are the ones recorded as ignored. The rest are refused as they are
81
+ * reached: the ones with a reason of their own with that reason, and
82
+ * anything else as a property AWS::SNS::Topic does not have, which is how
83
+ * real CloudFormation answers one too.
73
84
  */
74
85
  isAttributeProperty(name) {
75
86
  if (name === topicNamePropertyName ||
76
- name === topicSubscriptionPropertyName) {
87
+ name === topicSubscriptionPropertyName ||
88
+ ignoredPropertyReasons.has(name)) {
77
89
  return false;
78
90
  }
79
91
  if (attributePropertyNames.has(name)) {
@@ -28,3 +28,13 @@ export declare const attributePropertyNames: ReadonlySet<string>;
28
28
  * become fifteen separate attributes.
29
29
  */
30
30
  export declare const unsimulatedPropertyReasons: ReadonlyMap<string, string>;
31
+ /**
32
+ * The real AWS::SNS::Topic properties this simulation has nothing to act on
33
+ * and no reason to fail a stack over.
34
+ *
35
+ * `Tags` is the whole list. The topic is created without them and the omission
36
+ * is recorded against the Resource. A topic behaves the same way with a tag
37
+ * and without one, and a CDK app calling `Tags.of(app).add(...)` tags every
38
+ * topic in it.
39
+ */
40
+ export declare const ignoredPropertyReasons: ReadonlyMap<string, string>;
@@ -47,5 +47,20 @@ export const unsimulatedPropertyReasons = new Map([
47
47
  "DeliveryStatusLogging",
48
48
  "delivery status logging writes to CloudWatch Logs, which is not simulated",
49
49
  ],
50
- ["Tags", "no simulated service reads a topic tag"],
50
+ ]);
51
+ /**
52
+ * The real AWS::SNS::Topic properties this simulation has nothing to act on
53
+ * and no reason to fail a stack over.
54
+ *
55
+ * `Tags` is the whole list. The topic is created without them and the omission
56
+ * is recorded against the Resource. A topic behaves the same way with a tag
57
+ * and without one, and a CDK app calling `Tags.of(app).add(...)` tags every
58
+ * topic in it.
59
+ */
60
+ export const ignoredPropertyReasons = new Map([
61
+ [
62
+ "Tags",
63
+ "AWS::SNS::Topic property Tags is not simulated, so the topic is created " +
64
+ "without them. No simulated service reads a topic tag.",
65
+ ],
51
66
  ]);
@@ -28,6 +28,7 @@ export class SimCfnSsmParameterCreator {
28
28
  properties,
29
29
  });
30
30
  const name = parameterProperties.name();
31
+ parameterProperties.recordIgnoredTags();
31
32
  await this.ssm.putParameter({
32
33
  input: {
33
34
  Name: name,
@@ -38,7 +39,6 @@ export class SimCfnSsmParameterCreator {
38
39
  AllowedPattern: parameterProperties.allowedPattern(),
39
40
  DataType: parameterProperties.dataType(),
40
41
  Policies: parameterProperties.policies(),
41
- Tags: parameterProperties.tags(),
42
42
  },
43
43
  }, options);
44
44
  const parameter = this.ssm.findParameter(name);
@@ -1,6 +1,5 @@
1
1
  import type { SimCfnResource } from "../../../cloudformation/resource/sim-cfn-resource.js";
2
2
  import type { SimCfnTemplateValueRecord } from "../../../cloudformation/template/value/sim-cfn-template-value.js";
3
- import type { SimSsmTag } from "../../command/parameter/parameter.command.js";
4
3
  interface SimCfnSsmParameterPropertiesProperties {
5
4
  readonly resource: SimCfnResource;
6
5
  readonly properties: SimCfnTemplateValueRecord;
@@ -60,13 +59,19 @@ export declare class SimCfnSsmParameterProperties {
60
59
  */
61
60
  policies(): string | undefined;
62
61
  /**
63
- * The parameter Tags, which PutParameter refuses.
62
+ * Record the tags the parameter is written without.
64
63
  *
65
- * CloudFormation carries these as a map of names to values for this
66
- * Resource type, rather than the list of Key/Value pairs most Resource
67
- * types use, so they are turned into the list shape PutParameter takes.
64
+ * `Tags` is the one difference from `PutParameter`, which refuses it
65
+ * outright. A template's tags are usually the whole stack's, and a CDK app
66
+ * calling `Tags.of(app).add(...)` tags every parameter in it. The parameter
67
+ * holds the same value either way, so the deploy stands and the omission is
68
+ * recorded.
69
+ *
70
+ * The shape is still read, because CloudFormation carries these as a map of
71
+ * names to values for this Resource type and a template AWS refuses should
72
+ * not deploy here.
68
73
  */
69
- tags(): readonly SimSsmTag[] | undefined;
74
+ recordIgnoredTags(): void;
70
75
  private string;
71
76
  private stringValue;
72
77
  private propertyError;
@@ -88,23 +88,32 @@ export class SimCfnSsmParameterProperties {
88
88
  return this.string(this.properties["Policies"], "Policies");
89
89
  }
90
90
  /**
91
- * The parameter Tags, which PutParameter refuses.
91
+ * Record the tags the parameter is written without.
92
92
  *
93
- * CloudFormation carries these as a map of names to values for this
94
- * Resource type, rather than the list of Key/Value pairs most Resource
95
- * types use, so they are turned into the list shape PutParameter takes.
93
+ * `Tags` is the one difference from `PutParameter`, which refuses it
94
+ * outright. A template's tags are usually the whole stack's, and a CDK app
95
+ * calling `Tags.of(app).add(...)` tags every parameter in it. The parameter
96
+ * holds the same value either way, so the deploy stands and the omission is
97
+ * recorded.
98
+ *
99
+ * The shape is still read, because CloudFormation carries these as a map of
100
+ * names to values for this Resource type and a template AWS refuses should
101
+ * not deploy here.
96
102
  */
97
- tags() {
103
+ recordIgnoredTags() {
98
104
  const tags = this.properties["Tags"];
99
105
  if (tags === undefined) {
100
- return undefined;
106
+ return;
101
107
  }
102
108
  if (typeof tags !== "object" || tags === null || Array.isArray(tags)) {
103
109
  throw this.propertyError("Tags must be an object");
104
110
  }
105
- return Object.entries(tags).map(([key, value]) => {
106
- return { Key: key, Value: this.stringValue(value, `Tags.${key}`) };
107
- });
111
+ for (const [key, value] of Object.entries(tags)) {
112
+ this.stringValue(value, `Tags.${key}`);
113
+ }
114
+ this.resource.ignoreProperty("Tags", "AWS::SSM::Parameter property Tags is not simulated, so the parameter " +
115
+ "is written without them. Nothing reads them back and no " +
116
+ "aws:ResourceTag condition key matches them.");
108
117
  }
109
118
  string(value, name) {
110
119
  if (value === undefined) {
package/docs/README.md CHANGED
@@ -1,7 +1,36 @@
1
- # Simulated AWS usage documentation
1
+ # Yulin documentation
2
2
 
3
- This directory contains area-specific documentation for Yulin. Each page explains the simulated
4
- behaviour and includes example code that can be copied into tests or local development scripts.
3
+ Yulin runs simulated AWS services inside a Node.js process. Tests can use AWS SDK clients,
4
+ CloudFormation templates, or direct service calls without connecting to AWS. Each `SimAws` instance
5
+ holds its own state in memory.
6
+
7
+ Yulin implements selected AWS behaviour. The service pages describe what each simulation supports
8
+ and where it differs from AWS.
9
+
10
+ ## Install Yulin
11
+
12
+ ```bash
13
+ npm install --save-dev @kensio/yulin
14
+ ```
15
+
16
+ ## Choose how to use Yulin
17
+
18
+ Start with [AWS SDK interception](https://yulinsim.dev/sdk/) when the code under test already uses an
19
+ AWS SDK client. Yulin intercepts the client's `send` calls and returns responses from a simulated
20
+ service. The application code continues to use the AWS SDK normally.
21
+
22
+ Use [event factories](https://yulinsim.dev/factories/) when a test calls a handler directly and only
23
+ needs an AWS event object. The factories fill in fields that the test does not care about.
24
+
25
+ Use [CloudFormation](https://yulinsim.dev/services/cloudformation/) to build a simulation from a
26
+ template. This also works with templates synthesized by AWS CDK and AWS SAM.
27
+
28
+ Use the [localhost server](https://yulinsim.dev/serve/) when the code runs in another process or
29
+ sends HTTP requests. The [AWS CLI guide](https://yulinsim.dev/cli/) explains how to point AWS CLI
30
+ commands at the same endpoint.
31
+
32
+ Read [simulated time](https://yulinsim.dev/time/) when a test needs to advance a schedule, expire a
33
+ credential, or run other work that depends on time passing.
5
34
 
6
35
  ## Service documentation
7
36
 
@@ -42,7 +71,7 @@ behaviour and includes example code that can be copied into tests or local devel
42
71
  - [STS](https://yulinsim.dev/services/sts/ "Simulated STS usage docs")
43
72
  - [WAFv2](https://yulinsim.dev/services/wafv2/ "Simulated WAFv2 usage docs")
44
73
 
45
- ## Feature documentation
74
+ ## Feature guides
46
75
 
47
76
  - [AI skill](https://yulinsim.dev/ai-skill/ "Yulin AI skill usage docs")
48
77
  - [The AWS CLI](https://yulinsim.dev/cli/ "The AWS CLI against simulated AWS usage docs")