@digilogiclabs/platform-core 1.2.0 → 1.4.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/README.md +659 -545
- package/dist/{ConsoleEmail-hUDFsKoA.d.mts → ConsoleEmail-ubSVWgTa.d.mts} +187 -1
- package/dist/{ConsoleEmail-hUDFsKoA.d.ts → ConsoleEmail-ubSVWgTa.d.ts} +187 -1
- package/dist/index.d.mts +683 -35
- package/dist/index.d.ts +683 -35
- package/dist/index.js +5818 -462
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5798 -456
- package/dist/index.mjs.map +1 -1
- package/dist/migrate.js +91 -33
- package/dist/migrate.js.map +1 -1
- package/dist/migrations/index.js +33 -13
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/index.mjs +33 -13
- package/dist/migrations/index.mjs.map +1 -1
- package/dist/security-headers.d.mts +75 -0
- package/dist/security-headers.d.ts +75 -0
- package/dist/security-headers.js +137 -0
- package/dist/security-headers.js.map +1 -0
- package/dist/security-headers.mjs +111 -0
- package/dist/security-headers.mjs.map +1 -0
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +292 -37
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +291 -36
- package/dist/testing.mjs.map +1 -1
- package/package.json +11 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Security Headers Utility
|
|
3
|
+
* Generates consistent security headers for all Next.js apps.
|
|
4
|
+
* Zero heavy dependencies — pure utility function.
|
|
5
|
+
*/
|
|
6
|
+
interface SecurityHeadersConfig {
|
|
7
|
+
/** Enable Content-Security-Policy (default: true) */
|
|
8
|
+
csp?: boolean;
|
|
9
|
+
/** Additional allowed script-src domains */
|
|
10
|
+
cspScriptSrc?: string[];
|
|
11
|
+
/** Additional allowed connect-src domains */
|
|
12
|
+
cspConnectSrc?: string[];
|
|
13
|
+
/** Additional allowed frame-src domains */
|
|
14
|
+
cspFrameSrc?: string[];
|
|
15
|
+
/** Additional allowed style-src domains */
|
|
16
|
+
cspStyleSrc?: string[];
|
|
17
|
+
/** Additional allowed img-src domains */
|
|
18
|
+
cspImgSrc?: string[];
|
|
19
|
+
/** X-Frame-Options value (default: 'DENY') */
|
|
20
|
+
frameOptions?: "DENY" | "SAMEORIGIN";
|
|
21
|
+
/** Enable HSTS in production (default: true) */
|
|
22
|
+
hsts?: boolean;
|
|
23
|
+
/** HSTS max-age in seconds (default: 31536000 = 1 year) */
|
|
24
|
+
hstsMaxAge?: number;
|
|
25
|
+
/** Whether this is a production build (default: auto-detect from NODE_ENV) */
|
|
26
|
+
isProduction?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface NextHeaderEntry {
|
|
29
|
+
source: string;
|
|
30
|
+
headers: Array<{
|
|
31
|
+
key: string;
|
|
32
|
+
value: string;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
declare const SecurityHeaderPresets: {
|
|
36
|
+
/** Minimal: basic headers only, no CSP */
|
|
37
|
+
readonly minimal: {
|
|
38
|
+
csp: false;
|
|
39
|
+
hsts: false;
|
|
40
|
+
};
|
|
41
|
+
/** Standard: full CSP + HSTS for most apps */
|
|
42
|
+
readonly standard: {
|
|
43
|
+
csp: true;
|
|
44
|
+
hsts: true;
|
|
45
|
+
frameOptions: "DENY";
|
|
46
|
+
};
|
|
47
|
+
/** Strict: deny all permissions, strict CSP, no frame embedding */
|
|
48
|
+
readonly strict: {
|
|
49
|
+
csp: true;
|
|
50
|
+
hsts: true;
|
|
51
|
+
hstsMaxAge: number;
|
|
52
|
+
frameOptions: "DENY";
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Generate security headers array compatible with Next.js `headers()` config.
|
|
57
|
+
*
|
|
58
|
+
* Usage in next.config.mjs:
|
|
59
|
+
* ```js
|
|
60
|
+
* const { generateSecurityHeaders } = require('@digilogiclabs/platform-core');
|
|
61
|
+
*
|
|
62
|
+
* module.exports = {
|
|
63
|
+
* async headers() {
|
|
64
|
+
* return generateSecurityHeaders({
|
|
65
|
+
* isProduction: process.env.NODE_ENV === 'production',
|
|
66
|
+
* cspScriptSrc: ['https://js.stripe.com'],
|
|
67
|
+
* cspConnectSrc: ['https://api.stripe.com'],
|
|
68
|
+
* });
|
|
69
|
+
* },
|
|
70
|
+
* };
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function generateSecurityHeaders(config?: SecurityHeadersConfig): NextHeaderEntry[];
|
|
74
|
+
|
|
75
|
+
export { type NextHeaderEntry, SecurityHeaderPresets, type SecurityHeadersConfig, generateSecurityHeaders };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Security Headers Utility
|
|
3
|
+
* Generates consistent security headers for all Next.js apps.
|
|
4
|
+
* Zero heavy dependencies — pure utility function.
|
|
5
|
+
*/
|
|
6
|
+
interface SecurityHeadersConfig {
|
|
7
|
+
/** Enable Content-Security-Policy (default: true) */
|
|
8
|
+
csp?: boolean;
|
|
9
|
+
/** Additional allowed script-src domains */
|
|
10
|
+
cspScriptSrc?: string[];
|
|
11
|
+
/** Additional allowed connect-src domains */
|
|
12
|
+
cspConnectSrc?: string[];
|
|
13
|
+
/** Additional allowed frame-src domains */
|
|
14
|
+
cspFrameSrc?: string[];
|
|
15
|
+
/** Additional allowed style-src domains */
|
|
16
|
+
cspStyleSrc?: string[];
|
|
17
|
+
/** Additional allowed img-src domains */
|
|
18
|
+
cspImgSrc?: string[];
|
|
19
|
+
/** X-Frame-Options value (default: 'DENY') */
|
|
20
|
+
frameOptions?: "DENY" | "SAMEORIGIN";
|
|
21
|
+
/** Enable HSTS in production (default: true) */
|
|
22
|
+
hsts?: boolean;
|
|
23
|
+
/** HSTS max-age in seconds (default: 31536000 = 1 year) */
|
|
24
|
+
hstsMaxAge?: number;
|
|
25
|
+
/** Whether this is a production build (default: auto-detect from NODE_ENV) */
|
|
26
|
+
isProduction?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface NextHeaderEntry {
|
|
29
|
+
source: string;
|
|
30
|
+
headers: Array<{
|
|
31
|
+
key: string;
|
|
32
|
+
value: string;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
declare const SecurityHeaderPresets: {
|
|
36
|
+
/** Minimal: basic headers only, no CSP */
|
|
37
|
+
readonly minimal: {
|
|
38
|
+
csp: false;
|
|
39
|
+
hsts: false;
|
|
40
|
+
};
|
|
41
|
+
/** Standard: full CSP + HSTS for most apps */
|
|
42
|
+
readonly standard: {
|
|
43
|
+
csp: true;
|
|
44
|
+
hsts: true;
|
|
45
|
+
frameOptions: "DENY";
|
|
46
|
+
};
|
|
47
|
+
/** Strict: deny all permissions, strict CSP, no frame embedding */
|
|
48
|
+
readonly strict: {
|
|
49
|
+
csp: true;
|
|
50
|
+
hsts: true;
|
|
51
|
+
hstsMaxAge: number;
|
|
52
|
+
frameOptions: "DENY";
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Generate security headers array compatible with Next.js `headers()` config.
|
|
57
|
+
*
|
|
58
|
+
* Usage in next.config.mjs:
|
|
59
|
+
* ```js
|
|
60
|
+
* const { generateSecurityHeaders } = require('@digilogiclabs/platform-core');
|
|
61
|
+
*
|
|
62
|
+
* module.exports = {
|
|
63
|
+
* async headers() {
|
|
64
|
+
* return generateSecurityHeaders({
|
|
65
|
+
* isProduction: process.env.NODE_ENV === 'production',
|
|
66
|
+
* cspScriptSrc: ['https://js.stripe.com'],
|
|
67
|
+
* cspConnectSrc: ['https://api.stripe.com'],
|
|
68
|
+
* });
|
|
69
|
+
* },
|
|
70
|
+
* };
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function generateSecurityHeaders(config?: SecurityHeadersConfig): NextHeaderEntry[];
|
|
74
|
+
|
|
75
|
+
export { type NextHeaderEntry, SecurityHeaderPresets, type SecurityHeadersConfig, generateSecurityHeaders };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/security-headers.ts
|
|
21
|
+
var security_headers_exports = {};
|
|
22
|
+
__export(security_headers_exports, {
|
|
23
|
+
SecurityHeaderPresets: () => SecurityHeaderPresets,
|
|
24
|
+
generateSecurityHeaders: () => generateSecurityHeaders
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(security_headers_exports);
|
|
27
|
+
var SecurityHeaderPresets = {
|
|
28
|
+
/** Minimal: basic headers only, no CSP */
|
|
29
|
+
minimal: {
|
|
30
|
+
csp: false,
|
|
31
|
+
hsts: false
|
|
32
|
+
},
|
|
33
|
+
/** Standard: full CSP + HSTS for most apps */
|
|
34
|
+
standard: {
|
|
35
|
+
csp: true,
|
|
36
|
+
hsts: true,
|
|
37
|
+
frameOptions: "DENY"
|
|
38
|
+
},
|
|
39
|
+
/** Strict: deny all permissions, strict CSP, no frame embedding */
|
|
40
|
+
strict: {
|
|
41
|
+
csp: true,
|
|
42
|
+
hsts: true,
|
|
43
|
+
hstsMaxAge: 63072e3,
|
|
44
|
+
// 2 years
|
|
45
|
+
frameOptions: "DENY"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
function generateSecurityHeaders(config = {}) {
|
|
49
|
+
const isProduction = config.isProduction ?? process.env.NODE_ENV === "production";
|
|
50
|
+
const frameOptions = config.frameOptions ?? "DENY";
|
|
51
|
+
const enableCsp = config.csp ?? true;
|
|
52
|
+
const enableHsts = config.hsts ?? true;
|
|
53
|
+
const hstsMaxAge = config.hstsMaxAge ?? 31536e3;
|
|
54
|
+
const baseHeaders = [
|
|
55
|
+
{ key: "X-Frame-Options", value: frameOptions },
|
|
56
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
57
|
+
// Modern browsers use CSP, not XSS-Protection. Value '0' disables the
|
|
58
|
+
// legacy filter which can itself introduce vulnerabilities.
|
|
59
|
+
{ key: "X-XSS-Protection", value: "0" },
|
|
60
|
+
{
|
|
61
|
+
key: "Referrer-Policy",
|
|
62
|
+
value: "strict-origin-when-cross-origin"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
key: "Permissions-Policy",
|
|
66
|
+
value: "camera=(), microphone=(), geolocation=()"
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
const entries = [
|
|
70
|
+
{ source: "/:path*", headers: baseHeaders }
|
|
71
|
+
];
|
|
72
|
+
if (isProduction) {
|
|
73
|
+
const prodHeaders = [];
|
|
74
|
+
if (enableHsts) {
|
|
75
|
+
prodHeaders.push({
|
|
76
|
+
key: "Strict-Transport-Security",
|
|
77
|
+
value: `max-age=${hstsMaxAge}; includeSubDomains`
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (enableCsp) {
|
|
81
|
+
const csp = buildCsp(config);
|
|
82
|
+
prodHeaders.push({ key: "Content-Security-Policy", value: csp });
|
|
83
|
+
}
|
|
84
|
+
if (prodHeaders.length > 0) {
|
|
85
|
+
entries.push({ source: "/:path*", headers: prodHeaders });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return entries;
|
|
89
|
+
}
|
|
90
|
+
function buildCsp(config) {
|
|
91
|
+
const scriptSrc = [
|
|
92
|
+
"'self'",
|
|
93
|
+
"'unsafe-inline'",
|
|
94
|
+
"'unsafe-eval'",
|
|
95
|
+
...config.cspScriptSrc ?? []
|
|
96
|
+
];
|
|
97
|
+
const styleSrc = [
|
|
98
|
+
"'self'",
|
|
99
|
+
"'unsafe-inline'",
|
|
100
|
+
"https://fonts.googleapis.com",
|
|
101
|
+
...config.cspStyleSrc ?? []
|
|
102
|
+
];
|
|
103
|
+
const imgSrc = [
|
|
104
|
+
"'self'",
|
|
105
|
+
"data:",
|
|
106
|
+
"https:",
|
|
107
|
+
"blob:",
|
|
108
|
+
...config.cspImgSrc ?? []
|
|
109
|
+
];
|
|
110
|
+
const fontSrc = ["'self'", "data:", "https://fonts.gstatic.com"];
|
|
111
|
+
const connectSrc = ["'self'", ...config.cspConnectSrc ?? []];
|
|
112
|
+
const frameSrc = [...config.cspFrameSrc ?? []];
|
|
113
|
+
const directives = [
|
|
114
|
+
`default-src 'self'`,
|
|
115
|
+
`script-src ${scriptSrc.join(" ")}`,
|
|
116
|
+
`style-src ${styleSrc.join(" ")}`,
|
|
117
|
+
`img-src ${imgSrc.join(" ")}`,
|
|
118
|
+
`font-src ${fontSrc.join(" ")}`,
|
|
119
|
+
`connect-src ${connectSrc.join(" ")}`
|
|
120
|
+
];
|
|
121
|
+
if (frameSrc.length > 0) {
|
|
122
|
+
directives.push(`frame-src ${frameSrc.join(" ")}`);
|
|
123
|
+
}
|
|
124
|
+
directives.push(
|
|
125
|
+
`object-src 'none'`,
|
|
126
|
+
`base-uri 'self'`,
|
|
127
|
+
`form-action 'self'`,
|
|
128
|
+
`frame-ancestors 'none'`
|
|
129
|
+
);
|
|
130
|
+
return directives.join("; ");
|
|
131
|
+
}
|
|
132
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
133
|
+
0 && (module.exports = {
|
|
134
|
+
SecurityHeaderPresets,
|
|
135
|
+
generateSecurityHeaders
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=security-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security-headers.ts"],"sourcesContent":["/**\r\n * Shared Security Headers Utility\r\n * Generates consistent security headers for all Next.js apps.\r\n * Zero heavy dependencies — pure utility function.\r\n */\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// TYPES\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\nexport interface SecurityHeadersConfig {\r\n /** Enable Content-Security-Policy (default: true) */\r\n csp?: boolean;\r\n /** Additional allowed script-src domains */\r\n cspScriptSrc?: string[];\r\n /** Additional allowed connect-src domains */\r\n cspConnectSrc?: string[];\r\n /** Additional allowed frame-src domains */\r\n cspFrameSrc?: string[];\r\n /** Additional allowed style-src domains */\r\n cspStyleSrc?: string[];\r\n /** Additional allowed img-src domains */\r\n cspImgSrc?: string[];\r\n /** X-Frame-Options value (default: 'DENY') */\r\n frameOptions?: \"DENY\" | \"SAMEORIGIN\";\r\n /** Enable HSTS in production (default: true) */\r\n hsts?: boolean;\r\n /** HSTS max-age in seconds (default: 31536000 = 1 year) */\r\n hstsMaxAge?: number;\r\n /** Whether this is a production build (default: auto-detect from NODE_ENV) */\r\n isProduction?: boolean;\r\n}\r\n\r\nexport interface NextHeaderEntry {\r\n source: string;\r\n headers: Array<{ key: string; value: string }>;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// PRESETS\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\nexport const SecurityHeaderPresets = {\r\n /** Minimal: basic headers only, no CSP */\r\n minimal: {\r\n csp: false,\r\n hsts: false,\r\n } satisfies SecurityHeadersConfig,\r\n\r\n /** Standard: full CSP + HSTS for most apps */\r\n standard: {\r\n csp: true,\r\n hsts: true,\r\n frameOptions: \"DENY\",\r\n } satisfies SecurityHeadersConfig,\r\n\r\n /** Strict: deny all permissions, strict CSP, no frame embedding */\r\n strict: {\r\n csp: true,\r\n hsts: true,\r\n hstsMaxAge: 63072000, // 2 years\r\n frameOptions: \"DENY\",\r\n } satisfies SecurityHeadersConfig,\r\n} as const;\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// MAIN FUNCTION\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * Generate security headers array compatible with Next.js `headers()` config.\r\n *\r\n * Usage in next.config.mjs:\r\n * ```js\r\n * const { generateSecurityHeaders } = require('@digilogiclabs/platform-core');\r\n *\r\n * module.exports = {\r\n * async headers() {\r\n * return generateSecurityHeaders({\r\n * isProduction: process.env.NODE_ENV === 'production',\r\n * cspScriptSrc: ['https://js.stripe.com'],\r\n * cspConnectSrc: ['https://api.stripe.com'],\r\n * });\r\n * },\r\n * };\r\n * ```\r\n */\r\nexport function generateSecurityHeaders(\r\n config: SecurityHeadersConfig = {},\r\n): NextHeaderEntry[] {\r\n const isProduction =\r\n config.isProduction ?? process.env.NODE_ENV === \"production\";\r\n const frameOptions = config.frameOptions ?? \"DENY\";\r\n const enableCsp = config.csp ?? true;\r\n const enableHsts = config.hsts ?? true;\r\n const hstsMaxAge = config.hstsMaxAge ?? 31536000;\r\n\r\n // Base headers applied to all routes in all environments\r\n const baseHeaders: Array<{ key: string; value: string }> = [\r\n { key: \"X-Frame-Options\", value: frameOptions },\r\n { key: \"X-Content-Type-Options\", value: \"nosniff\" },\r\n // Modern browsers use CSP, not XSS-Protection. Value '0' disables the\r\n // legacy filter which can itself introduce vulnerabilities.\r\n { key: \"X-XSS-Protection\", value: \"0\" },\r\n {\r\n key: \"Referrer-Policy\",\r\n value: \"strict-origin-when-cross-origin\",\r\n },\r\n {\r\n key: \"Permissions-Policy\",\r\n value: \"camera=(), microphone=(), geolocation=()\",\r\n },\r\n ];\r\n\r\n const entries: NextHeaderEntry[] = [\r\n { source: \"/:path*\", headers: baseHeaders },\r\n ];\r\n\r\n // Production-only headers\r\n if (isProduction) {\r\n const prodHeaders: Array<{ key: string; value: string }> = [];\r\n\r\n // HSTS\r\n if (enableHsts) {\r\n prodHeaders.push({\r\n key: \"Strict-Transport-Security\",\r\n value: `max-age=${hstsMaxAge}; includeSubDomains`,\r\n });\r\n }\r\n\r\n // Content-Security-Policy\r\n if (enableCsp) {\r\n const csp = buildCsp(config);\r\n prodHeaders.push({ key: \"Content-Security-Policy\", value: csp });\r\n }\r\n\r\n if (prodHeaders.length > 0) {\r\n entries.push({ source: \"/:path*\", headers: prodHeaders });\r\n }\r\n }\r\n\r\n return entries;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// CSP BUILDER\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\nfunction buildCsp(config: SecurityHeadersConfig): string {\r\n const scriptSrc = [\r\n \"'self'\",\r\n \"'unsafe-inline'\",\r\n \"'unsafe-eval'\",\r\n ...(config.cspScriptSrc ?? []),\r\n ];\r\n\r\n const styleSrc = [\r\n \"'self'\",\r\n \"'unsafe-inline'\",\r\n \"https://fonts.googleapis.com\",\r\n ...(config.cspStyleSrc ?? []),\r\n ];\r\n\r\n const imgSrc = [\r\n \"'self'\",\r\n \"data:\",\r\n \"https:\",\r\n \"blob:\",\r\n ...(config.cspImgSrc ?? []),\r\n ];\r\n\r\n const fontSrc = [\"'self'\", \"data:\", \"https://fonts.gstatic.com\"];\r\n\r\n const connectSrc = [\"'self'\", ...(config.cspConnectSrc ?? [])];\r\n\r\n const frameSrc = [...(config.cspFrameSrc ?? [])];\r\n\r\n const directives = [\r\n `default-src 'self'`,\r\n `script-src ${scriptSrc.join(\" \")}`,\r\n `style-src ${styleSrc.join(\" \")}`,\r\n `img-src ${imgSrc.join(\" \")}`,\r\n `font-src ${fontSrc.join(\" \")}`,\r\n `connect-src ${connectSrc.join(\" \")}`,\r\n ];\r\n\r\n if (frameSrc.length > 0) {\r\n directives.push(`frame-src ${frameSrc.join(\" \")}`);\r\n }\r\n\r\n directives.push(\r\n `object-src 'none'`,\r\n `base-uri 'self'`,\r\n `form-action 'self'`,\r\n `frame-ancestors 'none'`,\r\n );\r\n\r\n return directives.join(\"; \");\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CO,IAAM,wBAAwB;AAAA;AAAA,EAEnC,SAAS;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA;AAAA,EAGA,UAAU;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA;AAAA,IACZ,cAAc;AAAA,EAChB;AACF;AAwBO,SAAS,wBACd,SAAgC,CAAC,GACd;AACnB,QAAM,eACJ,OAAO,gBAAgB,QAAQ,IAAI,aAAa;AAClD,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,YAAY,OAAO,OAAO;AAChC,QAAM,aAAa,OAAO,QAAQ;AAClC,QAAM,aAAa,OAAO,cAAc;AAGxC,QAAM,cAAqD;AAAA,IACzD,EAAE,KAAK,mBAAmB,OAAO,aAAa;AAAA,IAC9C,EAAE,KAAK,0BAA0B,OAAO,UAAU;AAAA;AAAA;AAAA,IAGlD,EAAE,KAAK,oBAAoB,OAAO,IAAI;AAAA,IACtC;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,UAA6B;AAAA,IACjC,EAAE,QAAQ,WAAW,SAAS,YAAY;AAAA,EAC5C;AAGA,MAAI,cAAc;AAChB,UAAM,cAAqD,CAAC;AAG5D,QAAI,YAAY;AACd,kBAAY,KAAK;AAAA,QACf,KAAK;AAAA,QACL,OAAO,WAAW,UAAU;AAAA,MAC9B,CAAC;AAAA,IACH;AAGA,QAAI,WAAW;AACb,YAAM,MAAM,SAAS,MAAM;AAC3B,kBAAY,KAAK,EAAE,KAAK,2BAA2B,OAAO,IAAI,CAAC;AAAA,IACjE;AAEA,QAAI,YAAY,SAAS,GAAG;AAC1B,cAAQ,KAAK,EAAE,QAAQ,WAAW,SAAS,YAAY,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,SAAS,QAAuC;AACvD,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,gBAAgB,CAAC;AAAA,EAC9B;AAEA,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,eAAe,CAAC;AAAA,EAC7B;AAEA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,aAAa,CAAC;AAAA,EAC3B;AAEA,QAAM,UAAU,CAAC,UAAU,SAAS,2BAA2B;AAE/D,QAAM,aAAa,CAAC,UAAU,GAAI,OAAO,iBAAiB,CAAC,CAAE;AAE7D,QAAM,WAAW,CAAC,GAAI,OAAO,eAAe,CAAC,CAAE;AAE/C,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,cAAc,UAAU,KAAK,GAAG,CAAC;AAAA,IACjC,aAAa,SAAS,KAAK,GAAG,CAAC;AAAA,IAC/B,WAAW,OAAO,KAAK,GAAG,CAAC;AAAA,IAC3B,YAAY,QAAQ,KAAK,GAAG,CAAC;AAAA,IAC7B,eAAe,WAAW,KAAK,GAAG,CAAC;AAAA,EACrC;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,eAAW,KAAK,aAAa,SAAS,KAAK,GAAG,CAAC,EAAE;AAAA,EACnD;AAEA,aAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,WAAW,KAAK,IAAI;AAC7B;","names":[]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// src/security-headers.ts
|
|
2
|
+
var SecurityHeaderPresets = {
|
|
3
|
+
/** Minimal: basic headers only, no CSP */
|
|
4
|
+
minimal: {
|
|
5
|
+
csp: false,
|
|
6
|
+
hsts: false
|
|
7
|
+
},
|
|
8
|
+
/** Standard: full CSP + HSTS for most apps */
|
|
9
|
+
standard: {
|
|
10
|
+
csp: true,
|
|
11
|
+
hsts: true,
|
|
12
|
+
frameOptions: "DENY"
|
|
13
|
+
},
|
|
14
|
+
/** Strict: deny all permissions, strict CSP, no frame embedding */
|
|
15
|
+
strict: {
|
|
16
|
+
csp: true,
|
|
17
|
+
hsts: true,
|
|
18
|
+
hstsMaxAge: 63072e3,
|
|
19
|
+
// 2 years
|
|
20
|
+
frameOptions: "DENY"
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function generateSecurityHeaders(config = {}) {
|
|
24
|
+
const isProduction = config.isProduction ?? process.env.NODE_ENV === "production";
|
|
25
|
+
const frameOptions = config.frameOptions ?? "DENY";
|
|
26
|
+
const enableCsp = config.csp ?? true;
|
|
27
|
+
const enableHsts = config.hsts ?? true;
|
|
28
|
+
const hstsMaxAge = config.hstsMaxAge ?? 31536e3;
|
|
29
|
+
const baseHeaders = [
|
|
30
|
+
{ key: "X-Frame-Options", value: frameOptions },
|
|
31
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
32
|
+
// Modern browsers use CSP, not XSS-Protection. Value '0' disables the
|
|
33
|
+
// legacy filter which can itself introduce vulnerabilities.
|
|
34
|
+
{ key: "X-XSS-Protection", value: "0" },
|
|
35
|
+
{
|
|
36
|
+
key: "Referrer-Policy",
|
|
37
|
+
value: "strict-origin-when-cross-origin"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: "Permissions-Policy",
|
|
41
|
+
value: "camera=(), microphone=(), geolocation=()"
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
const entries = [
|
|
45
|
+
{ source: "/:path*", headers: baseHeaders }
|
|
46
|
+
];
|
|
47
|
+
if (isProduction) {
|
|
48
|
+
const prodHeaders = [];
|
|
49
|
+
if (enableHsts) {
|
|
50
|
+
prodHeaders.push({
|
|
51
|
+
key: "Strict-Transport-Security",
|
|
52
|
+
value: `max-age=${hstsMaxAge}; includeSubDomains`
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (enableCsp) {
|
|
56
|
+
const csp = buildCsp(config);
|
|
57
|
+
prodHeaders.push({ key: "Content-Security-Policy", value: csp });
|
|
58
|
+
}
|
|
59
|
+
if (prodHeaders.length > 0) {
|
|
60
|
+
entries.push({ source: "/:path*", headers: prodHeaders });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return entries;
|
|
64
|
+
}
|
|
65
|
+
function buildCsp(config) {
|
|
66
|
+
const scriptSrc = [
|
|
67
|
+
"'self'",
|
|
68
|
+
"'unsafe-inline'",
|
|
69
|
+
"'unsafe-eval'",
|
|
70
|
+
...config.cspScriptSrc ?? []
|
|
71
|
+
];
|
|
72
|
+
const styleSrc = [
|
|
73
|
+
"'self'",
|
|
74
|
+
"'unsafe-inline'",
|
|
75
|
+
"https://fonts.googleapis.com",
|
|
76
|
+
...config.cspStyleSrc ?? []
|
|
77
|
+
];
|
|
78
|
+
const imgSrc = [
|
|
79
|
+
"'self'",
|
|
80
|
+
"data:",
|
|
81
|
+
"https:",
|
|
82
|
+
"blob:",
|
|
83
|
+
...config.cspImgSrc ?? []
|
|
84
|
+
];
|
|
85
|
+
const fontSrc = ["'self'", "data:", "https://fonts.gstatic.com"];
|
|
86
|
+
const connectSrc = ["'self'", ...config.cspConnectSrc ?? []];
|
|
87
|
+
const frameSrc = [...config.cspFrameSrc ?? []];
|
|
88
|
+
const directives = [
|
|
89
|
+
`default-src 'self'`,
|
|
90
|
+
`script-src ${scriptSrc.join(" ")}`,
|
|
91
|
+
`style-src ${styleSrc.join(" ")}`,
|
|
92
|
+
`img-src ${imgSrc.join(" ")}`,
|
|
93
|
+
`font-src ${fontSrc.join(" ")}`,
|
|
94
|
+
`connect-src ${connectSrc.join(" ")}`
|
|
95
|
+
];
|
|
96
|
+
if (frameSrc.length > 0) {
|
|
97
|
+
directives.push(`frame-src ${frameSrc.join(" ")}`);
|
|
98
|
+
}
|
|
99
|
+
directives.push(
|
|
100
|
+
`object-src 'none'`,
|
|
101
|
+
`base-uri 'self'`,
|
|
102
|
+
`form-action 'self'`,
|
|
103
|
+
`frame-ancestors 'none'`
|
|
104
|
+
);
|
|
105
|
+
return directives.join("; ");
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
SecurityHeaderPresets,
|
|
109
|
+
generateSecurityHeaders
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=security-headers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security-headers.ts"],"sourcesContent":["/**\r\n * Shared Security Headers Utility\r\n * Generates consistent security headers for all Next.js apps.\r\n * Zero heavy dependencies — pure utility function.\r\n */\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// TYPES\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\nexport interface SecurityHeadersConfig {\r\n /** Enable Content-Security-Policy (default: true) */\r\n csp?: boolean;\r\n /** Additional allowed script-src domains */\r\n cspScriptSrc?: string[];\r\n /** Additional allowed connect-src domains */\r\n cspConnectSrc?: string[];\r\n /** Additional allowed frame-src domains */\r\n cspFrameSrc?: string[];\r\n /** Additional allowed style-src domains */\r\n cspStyleSrc?: string[];\r\n /** Additional allowed img-src domains */\r\n cspImgSrc?: string[];\r\n /** X-Frame-Options value (default: 'DENY') */\r\n frameOptions?: \"DENY\" | \"SAMEORIGIN\";\r\n /** Enable HSTS in production (default: true) */\r\n hsts?: boolean;\r\n /** HSTS max-age in seconds (default: 31536000 = 1 year) */\r\n hstsMaxAge?: number;\r\n /** Whether this is a production build (default: auto-detect from NODE_ENV) */\r\n isProduction?: boolean;\r\n}\r\n\r\nexport interface NextHeaderEntry {\r\n source: string;\r\n headers: Array<{ key: string; value: string }>;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// PRESETS\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\nexport const SecurityHeaderPresets = {\r\n /** Minimal: basic headers only, no CSP */\r\n minimal: {\r\n csp: false,\r\n hsts: false,\r\n } satisfies SecurityHeadersConfig,\r\n\r\n /** Standard: full CSP + HSTS for most apps */\r\n standard: {\r\n csp: true,\r\n hsts: true,\r\n frameOptions: \"DENY\",\r\n } satisfies SecurityHeadersConfig,\r\n\r\n /** Strict: deny all permissions, strict CSP, no frame embedding */\r\n strict: {\r\n csp: true,\r\n hsts: true,\r\n hstsMaxAge: 63072000, // 2 years\r\n frameOptions: \"DENY\",\r\n } satisfies SecurityHeadersConfig,\r\n} as const;\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// MAIN FUNCTION\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * Generate security headers array compatible with Next.js `headers()` config.\r\n *\r\n * Usage in next.config.mjs:\r\n * ```js\r\n * const { generateSecurityHeaders } = require('@digilogiclabs/platform-core');\r\n *\r\n * module.exports = {\r\n * async headers() {\r\n * return generateSecurityHeaders({\r\n * isProduction: process.env.NODE_ENV === 'production',\r\n * cspScriptSrc: ['https://js.stripe.com'],\r\n * cspConnectSrc: ['https://api.stripe.com'],\r\n * });\r\n * },\r\n * };\r\n * ```\r\n */\r\nexport function generateSecurityHeaders(\r\n config: SecurityHeadersConfig = {},\r\n): NextHeaderEntry[] {\r\n const isProduction =\r\n config.isProduction ?? process.env.NODE_ENV === \"production\";\r\n const frameOptions = config.frameOptions ?? \"DENY\";\r\n const enableCsp = config.csp ?? true;\r\n const enableHsts = config.hsts ?? true;\r\n const hstsMaxAge = config.hstsMaxAge ?? 31536000;\r\n\r\n // Base headers applied to all routes in all environments\r\n const baseHeaders: Array<{ key: string; value: string }> = [\r\n { key: \"X-Frame-Options\", value: frameOptions },\r\n { key: \"X-Content-Type-Options\", value: \"nosniff\" },\r\n // Modern browsers use CSP, not XSS-Protection. Value '0' disables the\r\n // legacy filter which can itself introduce vulnerabilities.\r\n { key: \"X-XSS-Protection\", value: \"0\" },\r\n {\r\n key: \"Referrer-Policy\",\r\n value: \"strict-origin-when-cross-origin\",\r\n },\r\n {\r\n key: \"Permissions-Policy\",\r\n value: \"camera=(), microphone=(), geolocation=()\",\r\n },\r\n ];\r\n\r\n const entries: NextHeaderEntry[] = [\r\n { source: \"/:path*\", headers: baseHeaders },\r\n ];\r\n\r\n // Production-only headers\r\n if (isProduction) {\r\n const prodHeaders: Array<{ key: string; value: string }> = [];\r\n\r\n // HSTS\r\n if (enableHsts) {\r\n prodHeaders.push({\r\n key: \"Strict-Transport-Security\",\r\n value: `max-age=${hstsMaxAge}; includeSubDomains`,\r\n });\r\n }\r\n\r\n // Content-Security-Policy\r\n if (enableCsp) {\r\n const csp = buildCsp(config);\r\n prodHeaders.push({ key: \"Content-Security-Policy\", value: csp });\r\n }\r\n\r\n if (prodHeaders.length > 0) {\r\n entries.push({ source: \"/:path*\", headers: prodHeaders });\r\n }\r\n }\r\n\r\n return entries;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════\r\n// CSP BUILDER\r\n// ═══════════════════════════════════════════════════════════════\r\n\r\nfunction buildCsp(config: SecurityHeadersConfig): string {\r\n const scriptSrc = [\r\n \"'self'\",\r\n \"'unsafe-inline'\",\r\n \"'unsafe-eval'\",\r\n ...(config.cspScriptSrc ?? []),\r\n ];\r\n\r\n const styleSrc = [\r\n \"'self'\",\r\n \"'unsafe-inline'\",\r\n \"https://fonts.googleapis.com\",\r\n ...(config.cspStyleSrc ?? []),\r\n ];\r\n\r\n const imgSrc = [\r\n \"'self'\",\r\n \"data:\",\r\n \"https:\",\r\n \"blob:\",\r\n ...(config.cspImgSrc ?? []),\r\n ];\r\n\r\n const fontSrc = [\"'self'\", \"data:\", \"https://fonts.gstatic.com\"];\r\n\r\n const connectSrc = [\"'self'\", ...(config.cspConnectSrc ?? [])];\r\n\r\n const frameSrc = [...(config.cspFrameSrc ?? [])];\r\n\r\n const directives = [\r\n `default-src 'self'`,\r\n `script-src ${scriptSrc.join(\" \")}`,\r\n `style-src ${styleSrc.join(\" \")}`,\r\n `img-src ${imgSrc.join(\" \")}`,\r\n `font-src ${fontSrc.join(\" \")}`,\r\n `connect-src ${connectSrc.join(\" \")}`,\r\n ];\r\n\r\n if (frameSrc.length > 0) {\r\n directives.push(`frame-src ${frameSrc.join(\" \")}`);\r\n }\r\n\r\n directives.push(\r\n `object-src 'none'`,\r\n `base-uri 'self'`,\r\n `form-action 'self'`,\r\n `frame-ancestors 'none'`,\r\n );\r\n\r\n return directives.join(\"; \");\r\n}\r\n"],"mappings":";AA0CO,IAAM,wBAAwB;AAAA;AAAA,EAEnC,SAAS;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA;AAAA,EAGA,UAAU;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,IACN,cAAc;AAAA,EAChB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA;AAAA,IACZ,cAAc;AAAA,EAChB;AACF;AAwBO,SAAS,wBACd,SAAgC,CAAC,GACd;AACnB,QAAM,eACJ,OAAO,gBAAgB,QAAQ,IAAI,aAAa;AAClD,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,YAAY,OAAO,OAAO;AAChC,QAAM,aAAa,OAAO,QAAQ;AAClC,QAAM,aAAa,OAAO,cAAc;AAGxC,QAAM,cAAqD;AAAA,IACzD,EAAE,KAAK,mBAAmB,OAAO,aAAa;AAAA,IAC9C,EAAE,KAAK,0BAA0B,OAAO,UAAU;AAAA;AAAA;AAAA,IAGlD,EAAE,KAAK,oBAAoB,OAAO,IAAI;AAAA,IACtC;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,UAA6B;AAAA,IACjC,EAAE,QAAQ,WAAW,SAAS,YAAY;AAAA,EAC5C;AAGA,MAAI,cAAc;AAChB,UAAM,cAAqD,CAAC;AAG5D,QAAI,YAAY;AACd,kBAAY,KAAK;AAAA,QACf,KAAK;AAAA,QACL,OAAO,WAAW,UAAU;AAAA,MAC9B,CAAC;AAAA,IACH;AAGA,QAAI,WAAW;AACb,YAAM,MAAM,SAAS,MAAM;AAC3B,kBAAY,KAAK,EAAE,KAAK,2BAA2B,OAAO,IAAI,CAAC;AAAA,IACjE;AAEA,QAAI,YAAY,SAAS,GAAG;AAC1B,cAAQ,KAAK,EAAE,QAAQ,WAAW,SAAS,YAAY,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,SAAS,QAAuC;AACvD,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,gBAAgB,CAAC;AAAA,EAC9B;AAEA,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,eAAe,CAAC;AAAA,EAC7B;AAEA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,aAAa,CAAC;AAAA,EAC3B;AAEA,QAAM,UAAU,CAAC,UAAU,SAAS,2BAA2B;AAE/D,QAAM,aAAa,CAAC,UAAU,GAAI,OAAO,iBAAiB,CAAC,CAAE;AAE7D,QAAM,WAAW,CAAC,GAAI,OAAO,eAAe,CAAC,CAAE;AAE/C,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,cAAc,UAAU,KAAK,GAAG,CAAC;AAAA,IACjC,aAAa,SAAS,KAAK,GAAG,CAAC;AAAA,IAC/B,WAAW,OAAO,KAAK,GAAG,CAAC;AAAA,IAC3B,YAAY,QAAQ,KAAK,GAAG,CAAC;AAAA,IAC7B,eAAe,WAAW,KAAK,GAAG,CAAC;AAAA,EACrC;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,eAAW,KAAK,aAAa,SAAS,KAAK,GAAG,CAAC,EAAE;AAAA,EACnD;AAEA,aAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,WAAW,KAAK,IAAI;AAC7B;","names":[]}
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IPlatform, M as MemoryDatabase, a as MemoryCache, b as MemoryStorage, c as MemoryEmail, d as MemoryQueue, e as IDatabase } from './ConsoleEmail-
|
|
2
|
-
export { C as ConsoleEmail, h as ConsoleLogger, t as EmailMessage, E as EnvSecrets, l as ICache, n as IEmail, p as ILogger, q as IMetrics, k as IQueryBuilder, o as IQueue, r as ISecrets, m as IStorage, J as Job, s as JobOptions, i as MemoryMetrics, f as MemorySecrets, N as NoopLogger, j as NoopMetrics, Q as QueryResult, S as StorageFile, g as createPlatform } from './ConsoleEmail-
|
|
1
|
+
import { I as IPlatform, M as MemoryDatabase, a as MemoryCache, b as MemoryStorage, c as MemoryEmail, d as MemoryQueue, e as IDatabase } from './ConsoleEmail-ubSVWgTa.mjs';
|
|
2
|
+
export { C as ConsoleEmail, h as ConsoleLogger, t as EmailMessage, E as EnvSecrets, l as ICache, n as IEmail, p as ILogger, q as IMetrics, k as IQueryBuilder, o as IQueue, r as ISecrets, m as IStorage, J as Job, s as JobOptions, i as MemoryMetrics, f as MemorySecrets, N as NoopLogger, j as NoopMetrics, Q as QueryResult, S as StorageFile, g as createPlatform } from './ConsoleEmail-ubSVWgTa.mjs';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IPlatform, M as MemoryDatabase, a as MemoryCache, b as MemoryStorage, c as MemoryEmail, d as MemoryQueue, e as IDatabase } from './ConsoleEmail-
|
|
2
|
-
export { C as ConsoleEmail, h as ConsoleLogger, t as EmailMessage, E as EnvSecrets, l as ICache, n as IEmail, p as ILogger, q as IMetrics, k as IQueryBuilder, o as IQueue, r as ISecrets, m as IStorage, J as Job, s as JobOptions, i as MemoryMetrics, f as MemorySecrets, N as NoopLogger, j as NoopMetrics, Q as QueryResult, S as StorageFile, g as createPlatform } from './ConsoleEmail-
|
|
1
|
+
import { I as IPlatform, M as MemoryDatabase, a as MemoryCache, b as MemoryStorage, c as MemoryEmail, d as MemoryQueue, e as IDatabase } from './ConsoleEmail-ubSVWgTa.js';
|
|
2
|
+
export { C as ConsoleEmail, h as ConsoleLogger, t as EmailMessage, E as EnvSecrets, l as ICache, n as IEmail, p as ILogger, q as IMetrics, k as IQueryBuilder, o as IQueue, r as ISecrets, m as IStorage, J as Job, s as JobOptions, i as MemoryMetrics, f as MemorySecrets, N as NoopLogger, j as NoopMetrics, Q as QueryResult, S as StorageFile, g as createPlatform } from './ConsoleEmail-ubSVWgTa.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|