@mars-stack/core 0.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 +32 -0
- package/cursor/manifest.json +304 -0
- package/cursor/rules/mars-composition-patterns.mdc +186 -0
- package/cursor/rules/mars-data-access.mdc +26 -0
- package/cursor/rules/mars-project-structure.mdc +34 -0
- package/cursor/rules/mars-security.mdc +25 -0
- package/cursor/rules/mars-testing.mdc +24 -0
- package/cursor/rules/mars-ui-conventions.mdc +29 -0
- package/cursor/skills/mars-add-api-route/SKILL.md +120 -0
- package/cursor/skills/mars-add-audit-log/SKILL.md +373 -0
- package/cursor/skills/mars-add-blog/SKILL.md +447 -0
- package/cursor/skills/mars-add-command-palette/SKILL.md +438 -0
- package/cursor/skills/mars-add-component/SKILL.md +158 -0
- package/cursor/skills/mars-add-crud-routes/SKILL.md +221 -0
- package/cursor/skills/mars-add-e2e-test/SKILL.md +227 -0
- package/cursor/skills/mars-add-error-boundary/SKILL.md +472 -0
- package/cursor/skills/mars-add-feature/SKILL.md +174 -0
- package/cursor/skills/mars-add-middleware/SKILL.md +135 -0
- package/cursor/skills/mars-add-page/SKILL.md +153 -0
- package/cursor/skills/mars-add-prisma-model/SKILL.md +148 -0
- package/cursor/skills/mars-add-protected-resource/SKILL.md +192 -0
- package/cursor/skills/mars-add-role/SKILL.md +156 -0
- package/cursor/skills/mars-add-server-action/SKILL.md +167 -0
- package/cursor/skills/mars-add-webhook/SKILL.md +192 -0
- package/cursor/skills/mars-build-complete-feature/SKILL.md +228 -0
- package/cursor/skills/mars-build-dashboard/SKILL.md +211 -0
- package/cursor/skills/mars-build-data-table/SKILL.md +284 -0
- package/cursor/skills/mars-build-form/SKILL.md +229 -0
- package/cursor/skills/mars-build-landing-page/SKILL.md +248 -0
- package/cursor/skills/mars-capture-conversation-context/SKILL.md +119 -0
- package/cursor/skills/mars-configure-ai/SKILL.md +617 -0
- package/cursor/skills/mars-configure-analytics/SKILL.md +413 -0
- package/cursor/skills/mars-configure-dark-mode/SKILL.md +309 -0
- package/cursor/skills/mars-configure-email/SKILL.md +170 -0
- package/cursor/skills/mars-configure-email-verification/SKILL.md +333 -0
- package/cursor/skills/mars-configure-feature-flags/SKILL.md +361 -0
- package/cursor/skills/mars-configure-i18n/SKILL.md +518 -0
- package/cursor/skills/mars-configure-jobs/SKILL.md +500 -0
- package/cursor/skills/mars-configure-magic-links/SKILL.md +385 -0
- package/cursor/skills/mars-configure-multi-tenancy/SKILL.md +611 -0
- package/cursor/skills/mars-configure-notifications/SKILL.md +569 -0
- package/cursor/skills/mars-configure-oauth/SKILL.md +217 -0
- package/cursor/skills/mars-configure-onboarding/SKILL.md +483 -0
- package/cursor/skills/mars-configure-payments/SKILL.md +243 -0
- package/cursor/skills/mars-configure-realtime/SKILL.md +733 -0
- package/cursor/skills/mars-configure-search/SKILL.md +581 -0
- package/cursor/skills/mars-configure-storage/SKILL.md +273 -0
- package/cursor/skills/mars-configure-two-factor/SKILL.md +518 -0
- package/cursor/skills/mars-create-execution-plan/SKILL.md +204 -0
- package/cursor/skills/mars-create-seed/SKILL.md +191 -0
- package/cursor/skills/mars-deploy-to-vercel/SKILL.md +300 -0
- package/cursor/skills/mars-design-tokens/SKILL.md +138 -0
- package/cursor/skills/mars-setup-billing/SKILL.md +322 -0
- package/cursor/skills/mars-setup-project/SKILL.md +104 -0
- package/cursor/skills/mars-setup-teams/SKILL.md +688 -0
- package/cursor/skills/mars-test-api-route/SKILL.md +219 -0
- package/cursor/skills/mars-update-architecture-docs/SKILL.md +189 -0
- package/dist/api-error/index.d.ts +27 -0
- package/dist/api-error/index.d.ts.map +1 -0
- package/dist/api-error/index.js +2 -0
- package/dist/auth/credential-tag.d.ts +5 -0
- package/dist/auth/credential-tag.d.ts.map +1 -0
- package/dist/auth/credential-tag.js +2 -0
- package/dist/auth/crypto-utils.d.ts +43 -0
- package/dist/auth/crypto-utils.d.ts.map +1 -0
- package/dist/auth/crypto-utils.js +1 -0
- package/dist/auth/csrf.d.ts +32 -0
- package/dist/auth/csrf.d.ts.map +1 -0
- package/dist/auth/csrf.js +2 -0
- package/dist/auth/hooks/index.d.ts +4 -0
- package/dist/auth/hooks/index.d.ts.map +1 -0
- package/dist/auth/hooks/index.js +68 -0
- package/dist/auth/hooks/useCSRF.d.ts +7 -0
- package/dist/auth/hooks/useCSRF.d.ts.map +1 -0
- package/dist/auth/hooks/usePasswordStrength.d.ts +17 -0
- package/dist/auth/hooks/usePasswordStrength.d.ts.map +1 -0
- package/dist/auth/internal-api-key.d.ts +5 -0
- package/dist/auth/internal-api-key.d.ts.map +1 -0
- package/dist/auth/internal-api-key.js +30 -0
- package/dist/auth/link-utils.d.ts +13 -0
- package/dist/auth/link-utils.d.ts.map +1 -0
- package/dist/auth/link-utils.js +1 -0
- package/dist/auth/middleware.d.ts +56 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +3 -0
- package/dist/auth/password.d.ts +28 -0
- package/dist/auth/password.d.ts.map +1 -0
- package/dist/auth/password.js +1 -0
- package/dist/auth/reset-token.d.ts +3 -0
- package/dist/auth/reset-token.d.ts.map +1 -0
- package/dist/auth/reset-token.js +9 -0
- package/dist/auth/responses.d.ts +15 -0
- package/dist/auth/responses.d.ts.map +1 -0
- package/dist/auth/responses.js +2 -0
- package/dist/auth/session.d.ts +79 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +1 -0
- package/dist/auth/types.d.ts +18 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +10 -0
- package/dist/auth/validation.d.ts +146 -0
- package/dist/auth/validation.d.ts.map +1 -0
- package/dist/auth/validation.js +116 -0
- package/dist/auth/validators.d.ts +4 -0
- package/dist/auth/validators.d.ts.map +1 -0
- package/dist/auth/validators.js +27 -0
- package/dist/auth/verification.d.ts +54 -0
- package/dist/auth/verification.d.ts.map +1 -0
- package/dist/auth/verification.js +39 -0
- package/dist/chunk-4LS3QDD5.js +162 -0
- package/dist/chunk-ABBUHT5Z.js +110 -0
- package/dist/chunk-CTYAVMOF.js +15 -0
- package/dist/chunk-GVLH2GQP.js +14 -0
- package/dist/chunk-HOSMMQMA.js +109 -0
- package/dist/chunk-MXQ66RUN.js +28 -0
- package/dist/chunk-PZE3JGXO.js +149 -0
- package/dist/chunk-QAH2Y5WK.js +93 -0
- package/dist/chunk-QWMN5UJC.js +76 -0
- package/dist/chunk-ROQV54MU.js +117 -0
- package/dist/chunk-U4NZQ366.js +46 -0
- package/dist/chunk-WBJOIENS.js +22 -0
- package/dist/chunk-WO6FHJHG.js +29 -0
- package/dist/chunk-Z5BEKPJI.js +96 -0
- package/dist/chunk-ZA46T6GX.js +24 -0
- package/dist/configure-mars.d.ts +104 -0
- package/dist/configure-mars.d.ts.map +1 -0
- package/dist/database/index.d.ts +8 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +1 -0
- package/dist/email/index.d.ts +25 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +2 -0
- package/dist/email/types.d.ts +18 -0
- package/dist/email/types.d.ts.map +1 -0
- package/dist/env/index.d.ts +36 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +163 -0
- package/dist/logger/index.d.ts +80 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +1 -0
- package/dist/payments/index.d.ts +53 -0
- package/dist/payments/index.d.ts.map +1 -0
- package/dist/payments/index.js +72 -0
- package/dist/plugin/builtin/email-plugins.d.ts +10 -0
- package/dist/plugin/builtin/email-plugins.d.ts.map +1 -0
- package/dist/plugin/builtin/index.d.ts +4 -0
- package/dist/plugin/builtin/index.d.ts.map +1 -0
- package/dist/plugin/builtin/index.js +324 -0
- package/dist/plugin/builtin/payment-plugins.d.ts +4 -0
- package/dist/plugin/builtin/payment-plugins.d.ts.map +1 -0
- package/dist/plugin/builtin/storage-plugins.d.ts +5 -0
- package/dist/plugin/builtin/storage-plugins.d.ts.map +1 -0
- package/dist/plugin/index.d.ts +21 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +30 -0
- package/dist/rate-limit/index.d.ts +89 -0
- package/dist/rate-limit/index.d.ts.map +1 -0
- package/dist/rate-limit/index.js +166 -0
- package/dist/seo/faq.d.ts +37 -0
- package/dist/seo/faq.d.ts.map +1 -0
- package/dist/seo/index.d.ts +75 -0
- package/dist/seo/index.d.ts.map +1 -0
- package/dist/seo/index.js +1 -0
- package/dist/storage/index.d.ts +50 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +211 -0
- package/dist/test-utils/factories.d.ts +38 -0
- package/dist/test-utils/factories.d.ts.map +1 -0
- package/dist/test-utils/index.d.ts +6 -0
- package/dist/test-utils/index.d.ts.map +1 -0
- package/dist/test-utils/index.js +117 -0
- package/dist/test-utils/mock-auth.d.ts +25 -0
- package/dist/test-utils/mock-auth.d.ts.map +1 -0
- package/dist/test-utils/mock-prisma.d.ts +55 -0
- package/dist/test-utils/mock-prisma.d.ts.map +1 -0
- package/dist/test-utils/render.d.ts +4 -0
- package/dist/test-utils/render.d.ts.map +1 -0
- package/dist/test-utils/request-helpers.d.ts +6 -0
- package/dist/test-utils/request-helpers.d.ts.map +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/math.d.ts +2 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +7 -0
- package/dist/utils/optional-import.d.ts +14 -0
- package/dist/utils/optional-import.d.ts.map +1 -0
- package/package.json +205 -0
- package/scripts/generate-skill-adapters.ts +146 -0
- package/scripts/postinstall.mjs +146 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface SendEmailParams {
|
|
2
|
+
to: string;
|
|
3
|
+
subject: string;
|
|
4
|
+
html: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface EmailServiceError {
|
|
8
|
+
response?: {
|
|
9
|
+
body: {
|
|
10
|
+
errors: Array<{
|
|
11
|
+
message: string;
|
|
12
|
+
field: string;
|
|
13
|
+
help: string;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/email/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE;YACJ,MAAM,EAAE,KAAK,CAAC;gBACZ,OAAO,EAAE,MAAM,CAAC;gBAChB,KAAK,EAAE,MAAM,CAAC;gBACd,IAAI,EAAE,MAAM,CAAC;aACd,CAAC,CAAC;SACJ,CAAC;KACH,CAAC;CACH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
/**
|
|
3
|
+
* Determines the current deployment environment from Vercel environment variables.
|
|
4
|
+
*
|
|
5
|
+
* @returns 'production', 'staging', or 'development'
|
|
6
|
+
* @example
|
|
7
|
+
* if (getEnvironment() === 'production') enableStrictSecurity();
|
|
8
|
+
*/
|
|
9
|
+
export declare function getEnvironment(): 'production' | 'staging' | 'development';
|
|
10
|
+
interface EnvValidatorConfig {
|
|
11
|
+
features: Record<string, boolean>;
|
|
12
|
+
services: Record<string, {
|
|
13
|
+
provider: string;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates a lazy environment validator that builds a Zod schema from the app's
|
|
18
|
+
* feature flags and service configuration. Validates on first access via a Proxy
|
|
19
|
+
* and throws a descriptive error if any required variables are missing.
|
|
20
|
+
*
|
|
21
|
+
* @param config - Feature flags and service provider configuration
|
|
22
|
+
* @returns An object with a lazy `env` proxy, `validateJWTSecret`, and `getEnvironment`
|
|
23
|
+
* @example
|
|
24
|
+
* const { env, validateJWTSecret } = createEnvValidator({
|
|
25
|
+
* features: { auth: true, blog: false },
|
|
26
|
+
* services: { email: { provider: 'resend' } },
|
|
27
|
+
* });
|
|
28
|
+
* const dbUrl = env.DATABASE_URL;
|
|
29
|
+
*/
|
|
30
|
+
export declare function createEnvValidator(config: EnvValidatorConfig): {
|
|
31
|
+
env: Record<string, unknown>;
|
|
32
|
+
validateJWTSecret: () => string;
|
|
33
|
+
getEnvironment: typeof getEnvironment;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/env/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAkBrB;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,YAAY,GAAG,SAAS,GAAG,aAAa,CAIzE;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB;;6BA8G7B,MAAM;;EASrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createEnvValidator, getEnvironment } from '../chunk-Z5BEKPJI.js';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { MarsAppConfig, PrismaLike } from './types';
|
|
2
|
+
export type { SessionPayload } from './auth/session';
|
|
3
|
+
export type { SendEmailParams, EmailServiceError } from './email/types';
|
|
4
|
+
export type { SecurityEventType, SecurityEvent, } from './logger/index';
|
|
5
|
+
export { configureMars } from './configure-mars';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzD,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACxE,YAAY,EACV,iBAAiB,EACjB,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { buildCredentialTag } from './chunk-GVLH2GQP.js';
|
|
2
|
+
import { createSessionManager } from './chunk-4LS3QDD5.js';
|
|
3
|
+
import { createCSRFProtection } from './chunk-PZE3JGXO.js';
|
|
4
|
+
import { createAuthMiddleware } from './chunk-QWMN5UJC.js';
|
|
5
|
+
import './chunk-ZA46T6GX.js';
|
|
6
|
+
import { constantTimeEqual } from './chunk-MXQ66RUN.js';
|
|
7
|
+
import { createLogger } from './chunk-ROQV54MU.js';
|
|
8
|
+
import { createEmailService } from './chunk-HOSMMQMA.js';
|
|
9
|
+
import './chunk-CTYAVMOF.js';
|
|
10
|
+
import { createEnvValidator } from './chunk-Z5BEKPJI.js';
|
|
11
|
+
import { createApiErrorHandler } from './chunk-U4NZQ366.js';
|
|
12
|
+
import './chunk-QAH2Y5WK.js';
|
|
13
|
+
import { createSeoBuilders } from './chunk-ABBUHT5Z.js';
|
|
14
|
+
|
|
15
|
+
// src/configure-mars.ts
|
|
16
|
+
var DEV_ONLY_PROVIDERS = /* @__PURE__ */ new Set(["console", "local"]);
|
|
17
|
+
var SERVICE_REQUIREMENTS = [
|
|
18
|
+
{
|
|
19
|
+
feature: "emailVerification",
|
|
20
|
+
service: "email",
|
|
21
|
+
condition: (f) => f.auth !== false && f.emailVerification !== false
|
|
22
|
+
},
|
|
23
|
+
{ feature: "billing", service: "payments" },
|
|
24
|
+
{ feature: "fileUpload", service: "storage" }
|
|
25
|
+
];
|
|
26
|
+
function validateServiceProviders(appConfig) {
|
|
27
|
+
if (process.env.NODE_ENV !== "production") return;
|
|
28
|
+
if (process.env.NEXT_PHASE === "phase-production-build") return;
|
|
29
|
+
const errors = [];
|
|
30
|
+
for (const req of SERVICE_REQUIREMENTS) {
|
|
31
|
+
const featureEnabled = req.condition ? req.condition(appConfig.features) : appConfig.features[req.feature] === true;
|
|
32
|
+
if (!featureEnabled) continue;
|
|
33
|
+
const service = appConfig.services[req.service];
|
|
34
|
+
if (!service) continue;
|
|
35
|
+
if (DEV_ONLY_PROVIDERS.has(service.provider)) {
|
|
36
|
+
errors.push(
|
|
37
|
+
`[mars] "${req.service}" provider "${service.provider}" is not allowed in production (required by feature "${req.feature}"). Update app.config.ts to use a production provider and set the required env vars.`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (errors.length > 0) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Production service validation failed:
|
|
44
|
+
|
|
45
|
+
${errors.join("\n\n")}
|
|
46
|
+
`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function configureMars(options) {
|
|
51
|
+
const { appConfig, prisma, signInRoute } = options;
|
|
52
|
+
validateServiceProviders(appConfig);
|
|
53
|
+
const { logger, appLogger, authLogger, securityLogger, apiLogger, logSecurityEvent } = createLogger({ serviceName: appConfig.name });
|
|
54
|
+
const { sendEmail } = createEmailService({
|
|
55
|
+
provider: appConfig.services.email.provider,
|
|
56
|
+
appName: appConfig.name
|
|
57
|
+
});
|
|
58
|
+
const { env, validateJWTSecret, getEnvironment } = createEnvValidator({
|
|
59
|
+
features: appConfig.features,
|
|
60
|
+
services: appConfig.services
|
|
61
|
+
});
|
|
62
|
+
const sessionManager = createSessionManager({
|
|
63
|
+
getJWTSecret: () => validateJWTSecret(),
|
|
64
|
+
signInRoute,
|
|
65
|
+
validateCredential: async (userId, credentialTag) => {
|
|
66
|
+
const user = await prisma.user.findUnique({
|
|
67
|
+
where: { id: userId },
|
|
68
|
+
select: { password: true }
|
|
69
|
+
});
|
|
70
|
+
if (!user) return false;
|
|
71
|
+
const currentTag = await buildCredentialTag(user.password);
|
|
72
|
+
return constantTimeEqual(credentialTag, currentTag);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const csrf = createCSRFProtection({
|
|
76
|
+
getJWTSecret: () => validateJWTSecret(),
|
|
77
|
+
logViolation: logSecurityEvent.csrfViolation
|
|
78
|
+
});
|
|
79
|
+
const authMiddleware = createAuthMiddleware({
|
|
80
|
+
verifySession: sessionManager.verifySessionForAPI,
|
|
81
|
+
findUserRole: async (userId) => {
|
|
82
|
+
const user = await prisma.user.findUnique({
|
|
83
|
+
where: { id: userId },
|
|
84
|
+
select: { role: true }
|
|
85
|
+
});
|
|
86
|
+
return user?.role ?? null;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const { handleApiError } = createApiErrorHandler({ logger: apiLogger });
|
|
90
|
+
const seo = createSeoBuilders({
|
|
91
|
+
name: appConfig.name,
|
|
92
|
+
url: appConfig.url,
|
|
93
|
+
description: appConfig.description,
|
|
94
|
+
supportEmail: appConfig.support.email
|
|
95
|
+
});
|
|
96
|
+
function getBaseUrl(request) {
|
|
97
|
+
if (request && process.env.NODE_ENV === "development") {
|
|
98
|
+
const url = new URL(request.url);
|
|
99
|
+
const host2 = url.hostname.toLowerCase();
|
|
100
|
+
const isLocal = host2 === "localhost" || host2 === "127.0.0.1" || host2 === "[::1]" || host2.endsWith(".localhost");
|
|
101
|
+
if (isLocal) {
|
|
102
|
+
return `${url.protocol}//${url.host}`;
|
|
103
|
+
}
|
|
104
|
+
const appUrl = env.APP_URL;
|
|
105
|
+
if (appUrl) {
|
|
106
|
+
try {
|
|
107
|
+
const appHost = new URL(appUrl).hostname.toLowerCase();
|
|
108
|
+
if (host2 === appHost) return `${url.protocol}//${url.host}`;
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (process.env.NODE_ENV === "production" && env.APP_URL) {
|
|
114
|
+
return env.APP_URL;
|
|
115
|
+
}
|
|
116
|
+
if (process.env.VERCEL_URL) {
|
|
117
|
+
return `https://${process.env.VERCEL_URL}`;
|
|
118
|
+
}
|
|
119
|
+
if (env.APP_URL) {
|
|
120
|
+
return env.APP_URL;
|
|
121
|
+
}
|
|
122
|
+
const host = process.env.HOST || "localhost:3000";
|
|
123
|
+
const protocol = host.includes("localhost") ? "http" : "https";
|
|
124
|
+
return `${protocol}://${host}`;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
logger,
|
|
128
|
+
appLogger,
|
|
129
|
+
authLogger,
|
|
130
|
+
securityLogger,
|
|
131
|
+
apiLogger,
|
|
132
|
+
logSecurityEvent,
|
|
133
|
+
sendEmail,
|
|
134
|
+
env,
|
|
135
|
+
validateJWTSecret,
|
|
136
|
+
getEnvironment,
|
|
137
|
+
createSession: sessionManager.createSession,
|
|
138
|
+
getSession: sessionManager.getSession,
|
|
139
|
+
updateSession: sessionManager.updateSession,
|
|
140
|
+
deleteSession: sessionManager.deleteSession,
|
|
141
|
+
verifySession: sessionManager.verifySession,
|
|
142
|
+
verifySessionForAPI: sessionManager.verifySessionForAPI,
|
|
143
|
+
getCurrentUser: sessionManager.getCurrentUser,
|
|
144
|
+
generateCSRFToken: csrf.generateCSRFToken,
|
|
145
|
+
verifyCSRFToken: csrf.verifyCSRFToken,
|
|
146
|
+
requireCSRFToken: csrf.requireCSRFToken,
|
|
147
|
+
validateCSRFRequest: csrf.validateCSRFRequest,
|
|
148
|
+
withAuth: authMiddleware.withAuth,
|
|
149
|
+
withAuthNoParams: authMiddleware.withAuthNoParams,
|
|
150
|
+
withAuthSimple: authMiddleware.withAuthSimple,
|
|
151
|
+
withRole: authMiddleware.withRole,
|
|
152
|
+
withOwnership: authMiddleware.withOwnership,
|
|
153
|
+
handleApiError,
|
|
154
|
+
buildOrganizationJsonLd: seo.buildOrganizationJsonLd,
|
|
155
|
+
buildWebSiteJsonLd: seo.buildWebSiteJsonLd,
|
|
156
|
+
buildSiteNavigationJsonLd: seo.buildSiteNavigationJsonLd,
|
|
157
|
+
buildBreadcrumbListJsonLd: seo.buildBreadcrumbListJsonLd,
|
|
158
|
+
buildArticleJsonLd: seo.buildArticleJsonLd,
|
|
159
|
+
getBaseUrl
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export { configureMars };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
export declare enum SecurityEventType {
|
|
3
|
+
LOGIN_SUCCESS = "login_success",
|
|
4
|
+
LOGIN_FAILURE = "login_failure",
|
|
5
|
+
LOGOUT = "logout",
|
|
6
|
+
SESSION_EXPIRED = "session_expired",
|
|
7
|
+
ACCOUNT_CREATED = "account_created",
|
|
8
|
+
ACCOUNT_LOCKED = "account_locked",
|
|
9
|
+
ACCOUNT_UNLOCKED = "account_unlocked",
|
|
10
|
+
EMAIL_VERIFIED = "email_verified",
|
|
11
|
+
PASSWORD_CHANGED = "password_changed",
|
|
12
|
+
PASSWORD_RESET_REQUESTED = "password_reset_requested",
|
|
13
|
+
PASSWORD_RESET_COMPLETED = "password_reset_completed",
|
|
14
|
+
CSRF_VIOLATION = "csrf_violation",
|
|
15
|
+
RATE_LIMIT_EXCEEDED = "rate_limit_exceeded",
|
|
16
|
+
SUSPICIOUS_LOGIN = "suspicious_login",
|
|
17
|
+
MULTIPLE_FAILED_LOGINS = "multiple_failed_logins",
|
|
18
|
+
SESSION_HIJACK_ATTEMPT = "session_hijack_attempt",
|
|
19
|
+
ADMIN_LOGIN = "admin_login",
|
|
20
|
+
ADMIN_ACTION = "admin_action",
|
|
21
|
+
PRIVILEGE_ESCALATION_ATTEMPT = "privilege_escalation_attempt",
|
|
22
|
+
SECURITY_HEADER_VIOLATION = "security_header_violation",
|
|
23
|
+
INVALID_TOKEN = "invalid_token",
|
|
24
|
+
EXPIRED_TOKEN = "expired_token"
|
|
25
|
+
}
|
|
26
|
+
export interface SecurityEvent {
|
|
27
|
+
type: SecurityEventType;
|
|
28
|
+
userId?: string;
|
|
29
|
+
email?: string;
|
|
30
|
+
ipAddress?: string;
|
|
31
|
+
userAgent?: string;
|
|
32
|
+
details?: Record<string, unknown>;
|
|
33
|
+
sessionId?: string;
|
|
34
|
+
requestId?: string;
|
|
35
|
+
}
|
|
36
|
+
interface LoggerConfig {
|
|
37
|
+
serviceName: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function createLogger(config: LoggerConfig): {
|
|
40
|
+
logger: pino.Logger<never, boolean>;
|
|
41
|
+
appLogger: pino.Logger<never, boolean>;
|
|
42
|
+
authLogger: pino.Logger<never, boolean>;
|
|
43
|
+
securityLogger: pino.Logger<never, boolean>;
|
|
44
|
+
apiLogger: pino.Logger<never, boolean>;
|
|
45
|
+
logSecurityEvent: {
|
|
46
|
+
loginSuccess: (event: Omit<SecurityEvent, "type">) => void;
|
|
47
|
+
loginFailure: (event: Omit<SecurityEvent, "type"> & {
|
|
48
|
+
reason: string;
|
|
49
|
+
}) => void;
|
|
50
|
+
logout: (event: Omit<SecurityEvent, "type">) => void;
|
|
51
|
+
accountCreated: (event: Omit<SecurityEvent, "type">) => void;
|
|
52
|
+
accountLocked: (event: Omit<SecurityEvent, "type"> & {
|
|
53
|
+
failedAttempts: number;
|
|
54
|
+
}) => void;
|
|
55
|
+
emailVerified: (event: Omit<SecurityEvent, "type">) => void;
|
|
56
|
+
passwordChanged: (event: Omit<SecurityEvent, "type"> & {
|
|
57
|
+
method: "reset" | "change";
|
|
58
|
+
}) => void;
|
|
59
|
+
csrfViolation: (event: Omit<SecurityEvent, "type"> & {
|
|
60
|
+
endpoint?: string;
|
|
61
|
+
}) => void;
|
|
62
|
+
rateLimitExceeded: (event: Omit<SecurityEvent, "type"> & {
|
|
63
|
+
identifier: string;
|
|
64
|
+
limitType: string;
|
|
65
|
+
}) => void;
|
|
66
|
+
suspiciousLogin: (event: Omit<SecurityEvent, "type"> & {
|
|
67
|
+
reason: string;
|
|
68
|
+
}) => void;
|
|
69
|
+
adminLogin: (event: Omit<SecurityEvent, "type">) => void;
|
|
70
|
+
adminAction: (event: Omit<SecurityEvent, "type"> & {
|
|
71
|
+
action: string;
|
|
72
|
+
targetUserId?: string;
|
|
73
|
+
}) => void;
|
|
74
|
+
invalidToken: (event: Omit<SecurityEvent, "type"> & {
|
|
75
|
+
tokenType: string;
|
|
76
|
+
}) => void;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,oBAAY,iBAAiB;IAC3B,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,MAAM,WAAW;IACjB,eAAe,oBAAoB;IAEnC,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;IACjC,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;IACjC,gBAAgB,qBAAqB;IACrC,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IAErD,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,gBAAgB,qBAAqB;IACrC,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IAEjD,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,4BAA4B,iCAAiC;IAE7D,yBAAyB,8BAA8B;IACvD,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY;;;;;;;8BAiBvB,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;8BAI3B,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE;wBAItD,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;gCAInB,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;+BAI5B,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,cAAc,EAAE,MAAM,CAAA;SAAE;+BAOxD,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;iCAIzB,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAA;SAAE;+BAO9D,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE;mCAQjE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE;iCAQvD,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE;4BAOrD,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;6BAO1B,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,CAAC,EAAE,MAAM,CAAA;SAAE;8BAOtE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE;;EAgB5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SecurityEventType, createLogger } from '../chunk-ROQV54MU.js';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface CheckoutParams {
|
|
2
|
+
customerId: string;
|
|
3
|
+
priceId: string;
|
|
4
|
+
successUrl: string;
|
|
5
|
+
cancelUrl: string;
|
|
6
|
+
metadata?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export interface PortalParams {
|
|
9
|
+
customerId: string;
|
|
10
|
+
returnUrl: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PaymentProvider {
|
|
13
|
+
createCheckoutSession(params: CheckoutParams): Promise<{
|
|
14
|
+
url: string;
|
|
15
|
+
}>;
|
|
16
|
+
createPortalSession(params: PortalParams): Promise<{
|
|
17
|
+
url: string;
|
|
18
|
+
}>;
|
|
19
|
+
constructWebhookEvent(body: string, signature: string): Promise<unknown>;
|
|
20
|
+
}
|
|
21
|
+
export interface PaymentServiceConfig {
|
|
22
|
+
provider: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a payment service backed by the configured provider (Stripe or noop).
|
|
26
|
+
* The noop provider throws on all operations, guiding developers to configure a real provider.
|
|
27
|
+
*
|
|
28
|
+
* @param config - Configuration with provider name ('stripe' or 'none')
|
|
29
|
+
* @returns An object with createCheckoutSession, createPortalSession, and constructWebhookEvent methods
|
|
30
|
+
* @example
|
|
31
|
+
* const payments = createPaymentService({ provider: 'stripe' });
|
|
32
|
+
* const { url } = await payments.createCheckoutSession({ customerId, priceId, successUrl, cancelUrl });
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Creates a payment service backed by the configured provider (Stripe or noop).
|
|
36
|
+
* Unknown providers fall back to a noop implementation that throws on use.
|
|
37
|
+
*
|
|
38
|
+
* @param config - Configuration with the provider name (e.g. 'stripe' or 'none')
|
|
39
|
+
* @returns An object with checkout, portal, and webhook methods
|
|
40
|
+
* @example
|
|
41
|
+
* const payments = createPaymentService({ provider: 'stripe' });
|
|
42
|
+
* const { url } = await payments.createCheckoutSession({ customerId, priceId, successUrl, cancelUrl });
|
|
43
|
+
*/
|
|
44
|
+
export declare function createPaymentService(config: PaymentServiceConfig): {
|
|
45
|
+
createCheckoutSession: (params: CheckoutParams) => Promise<{
|
|
46
|
+
url: string;
|
|
47
|
+
}>;
|
|
48
|
+
createPortalSession: (params: PortalParams) => Promise<{
|
|
49
|
+
url: string;
|
|
50
|
+
}>;
|
|
51
|
+
constructWebhookEvent: (body: string, signature: string) => Promise<unknown>;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/payments/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+ED;;;;;;;;;GASG;AACH;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB;oCA1GjC,cAAc,KAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;kCAC3C,YAAY,KAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;kCACvC,MAAM,aAAa,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;EAiHzE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { importOptional } from '../chunk-CTYAVMOF.js';
|
|
2
|
+
|
|
3
|
+
// src/payments/index.ts
|
|
4
|
+
function createStripeProvider() {
|
|
5
|
+
return {
|
|
6
|
+
async createCheckoutSession(params) {
|
|
7
|
+
const Stripe = (await importOptional("stripe")).default;
|
|
8
|
+
const secretKey = process.env.STRIPE_SECRET_KEY;
|
|
9
|
+
if (!secretKey) throw new Error("STRIPE_SECRET_KEY is not set");
|
|
10
|
+
const stripe = new Stripe(secretKey);
|
|
11
|
+
const session = await stripe.checkout.sessions.create({
|
|
12
|
+
customer: params.customerId,
|
|
13
|
+
mode: "subscription",
|
|
14
|
+
line_items: [{ price: params.priceId, quantity: 1 }],
|
|
15
|
+
success_url: params.successUrl,
|
|
16
|
+
cancel_url: params.cancelUrl,
|
|
17
|
+
metadata: params.metadata
|
|
18
|
+
});
|
|
19
|
+
if (!session.url) {
|
|
20
|
+
throw new Error("Stripe checkout session created without a URL");
|
|
21
|
+
}
|
|
22
|
+
return { url: session.url };
|
|
23
|
+
},
|
|
24
|
+
async createPortalSession(params) {
|
|
25
|
+
const Stripe = (await importOptional("stripe")).default;
|
|
26
|
+
const secretKey = process.env.STRIPE_SECRET_KEY;
|
|
27
|
+
if (!secretKey) throw new Error("STRIPE_SECRET_KEY is not set");
|
|
28
|
+
const stripe = new Stripe(secretKey);
|
|
29
|
+
const session = await stripe.billingPortal.sessions.create({
|
|
30
|
+
customer: params.customerId,
|
|
31
|
+
return_url: params.returnUrl
|
|
32
|
+
});
|
|
33
|
+
return { url: session.url };
|
|
34
|
+
},
|
|
35
|
+
async constructWebhookEvent(body, signature) {
|
|
36
|
+
const Stripe = (await importOptional("stripe")).default;
|
|
37
|
+
const secretKey = process.env.STRIPE_SECRET_KEY;
|
|
38
|
+
if (!secretKey) throw new Error("STRIPE_SECRET_KEY is not set");
|
|
39
|
+
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
|
|
40
|
+
if (!webhookSecret) throw new Error("STRIPE_WEBHOOK_SECRET is not set");
|
|
41
|
+
const stripe = new Stripe(secretKey);
|
|
42
|
+
return stripe.webhooks.constructEvent(body, signature, webhookSecret);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function createNoopProvider() {
|
|
47
|
+
const notConfigured = () => {
|
|
48
|
+
throw new Error(
|
|
49
|
+
"Payment provider is not configured. Set services.payments.provider in app.config.ts."
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
createCheckoutSession: notConfigured,
|
|
54
|
+
createPortalSession: notConfigured,
|
|
55
|
+
constructWebhookEvent: notConfigured
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
var providerFactories = {
|
|
59
|
+
stripe: createStripeProvider,
|
|
60
|
+
none: createNoopProvider
|
|
61
|
+
};
|
|
62
|
+
function createPaymentService(config) {
|
|
63
|
+
const factory = providerFactories[config.provider] ?? providerFactories.none;
|
|
64
|
+
const provider = factory();
|
|
65
|
+
return {
|
|
66
|
+
createCheckoutSession: provider.createCheckoutSession.bind(provider),
|
|
67
|
+
createPortalSession: provider.createPortalSession.bind(provider),
|
|
68
|
+
constructWebhookEvent: provider.constructWebhookEvent.bind(provider)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { createPaymentService };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MarsPlugin } from '../index';
|
|
2
|
+
import type { EmailProvider } from '../../email/index';
|
|
3
|
+
interface EmailPluginConfig {
|
|
4
|
+
appName: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createSendGridPlugin(): MarsPlugin<EmailPluginConfig> & EmailProvider;
|
|
7
|
+
export declare function createResendPlugin(): MarsPlugin<EmailPluginConfig> & EmailProvider;
|
|
8
|
+
export declare function createConsoleEmailPlugin(): MarsPlugin<EmailPluginConfig> & EmailProvider;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=email-plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-plugins.d.ts","sourceRoot":"","sources":["../../../src/plugin/builtin/email-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,UAAU,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,oBAAoB,IAAI,UAAU,CAAC,iBAAiB,CAAC,GAAG,aAAa,CA0DpF;AAED,wBAAgB,kBAAkB,IAAI,UAAU,CAAC,iBAAiB,CAAC,GAAG,aAAa,CAiDlF;AAED,wBAAgB,wBAAwB,IAAI,UAAU,CAAC,iBAAiB,CAAC,GAAG,aAAa,CAiBxF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createSendGridPlugin, createResendPlugin, createConsoleEmailPlugin } from './email-plugins';
|
|
2
|
+
export { createStripePlugin } from './payment-plugins';
|
|
3
|
+
export { createVercelBlobPlugin, createS3Plugin } from './storage-plugins';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugin/builtin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
|