@nymbalhq/config 1.0.0 → 1.1.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/dist/index.d.ts +415 -46
- package/dist/index.js +118 -41
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
2
|
+
import { CommerceSlotAdapters } from '@nymbalhq/types';
|
|
3
|
+
export { CommerceSlot, Slot } from '@nymbalhq/types';
|
|
3
4
|
|
|
4
5
|
/** The schema's JWT secret when none is configured: fine for development, refused in production. */
|
|
5
6
|
declare const DEFAULT_JWT_SECRET = "dev-secret-please-override-me-1234567890";
|
|
@@ -19,24 +20,200 @@ declare const storeSchema: z.ZodObject<{
|
|
|
19
20
|
locale: string;
|
|
20
21
|
timezone: string;
|
|
21
22
|
}>;
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
/** The shared Redis connection of the `redis` document store and the `redis-streams` bus. */
|
|
24
|
+
declare const redisSchema: z.ZodObject<{
|
|
25
|
+
/** Defaults to `REDIS_URL`. */
|
|
26
|
+
url: z.ZodOptional<z.ZodString>;
|
|
27
|
+
/** Namespaces every key and stream; defaults to `NYMBAL_REDIS_PREFIX`, then `'nymbal'`. */
|
|
28
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
29
|
+
/** How long a publish waits for the groups it delivers to (default 15 000). */
|
|
30
|
+
ackTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
/** How long an entry may stay pending on a consumer before a live one takes it over (default 5 000). */
|
|
32
|
+
claimIdleMs: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
/** The approximate length each stream is trimmed to (default 10 000). */
|
|
34
|
+
streamMaxLen: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
}, "strict", z.ZodTypeAny, {
|
|
36
|
+
url?: string | undefined;
|
|
37
|
+
prefix?: string | undefined;
|
|
38
|
+
ackTimeoutMs?: number | undefined;
|
|
39
|
+
claimIdleMs?: number | undefined;
|
|
40
|
+
streamMaxLen?: number | undefined;
|
|
41
|
+
}, {
|
|
42
|
+
url?: string | undefined;
|
|
43
|
+
prefix?: string | undefined;
|
|
44
|
+
ackTimeoutMs?: number | undefined;
|
|
45
|
+
claimIdleMs?: number | undefined;
|
|
46
|
+
streamMaxLen?: number | undefined;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* The bucket `media: 's3'` stores in. Each field falls back to the environment in the platform; credentials are never
|
|
50
|
+
* config keys: the AWS SDK's default chain provides them.
|
|
51
|
+
*/
|
|
52
|
+
declare const s3Schema: z.ZodObject<{
|
|
53
|
+
/** Defaults to `S3_BUCKET`; one of the two is required. */
|
|
54
|
+
bucket: z.ZodOptional<z.ZodString>;
|
|
55
|
+
/** Defaults to `AWS_REGION`, then `'us-east-1'`. */
|
|
56
|
+
region: z.ZodOptional<z.ZodString>;
|
|
57
|
+
/** An S3-compatible API (MinIO, R2); defaults to `S3_ENDPOINT`, then AWS. */
|
|
58
|
+
endpoint: z.ZodOptional<z.ZodString>;
|
|
59
|
+
/** Where every object key starts; defaults to `NYMBAL_S3_PREFIX`, then none. */
|
|
60
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
61
|
+
/** Where the bucket's objects are served from (a CDN); defaults to `S3_PUBLIC_URL`, then the bucket's own URL. */
|
|
62
|
+
publicUrl: z.ZodOptional<z.ZodString>;
|
|
63
|
+
/** Path-style requests; true by default when an endpoint is set. */
|
|
64
|
+
forcePathStyle: z.ZodOptional<z.ZodBoolean>;
|
|
65
|
+
}, "strict", z.ZodTypeAny, {
|
|
66
|
+
prefix?: string | undefined;
|
|
67
|
+
bucket?: string | undefined;
|
|
68
|
+
region?: string | undefined;
|
|
69
|
+
endpoint?: string | undefined;
|
|
70
|
+
publicUrl?: string | undefined;
|
|
71
|
+
forcePathStyle?: boolean | undefined;
|
|
72
|
+
}, {
|
|
73
|
+
prefix?: string | undefined;
|
|
74
|
+
bucket?: string | undefined;
|
|
75
|
+
region?: string | undefined;
|
|
76
|
+
endpoint?: string | undefined;
|
|
77
|
+
publicUrl?: string | undefined;
|
|
78
|
+
forcePathStyle?: boolean | undefined;
|
|
79
|
+
}>;
|
|
80
|
+
declare const infrastructureSchema: z.ZodEffects<z.ZodObject<{
|
|
24
81
|
commandStore: z.ZodEnum<["sqlite", "postgres"]>;
|
|
25
|
-
documentStore: z.ZodEnum<["in-memory", "
|
|
26
|
-
eventBus: z.ZodEnum<["in-process", "
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
82
|
+
documentStore: z.ZodEnum<["in-memory", "redis", "postgres-jsonb"]>;
|
|
83
|
+
eventBus: z.ZodEnum<["in-process", "redis-streams"]>;
|
|
84
|
+
media: z.ZodDefault<z.ZodEnum<["local-fs", "s3"]>>;
|
|
85
|
+
redis: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
/** Defaults to `REDIS_URL`. */
|
|
87
|
+
url: z.ZodOptional<z.ZodString>;
|
|
88
|
+
/** Namespaces every key and stream; defaults to `NYMBAL_REDIS_PREFIX`, then `'nymbal'`. */
|
|
89
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
90
|
+
/** How long a publish waits for the groups it delivers to (default 15 000). */
|
|
91
|
+
ackTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
92
|
+
/** How long an entry may stay pending on a consumer before a live one takes it over (default 5 000). */
|
|
93
|
+
claimIdleMs: z.ZodOptional<z.ZodNumber>;
|
|
94
|
+
/** The approximate length each stream is trimmed to (default 10 000). */
|
|
95
|
+
streamMaxLen: z.ZodOptional<z.ZodNumber>;
|
|
96
|
+
}, "strict", z.ZodTypeAny, {
|
|
97
|
+
url?: string | undefined;
|
|
98
|
+
prefix?: string | undefined;
|
|
99
|
+
ackTimeoutMs?: number | undefined;
|
|
100
|
+
claimIdleMs?: number | undefined;
|
|
101
|
+
streamMaxLen?: number | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
url?: string | undefined;
|
|
104
|
+
prefix?: string | undefined;
|
|
105
|
+
ackTimeoutMs?: number | undefined;
|
|
106
|
+
claimIdleMs?: number | undefined;
|
|
107
|
+
streamMaxLen?: number | undefined;
|
|
108
|
+
}>>;
|
|
109
|
+
s3: z.ZodOptional<z.ZodObject<{
|
|
110
|
+
/** Defaults to `S3_BUCKET`; one of the two is required. */
|
|
111
|
+
bucket: z.ZodOptional<z.ZodString>;
|
|
112
|
+
/** Defaults to `AWS_REGION`, then `'us-east-1'`. */
|
|
113
|
+
region: z.ZodOptional<z.ZodString>;
|
|
114
|
+
/** An S3-compatible API (MinIO, R2); defaults to `S3_ENDPOINT`, then AWS. */
|
|
115
|
+
endpoint: z.ZodOptional<z.ZodString>;
|
|
116
|
+
/** Where every object key starts; defaults to `NYMBAL_S3_PREFIX`, then none. */
|
|
117
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
118
|
+
/** Where the bucket's objects are served from (a CDN); defaults to `S3_PUBLIC_URL`, then the bucket's own URL. */
|
|
119
|
+
publicUrl: z.ZodOptional<z.ZodString>;
|
|
120
|
+
/** Path-style requests; true by default when an endpoint is set. */
|
|
121
|
+
forcePathStyle: z.ZodOptional<z.ZodBoolean>;
|
|
122
|
+
}, "strict", z.ZodTypeAny, {
|
|
123
|
+
prefix?: string | undefined;
|
|
124
|
+
bucket?: string | undefined;
|
|
125
|
+
region?: string | undefined;
|
|
126
|
+
endpoint?: string | undefined;
|
|
127
|
+
publicUrl?: string | undefined;
|
|
128
|
+
forcePathStyle?: boolean | undefined;
|
|
129
|
+
}, {
|
|
130
|
+
prefix?: string | undefined;
|
|
131
|
+
bucket?: string | undefined;
|
|
132
|
+
region?: string | undefined;
|
|
133
|
+
endpoint?: string | undefined;
|
|
134
|
+
publicUrl?: string | undefined;
|
|
135
|
+
forcePathStyle?: boolean | undefined;
|
|
136
|
+
}>>;
|
|
137
|
+
}, "strict", z.ZodTypeAny, {
|
|
138
|
+
commandStore: "sqlite" | "postgres";
|
|
139
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
140
|
+
eventBus: "in-process" | "redis-streams";
|
|
141
|
+
media: "local-fs" | "s3";
|
|
142
|
+
redis?: {
|
|
143
|
+
url?: string | undefined;
|
|
144
|
+
prefix?: string | undefined;
|
|
145
|
+
ackTimeoutMs?: number | undefined;
|
|
146
|
+
claimIdleMs?: number | undefined;
|
|
147
|
+
streamMaxLen?: number | undefined;
|
|
148
|
+
} | undefined;
|
|
149
|
+
s3?: {
|
|
150
|
+
prefix?: string | undefined;
|
|
151
|
+
bucket?: string | undefined;
|
|
152
|
+
region?: string | undefined;
|
|
153
|
+
endpoint?: string | undefined;
|
|
154
|
+
publicUrl?: string | undefined;
|
|
155
|
+
forcePathStyle?: boolean | undefined;
|
|
156
|
+
} | undefined;
|
|
157
|
+
}, {
|
|
30
158
|
commandStore: "sqlite" | "postgres";
|
|
31
|
-
documentStore: "in-memory" | "
|
|
32
|
-
eventBus: "in-process" | "
|
|
33
|
-
|
|
159
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
160
|
+
eventBus: "in-process" | "redis-streams";
|
|
161
|
+
redis?: {
|
|
162
|
+
url?: string | undefined;
|
|
163
|
+
prefix?: string | undefined;
|
|
164
|
+
ackTimeoutMs?: number | undefined;
|
|
165
|
+
claimIdleMs?: number | undefined;
|
|
166
|
+
streamMaxLen?: number | undefined;
|
|
167
|
+
} | undefined;
|
|
168
|
+
media?: "local-fs" | "s3" | undefined;
|
|
169
|
+
s3?: {
|
|
170
|
+
prefix?: string | undefined;
|
|
171
|
+
bucket?: string | undefined;
|
|
172
|
+
region?: string | undefined;
|
|
173
|
+
endpoint?: string | undefined;
|
|
174
|
+
publicUrl?: string | undefined;
|
|
175
|
+
forcePathStyle?: boolean | undefined;
|
|
176
|
+
} | undefined;
|
|
177
|
+
}>, {
|
|
178
|
+
commandStore: "sqlite" | "postgres";
|
|
179
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
180
|
+
eventBus: "in-process" | "redis-streams";
|
|
181
|
+
media: "local-fs" | "s3";
|
|
182
|
+
redis?: {
|
|
183
|
+
url?: string | undefined;
|
|
184
|
+
prefix?: string | undefined;
|
|
185
|
+
ackTimeoutMs?: number | undefined;
|
|
186
|
+
claimIdleMs?: number | undefined;
|
|
187
|
+
streamMaxLen?: number | undefined;
|
|
188
|
+
} | undefined;
|
|
189
|
+
s3?: {
|
|
190
|
+
prefix?: string | undefined;
|
|
191
|
+
bucket?: string | undefined;
|
|
192
|
+
region?: string | undefined;
|
|
193
|
+
endpoint?: string | undefined;
|
|
194
|
+
publicUrl?: string | undefined;
|
|
195
|
+
forcePathStyle?: boolean | undefined;
|
|
196
|
+
} | undefined;
|
|
34
197
|
}, {
|
|
35
|
-
cloud: "local" | "aws" | "gcp" | "azure" | "docker";
|
|
36
198
|
commandStore: "sqlite" | "postgres";
|
|
37
|
-
documentStore: "in-memory" | "
|
|
38
|
-
eventBus: "in-process" | "
|
|
39
|
-
|
|
199
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
200
|
+
eventBus: "in-process" | "redis-streams";
|
|
201
|
+
redis?: {
|
|
202
|
+
url?: string | undefined;
|
|
203
|
+
prefix?: string | undefined;
|
|
204
|
+
ackTimeoutMs?: number | undefined;
|
|
205
|
+
claimIdleMs?: number | undefined;
|
|
206
|
+
streamMaxLen?: number | undefined;
|
|
207
|
+
} | undefined;
|
|
208
|
+
media?: "local-fs" | "s3" | undefined;
|
|
209
|
+
s3?: {
|
|
210
|
+
prefix?: string | undefined;
|
|
211
|
+
bucket?: string | undefined;
|
|
212
|
+
region?: string | undefined;
|
|
213
|
+
endpoint?: string | undefined;
|
|
214
|
+
publicUrl?: string | undefined;
|
|
215
|
+
forcePathStyle?: boolean | undefined;
|
|
216
|
+
} | undefined;
|
|
40
217
|
}>;
|
|
41
218
|
declare const securitySchema: z.ZodObject<{
|
|
42
219
|
adapter: z.ZodEnum<["middleware", "cloudflare", "aws-waf", "akamai"]>;
|
|
@@ -379,24 +556,143 @@ declare const nymbalConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
379
556
|
timezone: string;
|
|
380
557
|
}>;
|
|
381
558
|
template: z.ZodEnum<["astro", "nextjs"]>;
|
|
382
|
-
infrastructure: z.ZodObject<{
|
|
383
|
-
cloud: z.ZodEnum<["local", "aws", "gcp", "azure", "docker"]>;
|
|
559
|
+
infrastructure: z.ZodEffects<z.ZodObject<{
|
|
384
560
|
commandStore: z.ZodEnum<["sqlite", "postgres"]>;
|
|
385
|
-
documentStore: z.ZodEnum<["in-memory", "
|
|
386
|
-
eventBus: z.ZodEnum<["in-process", "
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
561
|
+
documentStore: z.ZodEnum<["in-memory", "redis", "postgres-jsonb"]>;
|
|
562
|
+
eventBus: z.ZodEnum<["in-process", "redis-streams"]>;
|
|
563
|
+
media: z.ZodDefault<z.ZodEnum<["local-fs", "s3"]>>;
|
|
564
|
+
redis: z.ZodOptional<z.ZodObject<{
|
|
565
|
+
/** Defaults to `REDIS_URL`. */
|
|
566
|
+
url: z.ZodOptional<z.ZodString>;
|
|
567
|
+
/** Namespaces every key and stream; defaults to `NYMBAL_REDIS_PREFIX`, then `'nymbal'`. */
|
|
568
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
569
|
+
/** How long a publish waits for the groups it delivers to (default 15 000). */
|
|
570
|
+
ackTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
571
|
+
/** How long an entry may stay pending on a consumer before a live one takes it over (default 5 000). */
|
|
572
|
+
claimIdleMs: z.ZodOptional<z.ZodNumber>;
|
|
573
|
+
/** The approximate length each stream is trimmed to (default 10 000). */
|
|
574
|
+
streamMaxLen: z.ZodOptional<z.ZodNumber>;
|
|
575
|
+
}, "strict", z.ZodTypeAny, {
|
|
576
|
+
url?: string | undefined;
|
|
577
|
+
prefix?: string | undefined;
|
|
578
|
+
ackTimeoutMs?: number | undefined;
|
|
579
|
+
claimIdleMs?: number | undefined;
|
|
580
|
+
streamMaxLen?: number | undefined;
|
|
581
|
+
}, {
|
|
582
|
+
url?: string | undefined;
|
|
583
|
+
prefix?: string | undefined;
|
|
584
|
+
ackTimeoutMs?: number | undefined;
|
|
585
|
+
claimIdleMs?: number | undefined;
|
|
586
|
+
streamMaxLen?: number | undefined;
|
|
587
|
+
}>>;
|
|
588
|
+
s3: z.ZodOptional<z.ZodObject<{
|
|
589
|
+
/** Defaults to `S3_BUCKET`; one of the two is required. */
|
|
590
|
+
bucket: z.ZodOptional<z.ZodString>;
|
|
591
|
+
/** Defaults to `AWS_REGION`, then `'us-east-1'`. */
|
|
592
|
+
region: z.ZodOptional<z.ZodString>;
|
|
593
|
+
/** An S3-compatible API (MinIO, R2); defaults to `S3_ENDPOINT`, then AWS. */
|
|
594
|
+
endpoint: z.ZodOptional<z.ZodString>;
|
|
595
|
+
/** Where every object key starts; defaults to `NYMBAL_S3_PREFIX`, then none. */
|
|
596
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
597
|
+
/** Where the bucket's objects are served from (a CDN); defaults to `S3_PUBLIC_URL`, then the bucket's own URL. */
|
|
598
|
+
publicUrl: z.ZodOptional<z.ZodString>;
|
|
599
|
+
/** Path-style requests; true by default when an endpoint is set. */
|
|
600
|
+
forcePathStyle: z.ZodOptional<z.ZodBoolean>;
|
|
601
|
+
}, "strict", z.ZodTypeAny, {
|
|
602
|
+
prefix?: string | undefined;
|
|
603
|
+
bucket?: string | undefined;
|
|
604
|
+
region?: string | undefined;
|
|
605
|
+
endpoint?: string | undefined;
|
|
606
|
+
publicUrl?: string | undefined;
|
|
607
|
+
forcePathStyle?: boolean | undefined;
|
|
608
|
+
}, {
|
|
609
|
+
prefix?: string | undefined;
|
|
610
|
+
bucket?: string | undefined;
|
|
611
|
+
region?: string | undefined;
|
|
612
|
+
endpoint?: string | undefined;
|
|
613
|
+
publicUrl?: string | undefined;
|
|
614
|
+
forcePathStyle?: boolean | undefined;
|
|
615
|
+
}>>;
|
|
616
|
+
}, "strict", z.ZodTypeAny, {
|
|
390
617
|
commandStore: "sqlite" | "postgres";
|
|
391
|
-
documentStore: "in-memory" | "
|
|
392
|
-
eventBus: "in-process" | "
|
|
393
|
-
|
|
618
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
619
|
+
eventBus: "in-process" | "redis-streams";
|
|
620
|
+
media: "local-fs" | "s3";
|
|
621
|
+
redis?: {
|
|
622
|
+
url?: string | undefined;
|
|
623
|
+
prefix?: string | undefined;
|
|
624
|
+
ackTimeoutMs?: number | undefined;
|
|
625
|
+
claimIdleMs?: number | undefined;
|
|
626
|
+
streamMaxLen?: number | undefined;
|
|
627
|
+
} | undefined;
|
|
628
|
+
s3?: {
|
|
629
|
+
prefix?: string | undefined;
|
|
630
|
+
bucket?: string | undefined;
|
|
631
|
+
region?: string | undefined;
|
|
632
|
+
endpoint?: string | undefined;
|
|
633
|
+
publicUrl?: string | undefined;
|
|
634
|
+
forcePathStyle?: boolean | undefined;
|
|
635
|
+
} | undefined;
|
|
394
636
|
}, {
|
|
395
|
-
cloud: "local" | "aws" | "gcp" | "azure" | "docker";
|
|
396
637
|
commandStore: "sqlite" | "postgres";
|
|
397
|
-
documentStore: "in-memory" | "
|
|
398
|
-
eventBus: "in-process" | "
|
|
399
|
-
|
|
638
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
639
|
+
eventBus: "in-process" | "redis-streams";
|
|
640
|
+
redis?: {
|
|
641
|
+
url?: string | undefined;
|
|
642
|
+
prefix?: string | undefined;
|
|
643
|
+
ackTimeoutMs?: number | undefined;
|
|
644
|
+
claimIdleMs?: number | undefined;
|
|
645
|
+
streamMaxLen?: number | undefined;
|
|
646
|
+
} | undefined;
|
|
647
|
+
media?: "local-fs" | "s3" | undefined;
|
|
648
|
+
s3?: {
|
|
649
|
+
prefix?: string | undefined;
|
|
650
|
+
bucket?: string | undefined;
|
|
651
|
+
region?: string | undefined;
|
|
652
|
+
endpoint?: string | undefined;
|
|
653
|
+
publicUrl?: string | undefined;
|
|
654
|
+
forcePathStyle?: boolean | undefined;
|
|
655
|
+
} | undefined;
|
|
656
|
+
}>, {
|
|
657
|
+
commandStore: "sqlite" | "postgres";
|
|
658
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
659
|
+
eventBus: "in-process" | "redis-streams";
|
|
660
|
+
media: "local-fs" | "s3";
|
|
661
|
+
redis?: {
|
|
662
|
+
url?: string | undefined;
|
|
663
|
+
prefix?: string | undefined;
|
|
664
|
+
ackTimeoutMs?: number | undefined;
|
|
665
|
+
claimIdleMs?: number | undefined;
|
|
666
|
+
streamMaxLen?: number | undefined;
|
|
667
|
+
} | undefined;
|
|
668
|
+
s3?: {
|
|
669
|
+
prefix?: string | undefined;
|
|
670
|
+
bucket?: string | undefined;
|
|
671
|
+
region?: string | undefined;
|
|
672
|
+
endpoint?: string | undefined;
|
|
673
|
+
publicUrl?: string | undefined;
|
|
674
|
+
forcePathStyle?: boolean | undefined;
|
|
675
|
+
} | undefined;
|
|
676
|
+
}, {
|
|
677
|
+
commandStore: "sqlite" | "postgres";
|
|
678
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
679
|
+
eventBus: "in-process" | "redis-streams";
|
|
680
|
+
redis?: {
|
|
681
|
+
url?: string | undefined;
|
|
682
|
+
prefix?: string | undefined;
|
|
683
|
+
ackTimeoutMs?: number | undefined;
|
|
684
|
+
claimIdleMs?: number | undefined;
|
|
685
|
+
streamMaxLen?: number | undefined;
|
|
686
|
+
} | undefined;
|
|
687
|
+
media?: "local-fs" | "s3" | undefined;
|
|
688
|
+
s3?: {
|
|
689
|
+
prefix?: string | undefined;
|
|
690
|
+
bucket?: string | undefined;
|
|
691
|
+
region?: string | undefined;
|
|
692
|
+
endpoint?: string | undefined;
|
|
693
|
+
publicUrl?: string | undefined;
|
|
694
|
+
forcePathStyle?: boolean | undefined;
|
|
695
|
+
} | undefined;
|
|
400
696
|
}>;
|
|
401
697
|
security: z.ZodObject<{
|
|
402
698
|
adapter: z.ZodEnum<["middleware", "cloudflare", "aws-waf", "akamai"]>;
|
|
@@ -730,11 +1026,25 @@ declare const nymbalConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
730
1026
|
};
|
|
731
1027
|
template: "astro" | "nextjs";
|
|
732
1028
|
infrastructure: {
|
|
733
|
-
cloud: "local" | "aws" | "gcp" | "azure" | "docker";
|
|
734
1029
|
commandStore: "sqlite" | "postgres";
|
|
735
|
-
documentStore: "in-memory" | "
|
|
736
|
-
eventBus: "in-process" | "
|
|
737
|
-
|
|
1030
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
1031
|
+
eventBus: "in-process" | "redis-streams";
|
|
1032
|
+
media: "local-fs" | "s3";
|
|
1033
|
+
redis?: {
|
|
1034
|
+
url?: string | undefined;
|
|
1035
|
+
prefix?: string | undefined;
|
|
1036
|
+
ackTimeoutMs?: number | undefined;
|
|
1037
|
+
claimIdleMs?: number | undefined;
|
|
1038
|
+
streamMaxLen?: number | undefined;
|
|
1039
|
+
} | undefined;
|
|
1040
|
+
s3?: {
|
|
1041
|
+
prefix?: string | undefined;
|
|
1042
|
+
bucket?: string | undefined;
|
|
1043
|
+
region?: string | undefined;
|
|
1044
|
+
endpoint?: string | undefined;
|
|
1045
|
+
publicUrl?: string | undefined;
|
|
1046
|
+
forcePathStyle?: boolean | undefined;
|
|
1047
|
+
} | undefined;
|
|
738
1048
|
};
|
|
739
1049
|
security: {
|
|
740
1050
|
adapter: "middleware" | "cloudflare" | "aws-waf" | "akamai";
|
|
@@ -825,11 +1135,25 @@ declare const nymbalConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
825
1135
|
};
|
|
826
1136
|
template: "astro" | "nextjs";
|
|
827
1137
|
infrastructure: {
|
|
828
|
-
cloud: "local" | "aws" | "gcp" | "azure" | "docker";
|
|
829
1138
|
commandStore: "sqlite" | "postgres";
|
|
830
|
-
documentStore: "in-memory" | "
|
|
831
|
-
eventBus: "in-process" | "
|
|
832
|
-
|
|
1139
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
1140
|
+
eventBus: "in-process" | "redis-streams";
|
|
1141
|
+
redis?: {
|
|
1142
|
+
url?: string | undefined;
|
|
1143
|
+
prefix?: string | undefined;
|
|
1144
|
+
ackTimeoutMs?: number | undefined;
|
|
1145
|
+
claimIdleMs?: number | undefined;
|
|
1146
|
+
streamMaxLen?: number | undefined;
|
|
1147
|
+
} | undefined;
|
|
1148
|
+
media?: "local-fs" | "s3" | undefined;
|
|
1149
|
+
s3?: {
|
|
1150
|
+
prefix?: string | undefined;
|
|
1151
|
+
bucket?: string | undefined;
|
|
1152
|
+
region?: string | undefined;
|
|
1153
|
+
endpoint?: string | undefined;
|
|
1154
|
+
publicUrl?: string | undefined;
|
|
1155
|
+
forcePathStyle?: boolean | undefined;
|
|
1156
|
+
} | undefined;
|
|
833
1157
|
};
|
|
834
1158
|
security: {
|
|
835
1159
|
adapter: "middleware" | "cloudflare" | "aws-waf" | "akamai";
|
|
@@ -920,11 +1244,25 @@ declare const nymbalConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
920
1244
|
};
|
|
921
1245
|
template: "astro" | "nextjs";
|
|
922
1246
|
infrastructure: {
|
|
923
|
-
cloud: "local" | "aws" | "gcp" | "azure" | "docker";
|
|
924
1247
|
commandStore: "sqlite" | "postgres";
|
|
925
|
-
documentStore: "in-memory" | "
|
|
926
|
-
eventBus: "in-process" | "
|
|
927
|
-
|
|
1248
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
1249
|
+
eventBus: "in-process" | "redis-streams";
|
|
1250
|
+
media: "local-fs" | "s3";
|
|
1251
|
+
redis?: {
|
|
1252
|
+
url?: string | undefined;
|
|
1253
|
+
prefix?: string | undefined;
|
|
1254
|
+
ackTimeoutMs?: number | undefined;
|
|
1255
|
+
claimIdleMs?: number | undefined;
|
|
1256
|
+
streamMaxLen?: number | undefined;
|
|
1257
|
+
} | undefined;
|
|
1258
|
+
s3?: {
|
|
1259
|
+
prefix?: string | undefined;
|
|
1260
|
+
bucket?: string | undefined;
|
|
1261
|
+
region?: string | undefined;
|
|
1262
|
+
endpoint?: string | undefined;
|
|
1263
|
+
publicUrl?: string | undefined;
|
|
1264
|
+
forcePathStyle?: boolean | undefined;
|
|
1265
|
+
} | undefined;
|
|
928
1266
|
};
|
|
929
1267
|
security: {
|
|
930
1268
|
adapter: "middleware" | "cloudflare" | "aws-waf" | "akamai";
|
|
@@ -1015,11 +1353,25 @@ declare const nymbalConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
1015
1353
|
};
|
|
1016
1354
|
template: "astro" | "nextjs";
|
|
1017
1355
|
infrastructure: {
|
|
1018
|
-
cloud: "local" | "aws" | "gcp" | "azure" | "docker";
|
|
1019
1356
|
commandStore: "sqlite" | "postgres";
|
|
1020
|
-
documentStore: "in-memory" | "
|
|
1021
|
-
eventBus: "in-process" | "
|
|
1022
|
-
|
|
1357
|
+
documentStore: "in-memory" | "redis" | "postgres-jsonb";
|
|
1358
|
+
eventBus: "in-process" | "redis-streams";
|
|
1359
|
+
redis?: {
|
|
1360
|
+
url?: string | undefined;
|
|
1361
|
+
prefix?: string | undefined;
|
|
1362
|
+
ackTimeoutMs?: number | undefined;
|
|
1363
|
+
claimIdleMs?: number | undefined;
|
|
1364
|
+
streamMaxLen?: number | undefined;
|
|
1365
|
+
} | undefined;
|
|
1366
|
+
media?: "local-fs" | "s3" | undefined;
|
|
1367
|
+
s3?: {
|
|
1368
|
+
prefix?: string | undefined;
|
|
1369
|
+
bucket?: string | undefined;
|
|
1370
|
+
region?: string | undefined;
|
|
1371
|
+
endpoint?: string | undefined;
|
|
1372
|
+
publicUrl?: string | undefined;
|
|
1373
|
+
forcePathStyle?: boolean | undefined;
|
|
1374
|
+
} | undefined;
|
|
1023
1375
|
};
|
|
1024
1376
|
security: {
|
|
1025
1377
|
adapter: "middleware" | "cloudflare" | "aws-waf" | "akamai";
|
|
@@ -1127,12 +1479,29 @@ declare const KNOWN_PROVIDERS: {
|
|
|
1127
1479
|
readonly ai: readonly ["none", "anthropic", "custom"];
|
|
1128
1480
|
};
|
|
1129
1481
|
|
|
1482
|
+
/**
|
|
1483
|
+
* The values each infrastructure slot accepts: only what is built. `in-memory`, `in-process` and `local-fs` are the
|
|
1484
|
+
* kernel's own; `redis`, `postgres-jsonb`, `redis-streams` and `s3` live in `@nymbalhq/*` packages the kernel loads
|
|
1485
|
+
* only when the config names them.
|
|
1486
|
+
*/
|
|
1487
|
+
declare const KNOWN_INFRASTRUCTURE: {
|
|
1488
|
+
readonly commandStore: readonly ["sqlite", "postgres"];
|
|
1489
|
+
readonly documentStore: readonly ["in-memory", "redis", "postgres-jsonb"];
|
|
1490
|
+
readonly eventBus: readonly ["in-process", "redis-streams"];
|
|
1491
|
+
readonly media: readonly ["local-fs", "s3"];
|
|
1492
|
+
};
|
|
1493
|
+
type InfrastructureSlot = keyof typeof KNOWN_INFRASTRUCTURE;
|
|
1494
|
+
/** Keys that drove nothing and were removed; a config that still sets one is told to delete it. */
|
|
1495
|
+
declare const REMOVED_INFRASTRUCTURE_KEYS: readonly ["cloud", "compute"];
|
|
1496
|
+
|
|
1130
1497
|
interface LoadedConfig {
|
|
1131
1498
|
config: NymbalConfig;
|
|
1132
1499
|
path: string;
|
|
1133
1500
|
projectRoot: string;
|
|
1501
|
+
/** The module's named `adapters` export: one adapter per slot whose provider is `custom`, for createApp. */
|
|
1502
|
+
adapters?: Partial<CommerceSlotAdapters>;
|
|
1134
1503
|
}
|
|
1135
1504
|
declare function findConfigFile(startDir: string): string | null;
|
|
1136
1505
|
declare function loadConfig(startDir?: string): Promise<LoadedConfig>;
|
|
1137
1506
|
|
|
1138
|
-
export { DEFAULT_JWT_SECRET, KNOWN_PROVIDERS, type LoadedConfig, type NymbalConfig, type NymbalConfigInput, commerceSchema, defineConfig, deploymentSchema, env, envBool, envNumber, envOptional, featuresSchema, findConfigFile, httpSchema, infrastructureSchema, loadConfig, nymbalConfigSchema, securitySchema, storeSchema };
|
|
1507
|
+
export { DEFAULT_JWT_SECRET, type InfrastructureSlot, KNOWN_INFRASTRUCTURE, KNOWN_PROVIDERS, type LoadedConfig, type NymbalConfig, type NymbalConfigInput, REMOVED_INFRASTRUCTURE_KEYS, commerceSchema, defineConfig, deploymentSchema, env, envBool, envNumber, envOptional, featuresSchema, findConfigFile, httpSchema, infrastructureSchema, loadConfig, nymbalConfigSchema, redisSchema, s3Schema, securitySchema, storeSchema };
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,15 @@ var KNOWN_PROVIDERS = {
|
|
|
49
49
|
ai: ["none", "anthropic", "custom"]
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
// src/known-infrastructure.ts
|
|
53
|
+
var KNOWN_INFRASTRUCTURE = {
|
|
54
|
+
commandStore: ["sqlite", "postgres"],
|
|
55
|
+
documentStore: ["in-memory", "redis", "postgres-jsonb"],
|
|
56
|
+
eventBus: ["in-process", "redis-streams"],
|
|
57
|
+
media: ["local-fs", "s3"]
|
|
58
|
+
};
|
|
59
|
+
var REMOVED_INFRASTRUCTURE_KEYS = ["cloud", "compute"];
|
|
60
|
+
|
|
52
61
|
// src/load.ts
|
|
53
62
|
import { existsSync } from "fs";
|
|
54
63
|
import { dirname, isAbsolute, resolve } from "path";
|
|
@@ -72,12 +81,88 @@ var storeSchema = z.object({
|
|
|
72
81
|
locale: z.string().min(2),
|
|
73
82
|
timezone: z.string().min(1)
|
|
74
83
|
});
|
|
75
|
-
var
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
var quotedList = (values) => values.map((v) => `'${v}'`).join(", ");
|
|
85
|
+
function infrastructureValue(slot, values) {
|
|
86
|
+
return z.enum(values, {
|
|
87
|
+
errorMap: (issue, ctx) => issue.code === z.ZodIssueCode.invalid_enum_value ? {
|
|
88
|
+
message: `unknown ${slot} '${String(issue.received)}'; the ${slot} values are ${quotedList(values)}`
|
|
89
|
+
} : { message: ctx.defaultError }
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
var INFRASTRUCTURE_KEYS = [...Object.keys(KNOWN_INFRASTRUCTURE), "redis", "s3"];
|
|
93
|
+
function unrecognizedInfrastructureKeys(keys) {
|
|
94
|
+
return keys.map(
|
|
95
|
+
(key) => REMOVED_INFRASTRUCTURE_KEYS.includes(key) ? `infrastructure.${key} was removed: it drives nothing, so delete it from the config` : `unknown infrastructure key '${key}'; the infrastructure keys are ${quotedList(INFRASTRUCTURE_KEYS)}`
|
|
96
|
+
).join("; ");
|
|
97
|
+
}
|
|
98
|
+
var redisSchema = z.object({
|
|
99
|
+
/** Defaults to `REDIS_URL`. */
|
|
100
|
+
url: z.string().min(1).optional(),
|
|
101
|
+
/** Namespaces every key and stream; defaults to `NYMBAL_REDIS_PREFIX`, then `'nymbal'`. */
|
|
102
|
+
prefix: z.string().min(1).optional(),
|
|
103
|
+
/** How long a publish waits for the groups it delivers to (default 15 000). */
|
|
104
|
+
ackTimeoutMs: z.number().int().positive().optional(),
|
|
105
|
+
/** How long an entry may stay pending on a consumer before a live one takes it over (default 5 000). */
|
|
106
|
+
claimIdleMs: z.number().int().positive().optional(),
|
|
107
|
+
/** The approximate length each stream is trimmed to (default 10 000). */
|
|
108
|
+
streamMaxLen: z.number().int().positive().optional()
|
|
109
|
+
}).strict();
|
|
110
|
+
var S3_KEYS = ["bucket", "region", "endpoint", "prefix", "publicUrl", "forcePathStyle"];
|
|
111
|
+
var s3Schema = z.object(
|
|
112
|
+
{
|
|
113
|
+
/** Defaults to `S3_BUCKET`; one of the two is required. */
|
|
114
|
+
bucket: z.string().min(1).optional(),
|
|
115
|
+
/** Defaults to `AWS_REGION`, then `'us-east-1'`. */
|
|
116
|
+
region: z.string().min(1).optional(),
|
|
117
|
+
/** An S3-compatible API (MinIO, R2); defaults to `S3_ENDPOINT`, then AWS. */
|
|
118
|
+
endpoint: z.string().min(1).optional(),
|
|
119
|
+
/** Where every object key starts; defaults to `NYMBAL_S3_PREFIX`, then none. */
|
|
120
|
+
prefix: z.string().optional(),
|
|
121
|
+
/** Where the bucket's objects are served from (a CDN); defaults to `S3_PUBLIC_URL`, then the bucket's own URL. */
|
|
122
|
+
publicUrl: z.string().min(1).optional(),
|
|
123
|
+
/** Path-style requests; true by default when an endpoint is set. */
|
|
124
|
+
forcePathStyle: z.boolean().optional()
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
errorMap: (issue, ctx) => issue.code === z.ZodIssueCode.unrecognized_keys ? {
|
|
128
|
+
message: `unknown infrastructure.s3 key${issue.keys.length > 1 ? "s" : ""} ${quotedList(issue.keys)}; the s3 keys are ${quotedList(S3_KEYS)}, and credentials come from the AWS SDK (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, a profile or a role), never the config`
|
|
129
|
+
} : { message: ctx.defaultError }
|
|
130
|
+
}
|
|
131
|
+
).strict();
|
|
132
|
+
var infrastructureSchema = z.object(
|
|
133
|
+
{
|
|
134
|
+
commandStore: infrastructureValue("commandStore", KNOWN_INFRASTRUCTURE.commandStore),
|
|
135
|
+
documentStore: infrastructureValue("documentStore", KNOWN_INFRASTRUCTURE.documentStore),
|
|
136
|
+
eventBus: infrastructureValue("eventBus", KNOWN_INFRASTRUCTURE.eventBus),
|
|
137
|
+
media: infrastructureValue("media", KNOWN_INFRASTRUCTURE.media).default("local-fs"),
|
|
138
|
+
redis: redisSchema.optional(),
|
|
139
|
+
s3: s3Schema.optional()
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
errorMap: (issue, ctx) => issue.code === z.ZodIssueCode.unrecognized_keys ? { message: unrecognizedInfrastructureKeys(issue.keys) } : { message: ctx.defaultError }
|
|
143
|
+
}
|
|
144
|
+
).strict().superRefine((infra, ctx) => {
|
|
145
|
+
if (infra.documentStore === "postgres-jsonb" && infra.commandStore !== "postgres") {
|
|
146
|
+
ctx.addIssue({
|
|
147
|
+
code: z.ZodIssueCode.custom,
|
|
148
|
+
path: ["documentStore"],
|
|
149
|
+
message: `documentStore 'postgres-jsonb' shares the command store's Postgres connection, so it needs commandStore 'postgres' (not '${infra.commandStore}')`
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (infra.eventBus === "redis-streams" && infra.documentStore === "in-memory") {
|
|
153
|
+
ctx.addIssue({
|
|
154
|
+
code: z.ZodIssueCode.custom,
|
|
155
|
+
path: ["eventBus"],
|
|
156
|
+
message: `eventBus 'redis-streams' needs a shared documentStore ('redis' or 'postgres-jsonb'), not 'in-memory': a named group hands each event to one instance, so a per-process read model would miss the rest`
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (infra.s3 !== void 0 && infra.media !== "s3") {
|
|
160
|
+
ctx.addIssue({
|
|
161
|
+
code: z.ZodIssueCode.custom,
|
|
162
|
+
path: ["s3"],
|
|
163
|
+
message: `infrastructure.s3 configures media 's3', but media is '${infra.media}': set media to 's3' or delete the s3 block`
|
|
164
|
+
});
|
|
165
|
+
}
|
|
81
166
|
});
|
|
82
167
|
var securitySchema = z.object({
|
|
83
168
|
adapter: z.enum(["middleware", "cloudflare", "aws-waf", "akamai"]),
|
|
@@ -162,29 +247,6 @@ var nymbalConfigSchema = z.object({
|
|
|
162
247
|
autoUpdates: false
|
|
163
248
|
})
|
|
164
249
|
}).superRefine((cfg, ctx) => {
|
|
165
|
-
if (cfg.infrastructure.cloud === "local") {
|
|
166
|
-
if (!["in-memory", "postgres-jsonb"].includes(cfg.infrastructure.documentStore)) {
|
|
167
|
-
ctx.addIssue({
|
|
168
|
-
code: z.ZodIssueCode.custom,
|
|
169
|
-
path: ["infrastructure", "documentStore"],
|
|
170
|
-
message: `cloud=local only supports 'in-memory' or 'postgres-jsonb' for documentStore`
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
if (!["in-process", "redis-streams"].includes(cfg.infrastructure.eventBus)) {
|
|
174
|
-
ctx.addIssue({
|
|
175
|
-
code: z.ZodIssueCode.custom,
|
|
176
|
-
path: ["infrastructure", "eventBus"],
|
|
177
|
-
message: `cloud=local only supports 'in-process' or 'redis-streams' for eventBus`
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
if (!["in-process", "worker-threads"].includes(cfg.infrastructure.compute)) {
|
|
181
|
-
ctx.addIssue({
|
|
182
|
-
code: z.ZodIssueCode.custom,
|
|
183
|
-
path: ["infrastructure", "compute"],
|
|
184
|
-
message: `cloud=local only supports 'in-process' or 'worker-threads' for compute`
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
250
|
const email = cfg.commerce.email;
|
|
189
251
|
if (email.provider === "native" && email.config?.["transport"] === "smtp") {
|
|
190
252
|
ctx.addIssue({
|
|
@@ -193,15 +255,6 @@ var nymbalConfigSchema = z.object({
|
|
|
193
255
|
message: `the native email provider only prints to the console; for SMTP mail set email.provider to 'smtp' (@nymbalhq/adapter-smtp)`
|
|
194
256
|
});
|
|
195
257
|
}
|
|
196
|
-
if (cfg.security.adapter === "middleware") {
|
|
197
|
-
if (["aws", "gcp", "azure"].includes(cfg.infrastructure.cloud)) {
|
|
198
|
-
ctx.addIssue({
|
|
199
|
-
code: z.ZodIssueCode.custom,
|
|
200
|
-
path: ["security", "adapter"],
|
|
201
|
-
message: `security.adapter='middleware' is intended for local/docker development. Use a WAF adapter ('cloudflare', 'aws-waf', 'akamai') for cloud=${cfg.infrastructure.cloud}.`
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
258
|
});
|
|
206
259
|
|
|
207
260
|
// src/load.ts
|
|
@@ -225,18 +278,20 @@ async function loadConfig(startDir = process.cwd()) {
|
|
|
225
278
|
);
|
|
226
279
|
}
|
|
227
280
|
const jiti = createJiti(pathToFileURL(path).href, { interopDefault: true });
|
|
228
|
-
let
|
|
281
|
+
let mod;
|
|
229
282
|
try {
|
|
230
|
-
|
|
283
|
+
mod = await jiti.import(path);
|
|
231
284
|
} catch (err) {
|
|
232
285
|
throw new ConfigError2(`Failed to load ${path}: ${err.message}`, {
|
|
233
286
|
cause: err,
|
|
234
287
|
context: { path }
|
|
235
288
|
});
|
|
236
289
|
}
|
|
290
|
+
const raw = mod["default"] ?? mod;
|
|
291
|
+
const adapters = adaptersExport(mod["adapters"], path);
|
|
237
292
|
try {
|
|
238
293
|
const config = nymbalConfigSchema.parse(raw);
|
|
239
|
-
return { config, path, projectRoot: dirname(path) };
|
|
294
|
+
return { config, path, projectRoot: dirname(path), ...adapters !== void 0 && { adapters } };
|
|
240
295
|
} catch (err) {
|
|
241
296
|
if (err instanceof z2.ZodError) {
|
|
242
297
|
throw new ConfigError2(formatZodError(err, path), {
|
|
@@ -247,6 +302,24 @@ async function loadConfig(startDir = process.cwd()) {
|
|
|
247
302
|
throw err;
|
|
248
303
|
}
|
|
249
304
|
}
|
|
305
|
+
function adaptersExport(value, path) {
|
|
306
|
+
if (value === void 0) return void 0;
|
|
307
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
308
|
+
throw new ConfigError2(`${path}: the adapters export must be an object keyed by commerce slot`, {
|
|
309
|
+
code: "config.adapters_invalid",
|
|
310
|
+
context: { path }
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const slots = Object.keys(KNOWN_PROVIDERS);
|
|
314
|
+
const unknown = Object.keys(value).filter((key) => !slots.includes(key));
|
|
315
|
+
if (unknown.length > 0) {
|
|
316
|
+
throw new ConfigError2(
|
|
317
|
+
`${path}: the adapters export names ${unknown.join(", ")}, which is no commerce slot (${slots.join(", ")})`,
|
|
318
|
+
{ code: "config.adapters_invalid", context: { path, unknown } }
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
return value;
|
|
322
|
+
}
|
|
250
323
|
function formatZodError(err, path) {
|
|
251
324
|
const lines = err.issues.map((issue) => {
|
|
252
325
|
const at = issue.path.length > 0 ? issue.path.join(".") : "<root>";
|
|
@@ -257,7 +330,9 @@ ${lines.join("\n")}`;
|
|
|
257
330
|
}
|
|
258
331
|
export {
|
|
259
332
|
DEFAULT_JWT_SECRET,
|
|
333
|
+
KNOWN_INFRASTRUCTURE,
|
|
260
334
|
KNOWN_PROVIDERS,
|
|
335
|
+
REMOVED_INFRASTRUCTURE_KEYS,
|
|
261
336
|
commerceSchema,
|
|
262
337
|
defineConfig,
|
|
263
338
|
deploymentSchema,
|
|
@@ -271,6 +346,8 @@ export {
|
|
|
271
346
|
infrastructureSchema,
|
|
272
347
|
loadConfig,
|
|
273
348
|
nymbalConfigSchema,
|
|
349
|
+
redisSchema,
|
|
350
|
+
s3Schema,
|
|
274
351
|
securitySchema,
|
|
275
352
|
storeSchema
|
|
276
353
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/define-config.ts","../src/env.ts","../src/known-providers.ts","../src/load.ts","../src/schema.ts"],"sourcesContent":["import type { NymbalConfigInput } from './schema.js'\n\nexport function defineConfig<T extends NymbalConfigInput>(config: T): T {\n return config\n}\n","import { ConfigError } from '@nymbalhq/types'\n\nexport function env(key: string, defaultValue?: string): string {\n const value = process.env[key]\n if (value !== undefined && value !== '') return value\n if (defaultValue !== undefined) return defaultValue\n throw new ConfigError(`Missing required environment variable: ${key}`, {\n context: { key },\n })\n}\n\nexport function envOptional(key: string): string | undefined {\n const value = process.env[key]\n return value !== undefined && value !== '' ? value : undefined\n}\n\nexport function envNumber(key: string, defaultValue?: number): number {\n const raw = envOptional(key)\n if (raw === undefined) {\n if (defaultValue !== undefined) return defaultValue\n throw new ConfigError(`Missing required environment variable: ${key}`, { context: { key } })\n }\n const parsed = Number(raw)\n if (!Number.isFinite(parsed)) {\n throw new ConfigError(`Environment variable ${key} is not a valid number: ${raw}`, {\n context: { key, raw },\n })\n }\n return parsed\n}\n\nexport function envBool(key: string, defaultValue = false): boolean {\n const raw = envOptional(key)?.toLowerCase()\n if (raw === undefined) return defaultValue\n return raw === 'true' || raw === '1' || raw === 'yes' || raw === 'on'\n}\n","import type { CommerceSlot } from '@nymbalhq/types'\n\nexport type { CommerceSlot }\n\n/**\n * The providers each commerce slot accepts. A provider that needs an SDK lives in an `@nymbalhq/adapter-*` package the\n * kernel loads only when the config names it; `custom` takes the adapter a project passes to `createApp`.\n */\nexport const KNOWN_PROVIDERS = {\n payments: ['native', 'stripe', 'custom'],\n email: ['native', 'smtp', 'custom'],\n reviews: ['native', 'custom'],\n search: ['native', 'custom'],\n analytics: ['native', 'custom'],\n shipping: ['native', 'custom'],\n tax: ['native', 'custom'],\n ai: ['none', 'anthropic', 'custom'],\n} as const satisfies Readonly<Record<CommerceSlot, readonly [string, ...string[]]>>\n","import { existsSync } from 'node:fs'\nimport { dirname, isAbsolute, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { createJiti } from 'jiti'\nimport { z } from 'zod'\nimport { ConfigError } from '@nymbalhq/types'\nimport { nymbalConfigSchema, type NymbalConfig } from './schema.js'\n\nconst CONFIG_FILE = 'nymbal.config.ts'\n\nexport interface LoadedConfig {\n config: NymbalConfig\n path: string\n projectRoot: string\n}\n\nexport function findConfigFile(startDir: string): string | null {\n let current = isAbsolute(startDir) ? startDir : resolve(startDir)\n while (true) {\n const candidate = resolve(current, CONFIG_FILE)\n if (existsSync(candidate)) return candidate\n const parent = dirname(current)\n if (parent === current) return null\n current = parent\n }\n}\n\nexport async function loadConfig(startDir: string = process.cwd()): Promise<LoadedConfig> {\n const path = findConfigFile(startDir)\n if (!path) {\n throw new ConfigError(\n `Could not find ${CONFIG_FILE} in ${startDir} or any parent directory.`,\n { context: { startDir } },\n )\n }\n\n const jiti = createJiti(pathToFileURL(path).href, { interopDefault: true })\n let raw: unknown\n try {\n raw = await jiti.import(path, { default: true })\n } catch (err) {\n throw new ConfigError(`Failed to load ${path}: ${(err as Error).message}`, {\n cause: err,\n context: { path },\n })\n }\n\n try {\n const config = nymbalConfigSchema.parse(raw)\n return { config, path, projectRoot: dirname(path) }\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new ConfigError(formatZodError(err, path), {\n cause: err,\n context: { path, issues: err.issues },\n })\n }\n throw err\n }\n}\n\nfunction formatZodError(err: z.ZodError, path: string): string {\n const lines = err.issues.map((issue) => {\n const at = issue.path.length > 0 ? issue.path.join('.') : '<root>'\n return ` • ${at}: ${issue.message}`\n })\n return `Invalid configuration in ${path}:\\n${lines.join('\\n')}`\n}\n","import { z } from 'zod'\nimport { KNOWN_PROVIDERS, type CommerceSlot } from './known-providers.js'\n\nconst rateLimitRuleSchema = z.object({\n requests: z.number().int().positive(),\n window: z.string().regex(/^\\d+(ms|s|m|h)$/, 'window must look like \"60s\", \"5m\", \"1h\"'),\n action: z.enum(['block', 'challenge', 'throttle']),\n})\n\nconst rateLimitPathPattern = /^\\/[\\w\\-/*:]*$/\n\n/** The schema's JWT secret when none is configured: fine for development, refused in production. */\nexport const DEFAULT_JWT_SECRET = 'dev-secret-please-override-me-1234567890'\n\nexport const storeSchema = z.object({\n name: z.string().min(1),\n currency: z.string().length(3),\n locale: z.string().min(2),\n timezone: z.string().min(1),\n})\n\nexport const infrastructureSchema = z.object({\n cloud: z.enum(['local', 'aws', 'gcp', 'azure', 'docker']),\n commandStore: z.enum(['sqlite', 'postgres']),\n documentStore: z.enum(['in-memory', 'dynamodb', 'firestore', 'cosmosdb', 'postgres-jsonb']),\n eventBus: z.enum(['in-process', 'eventbridge', 'pubsub', 'service-bus', 'redis-streams']),\n compute: z.enum(['in-process', 'lambda', 'cloud-functions', 'azure-functions', 'worker-threads']),\n})\n\nexport const securitySchema = z.object({\n adapter: z.enum(['middleware', 'cloudflare', 'aws-waf', 'akamai']),\n rateLimit: z\n .record(\n z.string().regex(rateLimitPathPattern, {\n message: 'rate limit keys must start with \"/\" and use only letters, numbers, -, _, /, *, :',\n }),\n rateLimitRuleSchema,\n )\n .default({}),\n botProtection: z\n .object({\n mode: z.enum(['off', 'managed', 'strict']).default('off'),\n allowList: z.array(z.string()).default([]),\n })\n .default({ mode: 'off', allowList: [] }),\n headers: z\n .object({\n hsts: z.boolean().default(true),\n contentSecurityPolicy: z\n .union([z.enum(['strict', 'relaxed', 'off']), z.string()])\n .default('strict'),\n referrerPolicy: z.string().default('strict-origin-when-cross-origin'),\n xFrameOptions: z.enum(['deny', 'sameorigin']).default('deny'),\n })\n .default({}),\n csrf: z.boolean().default(true),\n auth: z\n .object({\n jwtSecret: z.string().min(16).default(DEFAULT_JWT_SECRET),\n accessTtl: z\n .string()\n .regex(/^\\d+(ms|s|m|h|d)$/, 'TTL must look like \"15m\"')\n .default('15m'),\n refreshTtl: z\n .string()\n .regex(/^\\d+(ms|s|m|h|d)$/, 'TTL must look like \"7d\"')\n .default('7d'),\n })\n .default({}),\n})\n\n/** A slot's block: its provider must be one the slot knows, and an unknown one is named with the slot's list. */\nfunction adapterBlock<const P extends readonly [string, ...string[]]>(\n slot: CommerceSlot,\n providers: P,\n) {\n const known = providers.map((p) => `'${p}'`).join(', ')\n return z.object({\n provider: z.enum(providers, {\n errorMap: (issue, ctx) =>\n issue.code === z.ZodIssueCode.invalid_enum_value\n ? {\n message: `unknown ${slot} provider '${String(issue.received)}'; the ${slot} providers are ${known}`,\n }\n : { message: ctx.defaultError },\n }),\n config: z.record(z.string(), z.unknown()).optional(),\n })\n}\n\nexport const commerceSchema = z.object({\n payments: adapterBlock('payments', KNOWN_PROVIDERS.payments),\n email: adapterBlock('email', KNOWN_PROVIDERS.email),\n reviews: adapterBlock('reviews', KNOWN_PROVIDERS.reviews),\n search: adapterBlock('search', KNOWN_PROVIDERS.search),\n analytics: adapterBlock('analytics', KNOWN_PROVIDERS.analytics),\n shipping: adapterBlock('shipping', KNOWN_PROVIDERS.shipping),\n tax: adapterBlock('tax', KNOWN_PROVIDERS.tax),\n ai: adapterBlock('ai', KNOWN_PROVIDERS.ai),\n orders: z\n .object({\n numberPrefix: z.string().min(1).default('NYM'),\n numberStart: z.number().int().nonnegative().default(1000),\n })\n .default({}),\n})\n\nexport const httpSchema = z.object({\n adapter: z.enum(['fastify', 'hono']).default('fastify'),\n port: z.number().int().positive().default(3001),\n host: z.string().default('0.0.0.0'),\n /** Whether `X-Forwarded-For` sets the client IP the rate limiter keys on; only behind a proxy you run. */\n trustProxy: z.boolean().default(false),\n cors: z\n .object({\n allowedOrigins: z\n .array(z.string())\n .default(['http://localhost:3000', 'http://localhost:4321']),\n credentials: z.boolean().default(true),\n })\n .default({}),\n})\n\nexport const deploymentSchema = z.object({\n strategy: z.enum(['standard', 'blue-green']).default('standard'),\n})\n\nexport const featuresSchema = z.object({\n staging: z.boolean().default(false),\n heartbeat: z.boolean().default(false),\n autoUpdates: z.boolean().default(false),\n})\n\nexport const nymbalConfigSchema = z\n .object({\n store: storeSchema,\n template: z.enum(['astro', 'nextjs']),\n infrastructure: infrastructureSchema,\n security: securitySchema,\n commerce: commerceSchema,\n http: httpSchema,\n deployment: deploymentSchema,\n features: featuresSchema.default({\n staging: false,\n heartbeat: false,\n autoUpdates: false,\n }),\n })\n .superRefine((cfg, ctx) => {\n // Local infrastructure restricts which document-store / event-bus options make sense.\n if (cfg.infrastructure.cloud === 'local') {\n if (!['in-memory', 'postgres-jsonb'].includes(cfg.infrastructure.documentStore)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['infrastructure', 'documentStore'],\n message: `cloud=local only supports 'in-memory' or 'postgres-jsonb' for documentStore`,\n })\n }\n if (!['in-process', 'redis-streams'].includes(cfg.infrastructure.eventBus)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['infrastructure', 'eventBus'],\n message: `cloud=local only supports 'in-process' or 'redis-streams' for eventBus`,\n })\n }\n if (!['in-process', 'worker-threads'].includes(cfg.infrastructure.compute)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['infrastructure', 'compute'],\n message: `cloud=local only supports 'in-process' or 'worker-threads' for compute`,\n })\n }\n }\n\n // SMTP left the kernel for @nymbalhq/adapter-smtp; a native block still asking for it would print to the console.\n const email = cfg.commerce.email\n if (email.provider === 'native' && email.config?.['transport'] === 'smtp') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['commerce', 'email', 'config', 'transport'],\n message: `the native email provider only prints to the console; for SMTP mail set email.provider to 'smtp' (@nymbalhq/adapter-smtp)`,\n })\n }\n\n // middleware security adapter is v0.1 and not intended for managed-cloud production deployments.\n if (cfg.security.adapter === 'middleware') {\n if (['aws', 'gcp', 'azure'].includes(cfg.infrastructure.cloud)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['security', 'adapter'],\n message: `security.adapter='middleware' is intended for local/docker development. Use a WAF adapter ('cloudflare', 'aws-waf', 'akamai') for cloud=${cfg.infrastructure.cloud}.`,\n })\n }\n }\n })\n\nexport type NymbalConfigInput = z.input<typeof nymbalConfigSchema>\nexport type NymbalConfig = z.output<typeof nymbalConfigSchema>\n"],"mappings":"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","names":["z","ConfigError","ConfigError","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/define-config.ts","../src/env.ts","../src/known-providers.ts","../src/known-infrastructure.ts","../src/load.ts","../src/schema.ts"],"sourcesContent":["import type { NymbalConfigInput } from './schema.js'\n\nexport function defineConfig<T extends NymbalConfigInput>(config: T): T {\n return config\n}\n","import { ConfigError } from '@nymbalhq/types'\n\nexport function env(key: string, defaultValue?: string): string {\n const value = process.env[key]\n if (value !== undefined && value !== '') return value\n if (defaultValue !== undefined) return defaultValue\n throw new ConfigError(`Missing required environment variable: ${key}`, {\n context: { key },\n })\n}\n\nexport function envOptional(key: string): string | undefined {\n const value = process.env[key]\n return value !== undefined && value !== '' ? value : undefined\n}\n\nexport function envNumber(key: string, defaultValue?: number): number {\n const raw = envOptional(key)\n if (raw === undefined) {\n if (defaultValue !== undefined) return defaultValue\n throw new ConfigError(`Missing required environment variable: ${key}`, { context: { key } })\n }\n const parsed = Number(raw)\n if (!Number.isFinite(parsed)) {\n throw new ConfigError(`Environment variable ${key} is not a valid number: ${raw}`, {\n context: { key, raw },\n })\n }\n return parsed\n}\n\nexport function envBool(key: string, defaultValue = false): boolean {\n const raw = envOptional(key)?.toLowerCase()\n if (raw === undefined) return defaultValue\n return raw === 'true' || raw === '1' || raw === 'yes' || raw === 'on'\n}\n","import type { CommerceSlot } from '@nymbalhq/types'\n\nexport type { CommerceSlot }\n\n/**\n * The providers each commerce slot accepts. A provider that needs an SDK lives in an `@nymbalhq/adapter-*` package the\n * kernel loads only when the config names it; `custom` takes the adapter a project passes to `createApp`.\n */\nexport const KNOWN_PROVIDERS = {\n payments: ['native', 'stripe', 'custom'],\n email: ['native', 'smtp', 'custom'],\n reviews: ['native', 'custom'],\n search: ['native', 'custom'],\n analytics: ['native', 'custom'],\n shipping: ['native', 'custom'],\n tax: ['native', 'custom'],\n ai: ['none', 'anthropic', 'custom'],\n} as const satisfies Readonly<Record<CommerceSlot, readonly [string, ...string[]]>>\n","/**\n * The values each infrastructure slot accepts: only what is built. `in-memory`, `in-process` and `local-fs` are the\n * kernel's own; `redis`, `postgres-jsonb`, `redis-streams` and `s3` live in `@nymbalhq/*` packages the kernel loads\n * only when the config names them.\n */\nexport const KNOWN_INFRASTRUCTURE = {\n commandStore: ['sqlite', 'postgres'],\n documentStore: ['in-memory', 'redis', 'postgres-jsonb'],\n eventBus: ['in-process', 'redis-streams'],\n media: ['local-fs', 's3'],\n} as const satisfies Readonly<Record<string, readonly [string, ...string[]]>>\n\nexport type InfrastructureSlot = keyof typeof KNOWN_INFRASTRUCTURE\n\n/** Keys that drove nothing and were removed; a config that still sets one is told to delete it. */\nexport const REMOVED_INFRASTRUCTURE_KEYS = ['cloud', 'compute'] as const\n","import { existsSync } from 'node:fs'\nimport { dirname, isAbsolute, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { createJiti } from 'jiti'\nimport { z } from 'zod'\nimport { ConfigError, type CommerceSlotAdapters } from '@nymbalhq/types'\nimport { KNOWN_PROVIDERS } from './known-providers.js'\nimport { nymbalConfigSchema, type NymbalConfig } from './schema.js'\n\nconst CONFIG_FILE = 'nymbal.config.ts'\n\nexport interface LoadedConfig {\n config: NymbalConfig\n path: string\n projectRoot: string\n /** The module's named `adapters` export: one adapter per slot whose provider is `custom`, for createApp. */\n adapters?: Partial<CommerceSlotAdapters>\n}\n\nexport function findConfigFile(startDir: string): string | null {\n let current = isAbsolute(startDir) ? startDir : resolve(startDir)\n while (true) {\n const candidate = resolve(current, CONFIG_FILE)\n if (existsSync(candidate)) return candidate\n const parent = dirname(current)\n if (parent === current) return null\n current = parent\n }\n}\n\nexport async function loadConfig(startDir: string = process.cwd()): Promise<LoadedConfig> {\n const path = findConfigFile(startDir)\n if (!path) {\n throw new ConfigError(\n `Could not find ${CONFIG_FILE} in ${startDir} or any parent directory.`,\n { context: { startDir } },\n )\n }\n\n const jiti = createJiti(pathToFileURL(path).href, { interopDefault: true })\n let mod: Record<string, unknown>\n try {\n mod = await jiti.import<Record<string, unknown>>(path)\n } catch (err) {\n throw new ConfigError(`Failed to load ${path}: ${(err as Error).message}`, {\n cause: err,\n context: { path },\n })\n }\n\n const raw = mod['default'] ?? mod\n const adapters = adaptersExport(mod['adapters'], path)\n try {\n const config = nymbalConfigSchema.parse(raw)\n return { config, path, projectRoot: dirname(path), ...(adapters !== undefined && { adapters }) }\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new ConfigError(formatZodError(err, path), {\n cause: err,\n context: { path, issues: err.issues },\n })\n }\n throw err\n }\n}\n\n/** The `adapters` export, keyed by commerce slot; anything else is a mistake worth naming before createApp runs. */\nfunction adaptersExport(value: unknown, path: string): Partial<CommerceSlotAdapters> | undefined {\n if (value === undefined) return undefined\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new ConfigError(`${path}: the adapters export must be an object keyed by commerce slot`, {\n code: 'config.adapters_invalid',\n context: { path },\n })\n }\n const slots = Object.keys(KNOWN_PROVIDERS)\n const unknown = Object.keys(value).filter((key) => !slots.includes(key))\n if (unknown.length > 0) {\n throw new ConfigError(\n `${path}: the adapters export names ${unknown.join(', ')}, which is no commerce slot (${slots.join(', ')})`,\n { code: 'config.adapters_invalid', context: { path, unknown } },\n )\n }\n return value as Partial<CommerceSlotAdapters>\n}\n\nfunction formatZodError(err: z.ZodError, path: string): string {\n const lines = err.issues.map((issue) => {\n const at = issue.path.length > 0 ? issue.path.join('.') : '<root>'\n return ` • ${at}: ${issue.message}`\n })\n return `Invalid configuration in ${path}:\\n${lines.join('\\n')}`\n}\n","import { z } from 'zod'\nimport {\n KNOWN_INFRASTRUCTURE,\n REMOVED_INFRASTRUCTURE_KEYS,\n type InfrastructureSlot,\n} from './known-infrastructure.js'\nimport { KNOWN_PROVIDERS, type CommerceSlot } from './known-providers.js'\n\nconst rateLimitRuleSchema = z.object({\n requests: z.number().int().positive(),\n window: z.string().regex(/^\\d+(ms|s|m|h)$/, 'window must look like \"60s\", \"5m\", \"1h\"'),\n action: z.enum(['block', 'challenge', 'throttle']),\n})\n\nconst rateLimitPathPattern = /^\\/[\\w\\-/*:]*$/\n\n/** The schema's JWT secret when none is configured: fine for development, refused in production. */\nexport const DEFAULT_JWT_SECRET = 'dev-secret-please-override-me-1234567890'\n\nexport const storeSchema = z.object({\n name: z.string().min(1),\n currency: z.string().length(3),\n locale: z.string().min(2),\n timezone: z.string().min(1),\n})\n\nconst quotedList = (values: readonly string[]): string => values.map((v) => `'${v}'`).join(', ')\n\n/** A slot's value must be one the slot lists; an unknown one is named with the list. */\nfunction infrastructureValue<const V extends readonly [string, ...string[]]>(\n slot: InfrastructureSlot,\n values: V,\n) {\n return z.enum(values, {\n errorMap: (issue, ctx) =>\n issue.code === z.ZodIssueCode.invalid_enum_value\n ? {\n message: `unknown ${slot} '${String(issue.received)}'; the ${slot} values are ${quotedList(values)}`,\n }\n : { message: ctx.defaultError },\n })\n}\n\nconst INFRASTRUCTURE_KEYS = [...Object.keys(KNOWN_INFRASTRUCTURE), 'redis', 's3']\n\nfunction unrecognizedInfrastructureKeys(keys: string[]): string {\n return keys\n .map((key) =>\n (REMOVED_INFRASTRUCTURE_KEYS as readonly string[]).includes(key)\n ? `infrastructure.${key} was removed: it drives nothing, so delete it from the config`\n : `unknown infrastructure key '${key}'; the infrastructure keys are ${quotedList(INFRASTRUCTURE_KEYS)}`,\n )\n .join('; ')\n}\n\n/** The shared Redis connection of the `redis` document store and the `redis-streams` bus. */\nexport const redisSchema = z\n .object({\n /** Defaults to `REDIS_URL`. */\n url: z.string().min(1).optional(),\n /** Namespaces every key and stream; defaults to `NYMBAL_REDIS_PREFIX`, then `'nymbal'`. */\n prefix: z.string().min(1).optional(),\n /** How long a publish waits for the groups it delivers to (default 15 000). */\n ackTimeoutMs: z.number().int().positive().optional(),\n /** How long an entry may stay pending on a consumer before a live one takes it over (default 5 000). */\n claimIdleMs: z.number().int().positive().optional(),\n /** The approximate length each stream is trimmed to (default 10 000). */\n streamMaxLen: z.number().int().positive().optional(),\n })\n .strict()\n\nconst S3_KEYS = ['bucket', 'region', 'endpoint', 'prefix', 'publicUrl', 'forcePathStyle']\n\n/**\n * The bucket `media: 's3'` stores in. Each field falls back to the environment in the platform; credentials are never\n * config keys: the AWS SDK's default chain provides them.\n */\nexport const s3Schema = z\n .object(\n {\n /** Defaults to `S3_BUCKET`; one of the two is required. */\n bucket: z.string().min(1).optional(),\n /** Defaults to `AWS_REGION`, then `'us-east-1'`. */\n region: z.string().min(1).optional(),\n /** An S3-compatible API (MinIO, R2); defaults to `S3_ENDPOINT`, then AWS. */\n endpoint: z.string().min(1).optional(),\n /** Where every object key starts; defaults to `NYMBAL_S3_PREFIX`, then none. */\n prefix: z.string().optional(),\n /** Where the bucket's objects are served from (a CDN); defaults to `S3_PUBLIC_URL`, then the bucket's own URL. */\n publicUrl: z.string().min(1).optional(),\n /** Path-style requests; true by default when an endpoint is set. */\n forcePathStyle: z.boolean().optional(),\n },\n {\n errorMap: (issue, ctx) =>\n issue.code === z.ZodIssueCode.unrecognized_keys\n ? {\n message: `unknown infrastructure.s3 key${issue.keys.length > 1 ? 's' : ''} ${quotedList(issue.keys)}; the s3 keys are ${quotedList(S3_KEYS)}, and credentials come from the AWS SDK (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, a profile or a role), never the config`,\n }\n : { message: ctx.defaultError },\n },\n )\n .strict()\n\nexport const infrastructureSchema = z\n .object(\n {\n commandStore: infrastructureValue('commandStore', KNOWN_INFRASTRUCTURE.commandStore),\n documentStore: infrastructureValue('documentStore', KNOWN_INFRASTRUCTURE.documentStore),\n eventBus: infrastructureValue('eventBus', KNOWN_INFRASTRUCTURE.eventBus),\n media: infrastructureValue('media', KNOWN_INFRASTRUCTURE.media).default('local-fs'),\n redis: redisSchema.optional(),\n s3: s3Schema.optional(),\n },\n {\n errorMap: (issue, ctx) =>\n issue.code === z.ZodIssueCode.unrecognized_keys\n ? { message: unrecognizedInfrastructureKeys(issue.keys) }\n : { message: ctx.defaultError },\n },\n )\n .strict()\n .superRefine((infra, ctx) => {\n if (infra.documentStore === 'postgres-jsonb' && infra.commandStore !== 'postgres') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['documentStore'],\n message: `documentStore 'postgres-jsonb' shares the command store's Postgres connection, so it needs commandStore 'postgres' (not '${infra.commandStore}')`,\n })\n }\n if (infra.eventBus === 'redis-streams' && infra.documentStore === 'in-memory') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['eventBus'],\n message: `eventBus 'redis-streams' needs a shared documentStore ('redis' or 'postgres-jsonb'), not 'in-memory': a named group hands each event to one instance, so a per-process read model would miss the rest`,\n })\n }\n if (infra.s3 !== undefined && infra.media !== 's3') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['s3'],\n message: `infrastructure.s3 configures media 's3', but media is '${infra.media}': set media to 's3' or delete the s3 block`,\n })\n }\n })\n\nexport const securitySchema = z.object({\n adapter: z.enum(['middleware', 'cloudflare', 'aws-waf', 'akamai']),\n rateLimit: z\n .record(\n z.string().regex(rateLimitPathPattern, {\n message: 'rate limit keys must start with \"/\" and use only letters, numbers, -, _, /, *, :',\n }),\n rateLimitRuleSchema,\n )\n .default({}),\n botProtection: z\n .object({\n mode: z.enum(['off', 'managed', 'strict']).default('off'),\n allowList: z.array(z.string()).default([]),\n })\n .default({ mode: 'off', allowList: [] }),\n headers: z\n .object({\n hsts: z.boolean().default(true),\n contentSecurityPolicy: z\n .union([z.enum(['strict', 'relaxed', 'off']), z.string()])\n .default('strict'),\n referrerPolicy: z.string().default('strict-origin-when-cross-origin'),\n xFrameOptions: z.enum(['deny', 'sameorigin']).default('deny'),\n })\n .default({}),\n csrf: z.boolean().default(true),\n auth: z\n .object({\n jwtSecret: z.string().min(16).default(DEFAULT_JWT_SECRET),\n accessTtl: z\n .string()\n .regex(/^\\d+(ms|s|m|h|d)$/, 'TTL must look like \"15m\"')\n .default('15m'),\n refreshTtl: z\n .string()\n .regex(/^\\d+(ms|s|m|h|d)$/, 'TTL must look like \"7d\"')\n .default('7d'),\n })\n .default({}),\n})\n\n/** A slot's block: its provider must be one the slot knows, and an unknown one is named with the slot's list. */\nfunction adapterBlock<const P extends readonly [string, ...string[]]>(\n slot: CommerceSlot,\n providers: P,\n) {\n const known = providers.map((p) => `'${p}'`).join(', ')\n return z.object({\n provider: z.enum(providers, {\n errorMap: (issue, ctx) =>\n issue.code === z.ZodIssueCode.invalid_enum_value\n ? {\n message: `unknown ${slot} provider '${String(issue.received)}'; the ${slot} providers are ${known}`,\n }\n : { message: ctx.defaultError },\n }),\n config: z.record(z.string(), z.unknown()).optional(),\n })\n}\n\nexport const commerceSchema = z.object({\n payments: adapterBlock('payments', KNOWN_PROVIDERS.payments),\n email: adapterBlock('email', KNOWN_PROVIDERS.email),\n reviews: adapterBlock('reviews', KNOWN_PROVIDERS.reviews),\n search: adapterBlock('search', KNOWN_PROVIDERS.search),\n analytics: adapterBlock('analytics', KNOWN_PROVIDERS.analytics),\n shipping: adapterBlock('shipping', KNOWN_PROVIDERS.shipping),\n tax: adapterBlock('tax', KNOWN_PROVIDERS.tax),\n ai: adapterBlock('ai', KNOWN_PROVIDERS.ai),\n orders: z\n .object({\n numberPrefix: z.string().min(1).default('NYM'),\n numberStart: z.number().int().nonnegative().default(1000),\n })\n .default({}),\n})\n\nexport const httpSchema = z.object({\n adapter: z.enum(['fastify', 'hono']).default('fastify'),\n port: z.number().int().positive().default(3001),\n host: z.string().default('0.0.0.0'),\n /** Whether `X-Forwarded-For` sets the client IP the rate limiter keys on; only behind a proxy you run. */\n trustProxy: z.boolean().default(false),\n cors: z\n .object({\n allowedOrigins: z\n .array(z.string())\n .default(['http://localhost:3000', 'http://localhost:4321']),\n credentials: z.boolean().default(true),\n })\n .default({}),\n})\n\nexport const deploymentSchema = z.object({\n strategy: z.enum(['standard', 'blue-green']).default('standard'),\n})\n\nexport const featuresSchema = z.object({\n staging: z.boolean().default(false),\n heartbeat: z.boolean().default(false),\n autoUpdates: z.boolean().default(false),\n})\n\nexport const nymbalConfigSchema = z\n .object({\n store: storeSchema,\n template: z.enum(['astro', 'nextjs']),\n infrastructure: infrastructureSchema,\n security: securitySchema,\n commerce: commerceSchema,\n http: httpSchema,\n deployment: deploymentSchema,\n features: featuresSchema.default({\n staging: false,\n heartbeat: false,\n autoUpdates: false,\n }),\n })\n .superRefine((cfg, ctx) => {\n // SMTP left the kernel for @nymbalhq/adapter-smtp; a native block still asking for it would print to the console.\n const email = cfg.commerce.email\n if (email.provider === 'native' && email.config?.['transport'] === 'smtp') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['commerce', 'email', 'config', 'transport'],\n message: `the native email provider only prints to the console; for SMTP mail set email.provider to 'smtp' (@nymbalhq/adapter-smtp)`,\n })\n }\n })\n\nexport type NymbalConfigInput = z.input<typeof nymbalConfigSchema>\nexport type NymbalConfig = z.output<typeof nymbalConfigSchema>\n"],"mappings":"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","names":["z","ConfigError","ConfigError","z"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nymbalhq/config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Typed configuration surface for Nymbal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"jiti": "^2.4.0",
|
|
31
31
|
"zod": "^3.23.8",
|
|
32
|
-
"@nymbalhq/types": "1.
|
|
32
|
+
"@nymbalhq/types": "1.1.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"tsup": "^8.3.5",
|