@fjall/payload 0.89.5 → 0.94.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/LICENSE CHANGED
@@ -1,21 +1,50 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Fjall
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ Fjall Proprietary Software Licence
2
+
3
+ Copyright (c) 2026 Fjall. All rights reserved.
4
+
5
+ This software, including all source, object, bundled, and minified forms
6
+ ("the Software"), is the proprietary and confidential property of Fjall.
7
+
8
+ 1. Permitted Use. Subject to the terms of this Licence, Fjall grants you
9
+ a non-exclusive, non-transferable, revocable licence to install the
10
+ Software via the npm registry and to execute it solely for the purpose
11
+ of deploying, operating, and managing your own applications and
12
+ infrastructure on cloud providers.
13
+
14
+ 2. Restrictions. You may NOT, and may not permit any third party to:
15
+ (a) copy, redistribute, sublicense, sell, rent, lease, or otherwise
16
+ transfer the Software;
17
+ (b) modify, adapt, translate, or create derivative works of the Software;
18
+ (c) reverse engineer, decompile, disassemble, deminify, or otherwise
19
+ attempt to derive the source code, structure, or organisation of
20
+ the Software, except to the minimum extent expressly permitted by
21
+ applicable mandatory law;
22
+ (d) use the Software, or any portion of it, to develop, train, or
23
+ improve any product or service that competes with Fjall;
24
+ (e) remove, alter, or obscure any proprietary notices contained in
25
+ the Software;
26
+ (f) publish, share, or otherwise disclose the Software or its contents
27
+ to any third party.
28
+
29
+ 3. Ownership. All right, title, and interest in and to the Software,
30
+ including all intellectual property rights, remain with Fjall. No
31
+ rights are granted except as expressly set out in this Licence.
32
+
33
+ 4. Termination. This Licence terminates automatically if you breach any
34
+ of its terms. Upon termination you must cease all use of the Software
35
+ and destroy all copies in your possession.
36
+
37
+ 5. Disclaimer of Warranty. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT
38
+ WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
39
+ THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
40
+ AND NON-INFRINGEMENT.
41
+
42
+ 6. Limitation of Liability. IN NO EVENT SHALL FJALL BE LIABLE FOR ANY
43
+ INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES
44
+ ARISING OUT OF OR RELATED TO THE SOFTWARE, EVEN IF ADVISED OF THE
45
+ POSSIBILITY OF SUCH DAMAGES.
46
+
47
+ 7. Governing Law. This Licence is governed by the laws of England and
48
+ Wales, without regard to conflict of laws principles.
49
+
50
+ For commercial licensing enquiries, contact: contact@fjall.io
package/README.md CHANGED
@@ -130,6 +130,6 @@ When you run `fjall deploy` on a Payload project, the CLI automatically:
130
130
 
131
131
  No manual configuration required - just run `fjall deploy`.
132
132
 
133
- ## License
133
+ ## Licence
134
134
 
