fauxqs 1.3.0 → 1.3.1
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/README.md +50 -0
- package/dist/initConfig.d.ts +22 -18
- package/dist/initConfig.d.ts.map +1 -1
- package/dist/initConfig.js +27 -1
- package/dist/initConfig.js.map +1 -1
- package/dist/sns/actions/listSubscriptions.js +6 -6
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -62,6 +62,56 @@ kill %1
|
|
|
62
62
|
npx cross-port-killer 4566
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
### Running in Docker Compose
|
|
66
|
+
|
|
67
|
+
Use the `node:24-alpine` image with `npx fauxqs` and mount a JSON init config to pre-create resources:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
// scripts/fauxqs/init.json
|
|
71
|
+
{
|
|
72
|
+
"queues": [
|
|
73
|
+
{
|
|
74
|
+
"name": "my-queue.fifo",
|
|
75
|
+
"attributes": { "FifoQueue": "true", "ContentBasedDeduplication": "true" }
|
|
76
|
+
},
|
|
77
|
+
{ "name": "my-dlq" }
|
|
78
|
+
],
|
|
79
|
+
"topics": [{ "name": "my-events" }],
|
|
80
|
+
"subscriptions": [{ "topic": "my-events", "queue": "my-dlq" }],
|
|
81
|
+
"buckets": ["my-uploads"]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
# docker-compose.yml
|
|
87
|
+
services:
|
|
88
|
+
fauxqs:
|
|
89
|
+
image: node:24-alpine
|
|
90
|
+
working_dir: /app
|
|
91
|
+
command: npx fauxqs
|
|
92
|
+
ports:
|
|
93
|
+
- "4566:4566"
|
|
94
|
+
environment:
|
|
95
|
+
- FAUXQS_PORT=4566
|
|
96
|
+
- FAUXQS_INIT=/app/init.json
|
|
97
|
+
- FAUXQS_LOGGER=false
|
|
98
|
+
healthcheck:
|
|
99
|
+
test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:4566/health || exit 1"]
|
|
100
|
+
interval: 2s
|
|
101
|
+
timeout: 5s
|
|
102
|
+
retries: 10
|
|
103
|
+
volumes:
|
|
104
|
+
- ./scripts/fauxqs/init.json:/app/init.json
|
|
105
|
+
|
|
106
|
+
app:
|
|
107
|
+
# ...
|
|
108
|
+
depends_on:
|
|
109
|
+
fauxqs:
|
|
110
|
+
condition: service_healthy
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Other containers reference fauxqs using the Docker service name (`http://fauxqs:4566`). The init config file creates all queues, topics, subscriptions, and buckets before the healthcheck passes, so dependent services start only after resources are ready.
|
|
114
|
+
|
|
65
115
|
### Configuring AWS SDK clients
|
|
66
116
|
|
|
67
117
|
Point your SDK clients at the local server:
|
package/dist/initConfig.d.ts
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
1
2
|
import type { SqsStore } from "./sqs/sqsStore.ts";
|
|
2
3
|
import type { SnsStore } from "./sns/snsStore.ts";
|
|
3
4
|
import type { S3Store } from "./s3/s3Store.ts";
|
|
4
|
-
|
|
5
|
-
queues
|
|
6
|
-
name:
|
|
7
|
-
attributes
|
|
8
|
-
tags
|
|
9
|
-
}>;
|
|
10
|
-
topics
|
|
11
|
-
name:
|
|
12
|
-
attributes
|
|
13
|
-
tags
|
|
14
|
-
}>;
|
|
15
|
-
subscriptions
|
|
16
|
-
topic:
|
|
17
|
-
queue:
|
|
18
|
-
attributes
|
|
19
|
-
}>;
|
|
20
|
-
buckets
|
|
21
|
-
}
|
|
5
|
+
declare const InitConfigSchema: v.ObjectSchema<{
|
|
6
|
+
readonly queues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
7
|
+
readonly name: v.StringSchema<undefined>;
|
|
8
|
+
readonly attributes: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
|
|
9
|
+
readonly tags: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
|
|
10
|
+
}, undefined>, undefined>, undefined>;
|
|
11
|
+
readonly topics: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
12
|
+
readonly name: v.StringSchema<undefined>;
|
|
13
|
+
readonly attributes: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
|
|
14
|
+
readonly tags: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
|
|
15
|
+
}, undefined>, undefined>, undefined>;
|
|
16
|
+
readonly subscriptions: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
17
|
+
readonly topic: v.StringSchema<undefined>;
|
|
18
|
+
readonly queue: v.StringSchema<undefined>;
|
|
19
|
+
readonly attributes: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
|
|
20
|
+
}, undefined>, undefined>, undefined>;
|
|
21
|
+
readonly buckets: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
22
|
+
}, undefined>;
|
|
23
|
+
export type FauxqsInitConfig = v.InferOutput<typeof InitConfigSchema>;
|
|
24
|
+
export declare function validateInitConfig(data: unknown): FauxqsInitConfig;
|
|
22
25
|
export declare function loadInitConfig(path: string): FauxqsInitConfig;
|
|
23
26
|
export declare function applyInitConfig(config: FauxqsInitConfig, sqsStore: SqsStore, snsStore: SnsStore, s3Store: S3Store, context: {
|
|
24
27
|
host?: string;
|
|
25
28
|
port: number;
|
|
26
29
|
region: string;
|
|
27
30
|
}): void;
|
|
31
|
+
export {};
|
|
28
32
|
//# sourceMappingURL=initConfig.d.ts.map
|
package/dist/initConfig.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initConfig.d.ts","sourceRoot":"","sources":["../src/initConfig.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"initConfig.d.ts","sourceRoot":"","sources":["../src/initConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAI7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAsB/C,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;aAKpB,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEtE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAElE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAG7D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvD,IAAI,CAuCN"}
|
package/dist/initConfig.js
CHANGED
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
+
import * as v from "valibot";
|
|
2
3
|
import { sqsQueueArn } from "./common/arnHelper.js";
|
|
3
4
|
import { snsTopicArn } from "./common/arnHelper.js";
|
|
4
5
|
import { DEFAULT_ACCOUNT_ID } from "./common/types.js";
|
|
6
|
+
const StringRecordSchema = v.record(v.string(), v.string());
|
|
7
|
+
const QueueSchema = v.object({
|
|
8
|
+
name: v.string(),
|
|
9
|
+
attributes: v.optional(StringRecordSchema),
|
|
10
|
+
tags: v.optional(StringRecordSchema),
|
|
11
|
+
});
|
|
12
|
+
const TopicSchema = v.object({
|
|
13
|
+
name: v.string(),
|
|
14
|
+
attributes: v.optional(StringRecordSchema),
|
|
15
|
+
tags: v.optional(StringRecordSchema),
|
|
16
|
+
});
|
|
17
|
+
const SubscriptionSchema = v.object({
|
|
18
|
+
topic: v.string(),
|
|
19
|
+
queue: v.string(),
|
|
20
|
+
attributes: v.optional(StringRecordSchema),
|
|
21
|
+
});
|
|
22
|
+
const InitConfigSchema = v.object({
|
|
23
|
+
queues: v.optional(v.array(QueueSchema)),
|
|
24
|
+
topics: v.optional(v.array(TopicSchema)),
|
|
25
|
+
subscriptions: v.optional(v.array(SubscriptionSchema)),
|
|
26
|
+
buckets: v.optional(v.array(v.string())),
|
|
27
|
+
});
|
|
28
|
+
export function validateInitConfig(data) {
|
|
29
|
+
return v.parse(InitConfigSchema, data);
|
|
30
|
+
}
|
|
5
31
|
export function loadInitConfig(path) {
|
|
6
32
|
const content = readFileSync(path, "utf-8");
|
|
7
|
-
return JSON.parse(content);
|
|
33
|
+
return validateInitConfig(JSON.parse(content));
|
|
8
34
|
}
|
|
9
35
|
export function applyInitConfig(config, sqsStore, snsStore, s3Store, context) {
|
|
10
36
|
const { host, port, region } = context;
|
package/dist/initConfig.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initConfig.js","sourceRoot":"","sources":["../src/initConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"initConfig.js","sourceRoot":"","sources":["../src/initConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAKvD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAE5D,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACxC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtD,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;CACzC,CAAC,CAAC;AAIH,MAAM,UAAU,kBAAkB,CAAC,IAAa;IAC9C,OAAO,CAAC,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,MAAwB,EACxB,QAAkB,EAClB,QAAkB,EAClB,OAAgB,EAChB,OAAwD;IAExD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEvC,2DAA2D;IAC3D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,GAAW,CAAC;YAChB,IAAI,IAAI,EAAE,CAAC;gBACT,GAAG,GAAG,cAAc,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,kBAAkB,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,oBAAoB,IAAI,IAAI,kBAAkB,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACnE,CAAC;YACD,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9C,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAClC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -10,12 +10,12 @@ export function listSubscriptionsByTopic(params, snsStore) {
|
|
|
10
10
|
}
|
|
11
11
|
function formatSubscriptionList(action, subscriptions) {
|
|
12
12
|
const membersXml = subscriptions
|
|
13
|
-
.map((s) => `<member>
|
|
14
|
-
<SubscriptionArn>${escapeXml(s.arn)}</SubscriptionArn>
|
|
15
|
-
<TopicArn>${escapeXml(s.topicArn)}</TopicArn>
|
|
16
|
-
<Protocol>${escapeXml(s.protocol)}</Protocol>
|
|
17
|
-
<Endpoint>${escapeXml(s.endpoint)}</Endpoint>
|
|
18
|
-
<Owner>000000000000</Owner>
|
|
13
|
+
.map((s) => `<member>
|
|
14
|
+
<SubscriptionArn>${escapeXml(s.arn)}</SubscriptionArn>
|
|
15
|
+
<TopicArn>${escapeXml(s.topicArn)}</TopicArn>
|
|
16
|
+
<Protocol>${escapeXml(s.protocol)}</Protocol>
|
|
17
|
+
<Endpoint>${escapeXml(s.endpoint)}</Endpoint>
|
|
18
|
+
<Owner>000000000000</Owner>
|
|
19
19
|
</member>`)
|
|
20
20
|
.join("\n ");
|
|
21
21
|
return snsSuccessResponse(action, `<Subscriptions>${membersXml}</Subscriptions>`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fauxqs",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "SNS/SQS/S3 emulator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -67,7 +67,8 @@
|
|
|
67
67
|
"@aws-sdk/client-sns": "^3.992.0",
|
|
68
68
|
"@aws-sdk/client-sqs": "^3.992.0",
|
|
69
69
|
"@smithy/node-http-handler": "^4.4.10",
|
|
70
|
-
"fastify": "^5.7.4"
|
|
70
|
+
"fastify": "^5.7.4",
|
|
71
|
+
"valibot": "^1.2.0"
|
|
71
72
|
},
|
|
72
73
|
"devDependencies": {
|
|
73
74
|
"@message-queue-toolkit/s3-payload-store": "^3.0.0",
|