Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions graphile/graphile-settings/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const getGraphileSettings = (
awsAccessKey: cdn.awsAccessKey!,
awsSecretKey: cdn.awsSecretKey!,
minioEndpoint: cdn.minioEndpoint,
provider: cdn.provider,
});

const resolveUpload = uploader.resolveUpload.bind(uploader);
Expand Down
3 changes: 1 addition & 2 deletions graphile/graphile-upload-plugin/__tests__/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ let db: PgTestClient;

// Create bucket before tests
beforeAll(async () => {
process.env.IS_MINIO = 'true'; // Ensure MinIO behavior in createS3Bucket
const result = await createS3Bucket(s3Client, BUCKET_NAME!);
const result = await createS3Bucket(s3Client, BUCKET_NAME!, { provider: 'minio' });
if (!result.success) throw new Error('Failed to create test S3 bucket');

// Initialize uploader with real S3 configuration
Expand Down
1 change: 1 addition & 0 deletions graphile/graphile-upload-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"dependencies": {
"@constructive-io/s3-streamer": "workspace:^",
"@constructive-io/upload-names": "workspace:^",
"@pgpmjs/types": "workspace:^",
"graphile-build": "^4.14.1",
"graphql": "15.10.1"
}
Expand Down
6 changes: 5 additions & 1 deletion graphile/graphile-upload-plugin/src/resolvers/upload.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import streamer from '@constructive-io/s3-streamer';
import uploadNames from '@constructive-io/upload-names';
import type { BucketProvider } from '@pgpmjs/types';

export interface UploaderOptions {
bucketName: string;
awsRegion: string;
awsSecretKey: string;
awsAccessKey: string;
minioEndpoint?: string;
provider?: BucketProvider;
}

export class Uploader {
Expand All @@ -18,7 +20,8 @@ export class Uploader {
awsRegion,
awsSecretKey,
awsAccessKey,
minioEndpoint
minioEndpoint,
provider
} = this.opts;

this.streamerInstance = new streamer({
Expand All @@ -27,6 +30,7 @@ export class Uploader {
awsSecretKey,
awsAccessKey,
minioEndpoint,
provider,
});
}

Expand Down
5 changes: 4 additions & 1 deletion graphql/explorer/src/resolvers/uploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import Streamer from '@constructive-io/s3-streamer';
import uploadNames from '@constructive-io/upload-names';
import { ReadStream } from 'fs';
import type { GraphQLResolveInfo } from 'graphql';
import type { BucketProvider } from '@pgpmjs/types';

interface UploaderOptions {
bucketName: string;
awsRegion: string;
awsSecretKey: string;
awsAccessKey: string;
minioEndpoint?: string;
provider?: BucketProvider;
}

interface Upload {
Expand All @@ -32,7 +34,8 @@ export class UploadHandler {
awsRegion: options.awsRegion,
awsSecretKey: options.awsSecretKey,
awsAccessKey: options.awsAccessKey,
minioEndpoint: options.minioEndpoint
minioEndpoint: options.minioEndpoint,
provider: options.provider
});
}

Expand Down
27 changes: 18 additions & 9 deletions graphql/server/src/scripts/create-bucket.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
// Minimal script to create a bucket in MinIO using @constructive-io/s3-utils
// Minimal script to create a bucket in MinIO/S3 using @constructive-io/s3-utils
// Avoid strict type coupling between different @aws-sdk/client-s3 versions

import { S3Client } from '@aws-sdk/client-s3';
import { createS3Bucket } from '@constructive-io/s3-utils';
import { getEnvOptions } from '@constructive-io/graphql-env';
import { Logger } from '@pgpmjs/logger';

const log = new Logger('create-bucket');

(async () => {
try {
const opts = getEnvOptions();
const { cdn } = opts;

const provider = cdn?.provider || 'minio';
const isMinio = provider === 'minio';

const bucket = cdn?.bucketName || 'test-bucket';
const region = cdn?.awsRegion || 'us-east-1';
const accessKey = cdn?.awsAccessKey || 'minioadmin';
Expand All @@ -19,19 +25,22 @@ import { getEnvOptions } from '@constructive-io/graphql-env';
const client: any = new S3Client({
region,
credentials: { accessKeyId: accessKey, secretAccessKey: secretKey },
endpoint,
forcePathStyle: true,
...(isMinio ? {
endpoint,
forcePathStyle: true,
} : {}),
});

// Hint downstream to apply MinIO policies
process.env.IS_MINIO = 'true';

const res = await createS3Bucket(client as any, bucket);
console.log(`[create-bucket] ${bucket}:`, res);
const res = await createS3Bucket(client as any, bucket, { provider });
if (res.success) {
log.success(`${bucket} (provider: ${provider})`);
} else {
log.error(`Failed to create bucket ${bucket}`);
}

client.destroy();
} catch (e) {
console.error('[create-bucket] error', e);
log.error('error', e);
process.exitCode = 1;
}
})();
1 change: 1 addition & 0 deletions pgpm/env/__tests__/__snapshots__/merge.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exports[`getEnvOptions merges defaults, config, env, and overrides 1`] = `
"awsSecretKey": "minioadmin",
"bucketName": "test-bucket",
"minioEndpoint": "http://localhost:9000",
"provider": "minio",
},
"db": {
"connections": {
Expand Down
4 changes: 3 additions & 1 deletion pgpm/env/src/env.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PgpmOptions } from '@pgpmjs/types';
import { PgpmOptions, BucketProvider } from '@pgpmjs/types';

const parseEnvNumber = (val?: string): number | undefined => {
const num = Number(val);
Expand Down Expand Up @@ -50,6 +50,7 @@ export const getEnvVars = (): PgpmOptions => {
PGPASSWORD,
PGDATABASE,

BUCKET_PROVIDER,
BUCKET_NAME,
AWS_REGION,
AWS_ACCESS_KEY,
Expand Down Expand Up @@ -121,6 +122,7 @@ export const getEnvVars = (): PgpmOptions => {
...(PGDATABASE && { database: PGDATABASE }),
},
cdn: {
...(BUCKET_PROVIDER && { provider: BUCKET_PROVIDER as BucketProvider }),
...(BUCKET_NAME && { bucketName: BUCKET_NAME }),
...(AWS_REGION && { awsRegion: AWS_REGION }),
...((AWS_ACCESS_KEY || AWS_ACCESS_KEY_ID) && { awsAccessKey: AWS_ACCESS_KEY || AWS_ACCESS_KEY_ID }),
Expand Down
10 changes: 9 additions & 1 deletion pgpm/types/src/pgpm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,17 @@ export interface ServerOptions {
strictAuth?: boolean;
}

/**
* Storage provider type for CDN/bucket operations
*/
export type BucketProvider = 's3' | 'minio' | 'gcs';

/**
* CDN and file storage configuration
*/
export interface CDNOptions {
/** Storage provider type (s3, minio, gcs). Defaults to 'minio' for local dev */
provider?: BucketProvider;
/** S3 bucket name for file storage */
bucketName?: string;
/** AWS region for S3 bucket */
Expand All @@ -118,7 +125,7 @@ export interface CDNOptions {
awsAccessKey?: string;
/** AWS secret key for S3 */
awsSecretKey?: string;
/** MinIO endpoint URL for local development */
/** MinIO endpoint URL for local development (only used when provider is 'minio') */
minioEndpoint?: string;
}

Expand Down Expand Up @@ -241,6 +248,7 @@ export const pgpmDefaults: PgpmOptions = {
strictAuth: false,
},
cdn: {
provider: 'minio',
bucketName: 'test-bucket',
awsRegion: 'us-east-1',
awsAccessKey: 'minioadmin',
Expand Down
Loading