135
- MIT
135
+ Proprietary — see [LICENSE](./LICENSE).
package/dist/.minified ADDED
@@ -0,0 +1 @@
1
+ 6 files minified at 2026-04-21T02:12:03.431Z
@@ -28,4 +28,3 @@ export interface FjallPostgresAdapterOptions {
28
28
  */
29
29
  export declare function fjallPostgresAdapter(options?: FjallPostgresAdapterOptions): Promise<PostgresAdapterResult>;
30
30
  export {};
31
- //# sourceMappingURL=postgres.d.ts.map
@@ -1,79 +1 @@
1
- /**
2
- * Fjall PostgreSQL adapter for Payload CMS.
3
- *
4
- * Wraps @payloadcms/db-postgres with AWS-specific features:
5
- * - Fetches database credentials from AWS Secrets Manager via Lambda Extension
6
- * - Constructs connection string from Fjall environment variables
7
- * - Handles SSL configuration for Aurora PostgreSQL
8
- * - Falls back to DATABASE_URL for local development
9
- */
10
- import { postgresAdapter } from "@payloadcms/db-postgres";
11
- import { fetchSecretField } from "./secrets.js";
12
- // Module-level cache: Lambda reuses modules across invocations,
13
- // so caching avoids repeated Secrets Manager calls.
14
- let cachedDbUrl = null;
15
- async function getDatabaseUrl() {
16
- if (cachedDbUrl !== null)
17
- return cachedDbUrl;
18
- if (process.env.DATABASE_HOST) {
19
- const host = process.env.DATABASE_HOST;
20
- const port = process.env.DATABASE_PORT || "5432";
21
- const name = process.env.DATABASE_NAME;
22
- if (!name) {
23
- throw new Error("[fjall] DATABASE_NAME environment variable not configured. " +
24
- "Ensure DATABASE_NAME is set alongside DATABASE_HOST.");
25
- }
26
- const user = await fetchSecretField("DATABASE_USERNAME");
27
- const pass = await fetchSecretField("DATABASE_PASSWORD");
28
- if (!user || !pass) {
29
- throw new Error("[fjall] Database credentials not found in Secrets Manager. " +
30
- "Ensure DATABASE_USERNAME and DATABASE_PASSWORD are configured in your secrets.");
31
- }
32
- cachedDbUrl = `postgresql://${user}:${encodeURIComponent(pass)}@${host}:${port}/${name}`;
33
- return cachedDbUrl;
34
- }
35
- // Build-time handling: when no database is configured, use a connection string
36
- // that fails fast with a clear error. An empty string causes pg.Pool to default
37
- // to localhost:5432, which hangs or gives confusing errors.
38
- //
39
- // This allows Payload to initialise, but any database query will fail immediately
40
- // with a clear DNS resolution error instead of trying to connect to localhost.
41
- //
42
- // Users should wrap generateStaticParams with isBuildTime() to skip DB calls:
43
- // if (isBuildTime()) return []
44
- cachedDbUrl =
45
- process.env.DATABASE_URL ||
46
- "postgresql://fjall-build-time-no-database:5432/none";
47
- return cachedDbUrl;
48
- }
49
- // Aurora uses Amazon's internal CA, so we skip certificate verification.
50
- function getSslConfig() {
51
- return process.env.DATABASE_SSL === "true"
52
- ? { rejectUnauthorized: false }
53
- : false;
54
- }
55
- /**
56
- * @example
57
- * ```typescript
58
- * import { fjallPostgresAdapter } from '@fjall/payload'
59
- * import { migrations } from './migrations'
60
- *
61
- * export default buildConfig({
62
- * db: await fjallPostgresAdapter({ prodMigrations: migrations }),
63
- * })
64
- * ```
65
- */
66
- export async function fjallPostgresAdapter(options = {}) {
67
- const { migrationDir = "./src/migrations", prodMigrations } = options;
68
- const databaseUrl = await getDatabaseUrl();
69
- return postgresAdapter({
70
- pool: {
71
- connectionString: databaseUrl,
72
- ssl: getSslConfig(),
73
- },
74
- migrationDir,
75
- // Safe assertion: migrations are generated by `payload migrate:create`.
76
- prodMigrations: prodMigrations,
77
- });
78
- }
79
- //# sourceMappingURL=postgres.js.map
1
+ import{postgresAdapter as a}from"@payloadcms/db-postgres";import{fetchSecretField as A}from"./secrets.js";let e=null;async function i(){if(e!==null)return e;if(process.env.DATABASE_HOST){const t=process.env.DATABASE_HOST,o=process.env.DATABASE_PORT||"5432",r=process.env.DATABASE_NAME;if(!r)throw new Error("[fjall] DATABASE_NAME environment variable not configured. Ensure DATABASE_NAME is set alongside DATABASE_HOST.");const n=await A("DATABASE_USERNAME"),s=await A("DATABASE_PASSWORD");if(!n||!s)throw new Error("[fjall] Database credentials not found in Secrets Manager. Ensure DATABASE_USERNAME and DATABASE_PASSWORD are configured in your secrets.");return e=`postgresql://${n}:${encodeURIComponent(s)}@${t}:${o}/${r}`,e}return e=process.env.DATABASE_URL||"postgresql://fjall-build-time-no-database:5432/none",e}function c(){return process.env.DATABASE_SSL==="true"?{rejectUnauthorized:!1}:!1}async function E(t={}){const{migrationDir:o="./src/migrations",prodMigrations:r}=t,n=await i();return a({pool:{connectionString:n,ssl:c()},migrationDir:o,prodMigrations:r})}export{E as fjallPostgresAdapter};
@@ -18,4 +18,3 @@
18
18
  * @returns The secret value, or undefined if not available
19
19
  */
20
20
  export declare function fetchSecretField(envKey: string): Promise<string | undefined>;
21
- //# sourceMappingURL=secrets.d.ts.map
@@ -1,55 +1 @@
1
- /**
2
- * AWS Secrets Manager helper for Lambda environments.
3
- *
4
- * Fetches secrets via the Lambda Extension which runs on port 2773.
5
- * The extension caches secrets automatically for performance.
6
- *
7
- * @see https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_lambda.html
8
- */
9
- /**
10
- * Fetch a specific field from an AWS Secret stored in Secrets Manager.
11
- *
12
- * Uses the Lambda Parameters and Secrets Extension for secure, cached access.
13
- * The extension expects:
14
- * - `${envKey}_SECRET_ARN` - The ARN of the secret in Secrets Manager
15
- * - `${envKey}_SECRET_FIELD` - (Optional) The field name within the JSON secret
16
- *
17
- * @param envKey - The environment variable prefix (e.g., 'DATABASE_USERNAME')
18
- * @returns The secret value, or undefined if not available
19
- */
20
- export async function fetchSecretField(envKey) {
21
- const secretArn = process.env[`${envKey}_SECRET_ARN`];
22
- const secretField = process.env[`${envKey}_SECRET_FIELD`];
23
- if (!secretArn)
24
- return undefined;
25
- const sessionToken = process.env.AWS_SESSION_TOKEN;
26
- if (!sessionToken) {
27
- // AWS_SESSION_TOKEN is set by Lambda runtime - if missing, we're not in Lambda
28
- console.error(`fetchSecretField: AWS_SESSION_TOKEN not set (not running in Lambda?)`);
29
- return undefined;
30
- }
31
- try {
32
- const url = `http://localhost:2773/secretsmanager/get?secretId=${encodeURIComponent(secretArn)}`;
33
- const response = await fetch(url, {
34
- headers: {
35
- "X-Aws-Parameters-Secrets-Token": sessionToken,
36
- },
37
- });
38
- if (!response.ok) {
39
- console.error(`Failed to fetch secret ${envKey}: ${response.status}`);
40
- return undefined;
41
- }
42
- const data = (await response.json());
43
- if (!data.SecretString)
44
- return undefined;
45
- if (!secretField)
46
- return data.SecretString;
47
- const parsed = JSON.parse(data.SecretString);
48
- return parsed[secretField];
49
- }
50
- catch (err) {
51
- console.error(`Error fetching secret ${envKey}:`, err);
52
- return undefined;
53
- }
54
- }
55
- //# sourceMappingURL=secrets.js.map
1
+ async function a(e){const s=process.env[`${e}_SECRET_ARN`],c=process.env[`${e}_SECRET_FIELD`];if(!s)return;const o=process.env.AWS_SESSION_TOKEN;if(!o){console.error("fetchSecretField: AWS_SESSION_TOKEN not set (not running in Lambda?)");return}try{const r=`http://localhost:2773/secretsmanager/get?secretId=${encodeURIComponent(s)}`,t=await fetch(r,{headers:{"X-Aws-Parameters-Secrets-Token":o}});if(!t.ok){console.error(`Failed to fetch secret ${e}: ${t.status}`);return}const n=await t.json();return n.SecretString?c?JSON.parse(n.SecretString)[c]:n.SecretString:void 0}catch(r){console.error(`Error fetching secret ${e}:`,r);return}}export{a as fetchSecretField};
@@ -25,4 +25,3 @@ interface Logger {
25
25
  */
26
26
  export declare function invalidateS3Cache(pagePath: string, logger?: Logger): Promise<void>;
27
27
  export {};
28
- //# sourceMappingURL=invalidate.d.ts.map
@@ -1,59 +1 @@
1
- /**
2
- * S3 ISR cache invalidation for OpenNext deployments.
3
- *
4
- * Next.js standalone mode does not expose `x-next-cache-tags` via response
5
- * headers (Vercel-only). OpenNext's DynamoDB tag cache never receives
6
- * tag-to-path mappings for ISR page routes. When Payload calls
7
- * `revalidatePath('/about')`, there's nothing to invalidate in DynamoDB,
8
- * so stale S3 cache persists indefinitely.
9
- *
10
- * This utility deletes the stale S3 cache entry directly, forcing Lambda
11
- * to re-render from the database on next request.
12
- */
13
- import { readFileSync } from "node:fs";
14
- // Module-level caches: Lambda reuses modules across invocations,
15
- // so caching avoids repeated file reads and client construction.
16
- let cachedBuildId = null;
17
- let cachedS3Client = null;
18
- function getBuildId() {
19
- if (cachedBuildId !== null)
20
- return cachedBuildId;
21
- cachedBuildId = readFileSync("/var/task/.next/BUILD_ID", "utf8").trim();
22
- return cachedBuildId;
23
- }
24
- function pageToCacheKey(buildId, pagePath) {
25
- const normalised = pagePath === "/" ? "/index" : pagePath;
26
- return `${buildId}${normalised}.cache`;
27
- }
28
- /**
29
- * Delete the stale S3 ISR cache entry for a page path.
30
- *
31
- * - No-op when `CACHE_BUCKET_NAME` or `AWS_LAMBDA_FUNCTION_NAME` is not set
32
- * - Best-effort: catches all errors, logs via optional logger, never rejects
33
- *
34
- * @param pagePath - The page path as passed to `revalidatePath()`, e.g. `/about`
35
- * @param logger - Optional logger (`payload.logger` satisfies this)
36
- */
37
- export async function invalidateS3Cache(pagePath, logger) {
38
- try {
39
- const bucket = process.env.CACHE_BUCKET_NAME;
40
- const isLambda = process.env.AWS_LAMBDA_FUNCTION_NAME;
41
- if (!bucket || !isLambda)
42
- return;
43
- const buildId = getBuildId();
44
- const key = pageToCacheKey(buildId, pagePath);
45
- if (!cachedS3Client) {
46
- const { S3Client } = await import("@aws-sdk/client-s3");
47
- cachedS3Client = new S3Client({});
48
- }
49
- const { DeleteObjectCommand } = await import("@aws-sdk/client-s3");
50
- const command = new DeleteObjectCommand({ Bucket: bucket, Key: key });
51
- await cachedS3Client.send(command);
52
- logger?.info(`[fjall] Invalidated S3 cache: ${key}`);
53
- }
54
- catch (err) {
55
- const message = err instanceof Error ? err.message : "Unknown error";
56
- logger?.warn?.(`[fjall] S3 cache invalidation failed for ${pagePath}: ${message}`);
57
- }
58
- }
59
- //# sourceMappingURL=invalidate.js.map
1
+ import{readFileSync as u}from"node:fs";let c=null,i=null;function f(){return c!==null||(c=u("/var/task/.next/BUILD_ID","utf8").trim()),c}function m(t,e){return`${t}${e==="/"?"/index":e}.cache`}async function w(t,e){try{const n=process.env.CACHE_BUCKET_NAME,a=process.env.AWS_LAMBDA_FUNCTION_NAME;if(!n||!a)return;const r=f(),o=m(r,t);if(!i){const{S3Client:d}=await import("@aws-sdk/client-s3");i=new d({})}const{DeleteObjectCommand:l}=await import("@aws-sdk/client-s3"),s=new l({Bucket:n,Key:o});await i.send(s),e?.info(`[fjall] Invalidated S3 cache: ${o}`)}catch(n){const a=n instanceof Error?n.message:"Unknown error";e?.warn?.(`[fjall] S3 cache invalidation failed for ${t}: ${a}`)}}export{w as invalidateS3Cache};
@@ -86,4 +86,3 @@ export declare function fjallDefaults(): {
86
86
  export declare function conditionalStaticDir(localPath: string): {
87
87
  staticDir: string;
88
88
  } | Record<string, never>;
89
- //# sourceMappingURL=defaults.d.ts.map
@@ -1,101 +1 @@
1
- /**
2
- * Fjall default configuration helpers for Payload CMS.
3
- *
4
- * Provides sensible defaults for AWS Lambda deployments:
5
- * - CORS configuration based on environment
6
- * - CSRF configuration for security
7
- * - Environment detection helpers
8
- */
9
- /**
10
- * Check if running during Next.js build phase.
11
- *
12
- * During build, there's no database connection available. Use this to skip
13
- * database queries in generateStaticParams and other build-time code.
14
- *
15
- * @example
16
- * ```typescript
17
- * import { isBuildTime } from '@fjall/payload'
18
- *
19
- * export async function generateStaticParams() {
20
- * if (isBuildTime()) {
21
- * return [] // Skip static generation - pages render on-demand
22
- * }
23
- * const payload = await getPayload({ config: configPromise })
24
- * // ... fetch data
25
- * }
26
- * ```
27
- */
28
- export function isBuildTime() {
29
- return process.env.NEXT_PHASE === "phase-production-build";
30
- }
31
- /**
32
- * Check if running in a production AWS environment.
33
- *
34
- * Detection is based on the presence of MEDIA_BUCKET_NAME which is set
35
- * by Fjall infrastructure in Lambda environments.
36
- */
37
- export function isProduction() {
38
- return Boolean(process.env.MEDIA_BUCKET_NAME);
39
- }
40
- /**
41
- * Check if running in AWS Lambda.
42
- *
43
- * Uses AWS_LAMBDA_FUNCTION_NAME which is set by the Lambda runtime.
44
- */
45
- export function isLambda() {
46
- return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);
47
- }
48
- /**
49
- * Fjall default configuration spread for Payload buildConfig.
50
- *
51
- * Provides:
52
- * - CORS: Locked to NEXT_PUBLIC_SERVER_URL in production, permissive otherwise
53
- * - CSRF: Enabled in production with NEXT_PUBLIC_SERVER_URL
54
- *
55
- * @example
56
- * ```typescript
57
- * import { fjallDefaults } from '@fjall/payload'
58
- *
59
- * export default buildConfig({
60
- * ...fjallDefaults(),
61
- * // your config...
62
- * })
63
- * ```
64
- */
65
- export function fjallDefaults() {
66
- const serverUrl = process.env.NEXT_PUBLIC_SERVER_URL;
67
- return {
68
- // When custom domain is set (via Lambda env), lock CORS to that domain
69
- // Otherwise permissive for CloudFront deployments
70
- cors: serverUrl ? [serverUrl] : ["*"],
71
- // CSRF protection - only enable when we have a known origin
72
- csrf: serverUrl ? [serverUrl] : [],
73
- };
74
- }
75
- /**
76
- * Get the conditional staticDir configuration for Media collections.
77
- *
78
- * In production (Lambda), S3 storage is used and staticDir should be omitted.
79
- * In local development, uploads go to the local filesystem.
80
- *
81
- * @param localPath - The local path for development (e.g., './public/media')
82
- * @returns Object with staticDir for local dev, empty object for production
83
- *
84
- * @example
85
- * ```typescript
86
- * import { conditionalStaticDir } from '@fjall/payload'
87
- * import path from 'path'
88
- *
89
- * export const Media: CollectionConfig = {
90
- * slug: 'media',
91
- * upload: {
92
- * ...conditionalStaticDir(path.resolve(__dirname, '../../public/media')),
93
- * // other upload config...
94
- * },
95
- * }
96
- * ```
97
- */
98
- export function conditionalStaticDir(localPath) {
99
- return isProduction() ? {} : { staticDir: localPath };
100
- }
101
- //# sourceMappingURL=defaults.js.map
1
+ function o(){return process.env.NEXT_PHASE==="phase-production-build"}function n(){return!!process.env.MEDIA_BUCKET_NAME}function e(){return!!process.env.AWS_LAMBDA_FUNCTION_NAME}function t(){const r=process.env.NEXT_PUBLIC_SERVER_URL;return{cors:r?[r]:["*"],csrf:r?[r]:[]}}function i(r){return n()?{}:{staticDir:r}}export{i as conditionalStaticDir,t as fjallDefaults,o as isBuildTime,e as isLambda,n as isProduction};
package/dist/index.d.ts CHANGED
@@ -35,4 +35,3 @@ export { fetchSecretField } from "./adapters/secrets.js";
35
35
  export { awsS3Storage, type AwsS3StorageOptions } from "./storage/s3.js";
36
36
  export { fjallDefaults, isProduction, isLambda, isBuildTime, conditionalStaticDir, } from "./config/defaults.js";
37
37
  export { invalidateS3Cache } from "./cache/invalidate.js";
38
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,43 +1 @@
1
- /**
2
- * @fjall/payload - Fjall AWS adapters and utilities for Payload CMS
3
- *
4
- * This package provides AWS-specific adapters and helpers for deploying
5
- * Payload CMS applications to AWS Lambda via Fjall.
6
- *
7
- * @example
8
- * ```typescript
9
- * // payload.config.ts
10
- * import {
11
- * fjallPostgresAdapter,
12
- * awsS3Storage,
13
- * fjallDefaults,
14
- * } from '@fjall/payload'
15
- * import { migrations } from './migrations'
16
- *
17
- * const db = await fjallPostgresAdapter({
18
- * migrationDir: './src/migrations',
19
- * prodMigrations: migrations,
20
- * })
21
- *
22
- * export default buildConfig({
23
- * ...fjallDefaults(),
24
- * db,
25
- * plugins: [
26
- * awsS3Storage(),
27
- * // other plugins...
28
- * ],
29
- * // your config...
30
- * })
31
- * ```
32
- */
33
- // Database adapter
34
- export { fjallPostgresAdapter, } from "./adapters/postgres.js";
35
- // AWS Secrets helper
36
- export { fetchSecretField } from "./adapters/secrets.js";
37
- // S3 storage plugin
38
- export { awsS3Storage } from "./storage/s3.js";
39
- // Configuration helpers
40
- export { fjallDefaults, isProduction, isLambda, isBuildTime, conditionalStaticDir, } from "./config/defaults.js";
41
- // S3 ISR cache invalidation
42
- export { invalidateS3Cache } from "./cache/invalidate.js";
43
- //# sourceMappingURL=index.js.map
1
+ import{fjallPostgresAdapter as r}from"./adapters/postgres.js";import{fetchSecretField as a}from"./adapters/secrets.js";import{awsS3Storage as f}from"./storage/s3.js";import{fjallDefaults as d,isProduction as m,isLambda as s,isBuildTime as c,conditionalStaticDir as p}from"./config/defaults.js";import{invalidateS3Cache as S}from"./cache/invalidate.js";export{f as awsS3Storage,p as conditionalStaticDir,a as fetchSecretField,d as fjallDefaults,r as fjallPostgresAdapter,S as invalidateS3Cache,c as isBuildTime,s as isLambda,m as isProduction};
@@ -49,4 +49,3 @@ export interface AwsS3StorageOptions {
49
49
  * ```
50
50
  */
51
51
  export declare function awsS3Storage(options?: AwsS3StorageOptions): Plugin;
52
- //# sourceMappingURL=s3.d.ts.map
@@ -1,45 +1 @@
1
- /**
2
- * Fjall S3 storage configuration for Payload CMS.
3
- *
4
- * Wraps @payloadcms/storage-s3 with AWS Lambda-specific defaults:
5
- * - Uses MEDIA_BUCKET_NAME environment variable from Fjall infrastructure
6
- * - Enables/disables local storage based on environment
7
- * - Uses AWS_REGION for automatic region configuration
8
- */
9
- import { s3Storage } from "@payloadcms/storage-s3";
10
- /**
11
- * Create an S3 storage plugin configured for Fjall/AWS Lambda.
12
- *
13
- * This plugin is always registered so Payload includes S3 client components
14
- * in the importMap at build time. In local development (when MEDIA_BUCKET_NAME
15
- * is not set), uploads fall back to disk storage.
16
- *
17
- * @example
18
- * ```typescript
19
- * import { awsS3Storage } from '@fjall/payload'
20
- *
21
- * export const plugins: Plugin[] = [
22
- * awsS3Storage(),
23
- * // other plugins...
24
- * ]
25
- * ```
26
- */
27
- export function awsS3Storage(options = {}) {
28
- const { collections = ["media"], prefix = "media", bucket = process.env.MEDIA_BUCKET_NAME, region = process.env.AWS_REGION || "us-east-1", } = options;
29
- // Build collection config - disable local storage when bucket is configured
30
- const collectionConfig = Object.fromEntries(collections.map((slug) => [
31
- slug,
32
- { prefix, disableLocalStorage: !!bucket },
33
- ]));
34
- return s3Storage({
35
- collections: collectionConfig,
36
- // Use placeholder bucket for local dev - plugin is registered but won't be used
37
- bucket: bucket || "placeholder",
38
- config: {
39
- // When running in Lambda with IAM role, credentials are automatic
40
- // For local testing with S3, set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
41
- region,
42
- },
43
- });
44
- }
45
- //# sourceMappingURL=s3.js.map
1
+ import{s3Storage as i}from"@payloadcms/storage-s3";function l(o={}){const{collections:c=["media"],prefix:t="media",bucket:e=process.env.MEDIA_BUCKET_NAME,region:r=process.env.AWS_REGION||"us-east-1"}=o,n=Object.fromEntries(c.map(s=>[s,{prefix:t,disableLocalStorage:!!e}]));return i({collections:n,bucket:e||"placeholder",config:{region:r}})}export{l as awsS3Storage};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/payload",
3
- "version": "0.89.5",
3
+ "version": "0.94.0",
4
4
  "description": "Fjall AWS adapters and utilities for Payload CMS",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -8,15 +8,15 @@
8
8
  "exports": {
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
11
+ "default": "./dist/index.js"
12
12
  }
13
13
  },
14
14
  "files": [
15
15
  "dist/"
16
16
  ],
17
17
  "scripts": {
18
- "clean": "rm -rf ./dist",
19
- "build": "npm run clean && npx tsc",
18
+ "clean": "rm -rf ./dist ./sourcemaps",
19
+ "build": "npm run clean && npx tsc && node ../scripts/minify-dist.mjs dist",
20
20
  "watch": "npm run build && npx tsc-watch",
21
21
  "typecheck": "tsc --noEmit",
22
22
  "test": "vitest run",
@@ -26,10 +26,10 @@
26
26
  "lint:fix": "eslint src/ --fix"
27
27
  },
28
28
  "engines": {
29
- "node": ">=18.0.0"
29
+ "node": ">=22.0.0"
30
30
  },
31
31
  "author": "",
32
- "license": "MIT",
32
+ "license": "SEE LICENSE IN LICENSE",
33
33
  "peerDependencies": {
34
34
  "@aws-sdk/client-s3": "^3.0.0",
35
35
  "@payloadcms/db-postgres": "^3.0.0",
@@ -56,5 +56,5 @@
56
56
  "typescript": "^5.8.2",
57
57
  "vitest": "^4.0.0"
58
58
  },
59
- "gitHead": "1680c1a0be16950e9e10e571163ccc42198f6a8e"
59
+ "gitHead": "97f6b382405bb3068e841d30866222fd76bc3b15"
60
60
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/adapters/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAyDhE,MAAM,WAAW,2BAA2B;IAC1C,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC,CAgBhC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/adapters/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIhD,gEAAgE;AAChE,oDAAoD;AACpD,IAAI,WAAW,GAAkB,IAAI,CAAC;AAEtC,KAAK,UAAU,cAAc;IAC3B,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,WAAW,CAAC;IAE7C,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC;QACjD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QAEvC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACb,6DAA6D;gBAC3D,sDAAsD,CACzD,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QAEzD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,6DAA6D;gBAC3D,gFAAgF,CACnF,CAAC;QACJ,CAAC;QAED,WAAW,GAAG,gBAAgB,IAAI,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACzF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,+EAA+E;IAC/E,gFAAgF;IAChF,4DAA4D;IAC5D,EAAE;IACF,kFAAkF;IAClF,+EAA+E;IAC/E,EAAE;IACF,8EAA8E;IAC9E,iCAAiC;IACjC,WAAW;QACT,OAAO,CAAC,GAAG,CAAC,YAAY;YACxB,qDAAqD,CAAC;IACxD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,yEAAyE;AACzE,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,MAAM;QACxC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE;QAC/B,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AASD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAuC,EAAE;IAEzC,MAAM,EAAE,YAAY,GAAG,kBAAkB,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAEtE,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAE3C,OAAO,eAAe,CAAC;QACrB,IAAI,EAAE;YACJ,gBAAgB,EAAE,WAAW;YAC7B,GAAG,EAAE,YAAY,EAAE;SACpB;QACD,YAAY;QACZ,wEAAwE;QACxE,cAAc,EAAE,cAEM;KACvB,CAAC,CAAC;AACL,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/adapters/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuC7B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/adapters/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc;IAEd,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,aAAa,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,eAAe,CAAC,CAAC;IAE1D,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACnD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,+EAA+E;QAC/E,OAAO,CAAC,KAAK,CACX,sEAAsE,CACvE,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,qDAAqD,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;QACjG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE;gBACP,gCAAgC,EAAE,YAAY;aAC/C;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,0BAA0B,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACtE,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA8B,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QAEzC,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QAE3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAA2B,CAAC;QACvE,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"invalidate.d.ts","sourceRoot":"","sources":["../../src/cache/invalidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,UAAU,MAAM;IACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAkBD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"invalidate.js","sourceRoot":"","sources":["../../src/cache/invalidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,iEAAiE;AACjE,iEAAiE;AACjE,IAAI,aAAa,GAAkB,IAAI,CAAC;AACxC,IAAI,cAAc,GAAoB,IAAI,CAAC;AAE3C,SAAS,UAAU;IACjB,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,aAAa,CAAC;IACjD,aAAa,GAAG,YAAY,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACxE,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,QAAgB;IACvD,MAAM,UAAU,GAAG,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1D,OAAO,GAAG,OAAO,GAAG,UAAU,QAAQ,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAgB,EAChB,MAAe;IAEf,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;QAEtD,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEjC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE9C,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YACxD,cAAc,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACtE,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEnC,MAAM,EAAE,IAAI,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,MAAM,EAAE,IAAI,EAAE,CACZ,4CAA4C,QAAQ,KAAK,OAAO,EAAE,CACnE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,IAAI;IAC/B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAUA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,GAChB;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAE/C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,wBAAwB,CAAC;AAC7D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa;IAI3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAErD,OAAO;QACL,uEAAuE;QACvE,kDAAkD;QAClD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACrC,4DAA4D;QAC5D,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;KACnC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAAiB;IAEjB,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACxD,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EACL,oBAAoB,EACpB,KAAK,2BAA2B,GACjC,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EACL,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,mBAAmB;AACnB,OAAO,EACL,oBAAoB,GAErB,MAAM,wBAAwB,CAAC;AAEhC,qBAAqB;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAA4B,MAAM,iBAAiB,CAAC;AAEzE,wBAAwB;AACxB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,4BAA4B;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA0BtE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA+BnD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAAC,UAA+B,EAAE;IAC5D,MAAM,EACJ,WAAW,GAAG,CAAC,OAAO,CAAC,EACvB,MAAM,GAAG,OAAO,EAChB,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,EACtC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW,GAC/C,GAAG,OAAO,CAAC;IAEZ,4EAA4E;IAC5E,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,CACzC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,IAAI;QACJ,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE;KAC1C,CAAC,CACH,CAAC;IAEF,OAAO,SAAS,CAAC;QACf,WAAW,EAAE,gBAAgB;QAC7B,gFAAgF;QAChF,MAAM,EAAE,MAAM,IAAI,aAAa;QAC/B,MAAM,EAAE;YACN,kEAAkE;YAClE,6EAA6E;YAC7E,MAAM;SACP;KACF,CAAC,CAAC;AACL,CAAC"}