graphile-bucket-provisioner-plugin 1.14.1 → 1.15.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 +28 -137
- package/esm/index.d.ts +3 -29
- package/esm/index.js +2 -28
- package/esm/plugin.d.ts +6 -12
- package/esm/plugin.js +129 -150
- package/esm/preset.d.ts +2 -30
- package/esm/preset.js +3 -30
- package/esm/types.d.ts +9 -57
- package/index.d.ts +3 -29
- package/index.js +2 -28
- package/package.json +3 -3
- package/plugin.d.ts +6 -12
- package/plugin.js +129 -150
- package/preset.d.ts +2 -30
- package/preset.js +3 -30
- package/types.d.ts +9 -57
package/README.md
CHANGED
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
# graphile-bucket-provisioner-plugin
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
</p>
|
|
3
|
+
PostGraphile v5 plugin that exposes a `provisionBucket` mutation for manually
|
|
4
|
+
queueing storage reconciliation.
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<a href="https://github.com/constructive-io/constructive/blob/main/LICENSE"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/></a>
|
|
12
|
-
<a href="https://www.npmjs.com/package/graphile-bucket-provisioner-plugin"><img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/constructive?filename=graphile%2Fgraphile-bucket-provisioner-plugin%2Fpackage.json"/></a>
|
|
13
|
-
</p>
|
|
14
|
-
|
|
15
|
-
PostGraphile v5 plugin that explicitly provisions S3-compatible buckets through a GraphQL mutation using [`@constructive-io/bucket-provisioner`](../packages/bucket-provisioner).
|
|
16
|
-
|
|
17
|
-
## Features
|
|
18
|
-
|
|
19
|
-
- **Explicit `provisionBucket` mutation** — GraphQL mutation for manual/retry provisioning of any bucket
|
|
20
|
-
- **3-tier CORS resolution** — Bucket-level `allowed_origins` → storage module-level `allowed_origins` → plugin config `allowedOrigins`
|
|
21
|
-
- **Wildcard CORS** — Set `allowed_origins = ['*']` on a bucket for fully open CDN/public deployments
|
|
22
|
-
- **Per-database overrides** — Reads `endpoint`, `provider`, `public_url_prefix`, and `allowed_origins` from the `storage_module` table for multi-tenant setups
|
|
23
|
-
- **Lazy S3 config** — Connection config can be a function (evaluated once, cached) to avoid eager env-var reads at import time
|
|
24
|
-
- **Deployment-controlled naming** — Requires a `resolveBucketName` policy for tenant-aware physical bucket names
|
|
6
|
+
The constructive-db `storage:provision_bucket` job is the only component that
|
|
7
|
+
mints physical S3 bucket names, provisions S3, and records `physical_name`.
|
|
8
|
+
This plugin resolves the logical bucket under RLS and enqueues that job; it
|
|
9
|
+
does not call S3 or derive a physical name.
|
|
25
10
|
|
|
26
11
|
## Installation
|
|
27
12
|
|
|
@@ -29,140 +14,46 @@ PostGraphile v5 plugin that explicitly provisions S3-compatible buckets through
|
|
|
29
14
|
pnpm add graphile-bucket-provisioner-plugin
|
|
30
15
|
```
|
|
31
16
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { createBucketProvisionerPlugin } from 'graphile-bucket-provisioner-plugin';
|
|
36
|
-
|
|
37
|
-
const BucketProvisionerPlugin = createBucketProvisionerPlugin({
|
|
38
|
-
connection: {
|
|
39
|
-
provider: 'minio',
|
|
40
|
-
region: 'us-east-1',
|
|
41
|
-
endpoint: 'http://minio:9000',
|
|
42
|
-
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
|
|
43
|
-
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
|
|
44
|
-
},
|
|
45
|
-
allowedOrigins: ['https://app.example.com'],
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Add to your PostGraphile preset
|
|
49
|
-
const preset: GraphileConfig.Preset = {
|
|
50
|
-
plugins: [BucketProvisionerPlugin],
|
|
51
|
-
};
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Or use the convenience preset:
|
|
17
|
+
## Usage
|
|
55
18
|
|
|
56
19
|
```typescript
|
|
57
20
|
import { BucketProvisionerPreset } from 'graphile-bucket-provisioner-plugin';
|
|
58
21
|
|
|
59
|
-
const preset
|
|
60
|
-
extends: [
|
|
61
|
-
BucketProvisionerPreset({
|
|
62
|
-
connection: () => ({
|
|
63
|
-
provider: 'minio',
|
|
64
|
-
region: 'us-east-1',
|
|
65
|
-
endpoint: process.env.S3_ENDPOINT!,
|
|
66
|
-
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
|
|
67
|
-
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
|
|
68
|
-
}),
|
|
69
|
-
allowedOrigins: ['https://app.example.com'],
|
|
70
|
-
}),
|
|
71
|
-
],
|
|
22
|
+
const preset = {
|
|
23
|
+
extends: [BucketProvisionerPreset()],
|
|
72
24
|
};
|
|
73
25
|
```
|
|
74
26
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
### Auto-Provisioning (default)
|
|
78
|
-
|
|
79
|
-
When a `createBucket` mutation runs on a table tagged with `@storageBuckets`:
|
|
80
|
-
|
|
81
|
-
1. The original resolver runs first (creates the DB row via RLS)
|
|
82
|
-
2. The plugin reads the bucket's `key` and `type` from the mutation input
|
|
83
|
-
3. It reads the `storage_module` config for per-database endpoint/provider overrides
|
|
84
|
-
4. It calls `BucketProvisioner.provision()` to create and configure the S3 bucket
|
|
85
|
-
5. If provisioning fails, the error is logged but the mutation result is returned normally
|
|
86
|
-
|
|
87
|
-
### Explicit Mutation
|
|
88
|
-
|
|
89
|
-
The plugin also adds a `provisionBucket` mutation for manual provisioning or retrying failed provisions:
|
|
27
|
+
The mutation accepts a logical bucket key and optionally an owner entity ID:
|
|
90
28
|
|
|
91
29
|
```graphql
|
|
92
30
|
mutation {
|
|
93
31
|
provisionBucket(input: { bucketKey: "public" }) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
endpoint
|
|
99
|
-
error
|
|
32
|
+
bucketId
|
|
33
|
+
bucketKey
|
|
34
|
+
physicalName
|
|
35
|
+
jobId
|
|
100
36
|
}
|
|
101
37
|
}
|
|
102
38
|
```
|
|
103
39
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
## API
|
|
111
|
-
|
|
112
|
-
### `createBucketProvisionerPlugin(options)`
|
|
113
|
-
|
|
114
|
-
Creates the plugin instance. Returns a `GraphileConfig.Plugin`.
|
|
115
|
-
|
|
116
|
-
| Option | Type | Description |
|
|
117
|
-
|--------|------|-------------|
|
|
118
|
-
| `connection` | `StorageConnectionConfig \| () => StorageConnectionConfig` | S3 connection config (static or lazy getter) |
|
|
119
|
-
| `allowedOrigins` | `string[]` | CORS allowed origins for bucket configuration |
|
|
120
|
-
| `resolveBucketName` | `(databaseId, bucketKey) => string` | Deployment policy for deriving a tenant-aware physical bucket name |
|
|
121
|
-
| `versioning` | `boolean?` | Enable S3 versioning on provisioned buckets (default: `false`) |
|
|
122
|
-
|
|
123
|
-
### `BucketProvisionerPreset(options)`
|
|
124
|
-
|
|
125
|
-
Convenience function that wraps the plugin in a `GraphileConfig.Preset`.
|
|
126
|
-
|
|
127
|
-
### Connection Config
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
interface StorageConnectionConfig {
|
|
131
|
-
provider: 's3' | 'minio' | 'r2' | 'gcs' | 'spaces';
|
|
132
|
-
region: string;
|
|
133
|
-
endpoint?: string;
|
|
134
|
-
accessKeyId: string;
|
|
135
|
-
secretAccessKey: string;
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Smart Tag Detection
|
|
140
|
-
|
|
141
|
-
The plugin detects tables tagged with `@storageBuckets` (set by the storage module generator in constructive-db):
|
|
142
|
-
|
|
143
|
-
```sql
|
|
144
|
-
COMMENT ON TABLE app_public.buckets IS E'@storageBuckets\nStorage buckets table';
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
The plugin wraps `create*` mutations for auto-provisioning and `update*` mutations for CORS change detection. Delete mutations are not wrapped.
|
|
148
|
-
|
|
149
|
-
## Error Handling
|
|
150
|
-
|
|
151
|
-
The plugin is designed to never break mutations:
|
|
152
|
-
|
|
153
|
-
- **Auto-provisioning errors** are caught and logged. The mutation result is returned normally. The admin can retry via the `provisionBucket` mutation.
|
|
154
|
-
- **Explicit `provisionBucket` errors** return a structured payload with `success: false` and an `error` message.
|
|
155
|
-
- **Validation errors** (`INVALID_BUCKET_KEY`, `DATABASE_NOT_FOUND`, `STORAGE_MODULE_NOT_PROVISIONED`, `BUCKET_NOT_FOUND`) are thrown as exceptions since they indicate configuration issues.
|
|
156
|
-
|
|
157
|
-
## Multi-Tenant Support
|
|
40
|
+
`provisionBucket` resolves the bucket row under RLS and enqueues the same
|
|
41
|
+
`storage:provision_bucket` job used by the database INSERT trigger. Database
|
|
42
|
+
scope jobs include `database_id`, use the `bucket:<uuid>` queue, and have
|
|
43
|
+
25 attempts. Platform scope jobs use the platform trigger payload. Enqueue
|
|
44
|
+
failures are returned as GraphQL errors.
|
|
158
45
|
|
|
159
|
-
The
|
|
46
|
+
The payload fields are:
|
|
160
47
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
48
|
+
| Field | Description |
|
|
49
|
+
|-------|-------------|
|
|
50
|
+
| `bucketId` | Logical bucket row ID |
|
|
51
|
+
| `bucketKey` | Logical bucket key |
|
|
52
|
+
| `physicalName` | Recorded physical name, or `null` while reconciliation is pending |
|
|
53
|
+
| `jobId` | ID of the queued reconciler job |
|
|
164
54
|
|
|
165
|
-
|
|
55
|
+
There are no plugin options: S3 connection details, naming, CORS, versioning,
|
|
56
|
+
and physical-name recording belong to the reconciler.
|
|
166
57
|
|
|
167
58
|
---
|
|
168
59
|
|
package/esm/index.d.ts
CHANGED
|
@@ -1,35 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bucket Provisioner Plugin for PostGraphile v5
|
|
3
3
|
*
|
|
4
|
-
* Provides an explicit `provisionBucket` mutation for
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { BucketProvisionerPreset } from 'graphile-bucket-provisioner-plugin';
|
|
9
|
-
* import { getEnvOptions } from '@constructive-io/graphql-env';
|
|
10
|
-
*
|
|
11
|
-
* // Use a lazy getter so env vars are read at runtime, not import time
|
|
12
|
-
* function getConnection() {
|
|
13
|
-
* const { cdn } = getEnvOptions();
|
|
14
|
-
* return {
|
|
15
|
-
* provider: cdn?.provider || 'minio',
|
|
16
|
-
* region: cdn?.awsRegion || 'us-east-1',
|
|
17
|
-
* endpoint: cdn?.endpoint || 'http://minio:9000',
|
|
18
|
-
* accessKeyId: cdn?.awsAccessKey!,
|
|
19
|
-
* secretAccessKey: cdn?.awsSecretKey!,
|
|
20
|
-
* };
|
|
21
|
-
* }
|
|
22
|
-
*
|
|
23
|
-
* const preset = {
|
|
24
|
-
* extends: [
|
|
25
|
-
* BucketProvisionerPreset({
|
|
26
|
-
* connection: getConnection, // pass function ref, NOT getConnection()
|
|
27
|
-
* allowedOrigins: ['https://app.example.com'],
|
|
28
|
-
* }),
|
|
29
|
-
* ],
|
|
30
|
-
* };
|
|
31
|
-
* ```
|
|
4
|
+
* Provides an explicit `provisionBucket` reconciliation enqueue mutation for
|
|
5
|
+
* PostGraphile v5.
|
|
32
6
|
*/
|
|
33
7
|
export { BucketProvisionerPlugin, createBucketProvisionerPlugin } from './plugin';
|
|
34
8
|
export { BucketProvisionerPreset } from './preset';
|
|
35
|
-
export type {
|
|
9
|
+
export type { ProvisionBucketInput, ProvisionBucketPayload, } from './types';
|
package/esm/index.js
CHANGED
|
@@ -1,34 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bucket Provisioner Plugin for PostGraphile v5
|
|
3
3
|
*
|
|
4
|
-
* Provides an explicit `provisionBucket` mutation for
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { BucketProvisionerPreset } from 'graphile-bucket-provisioner-plugin';
|
|
9
|
-
* import { getEnvOptions } from '@constructive-io/graphql-env';
|
|
10
|
-
*
|
|
11
|
-
* // Use a lazy getter so env vars are read at runtime, not import time
|
|
12
|
-
* function getConnection() {
|
|
13
|
-
* const { cdn } = getEnvOptions();
|
|
14
|
-
* return {
|
|
15
|
-
* provider: cdn?.provider || 'minio',
|
|
16
|
-
* region: cdn?.awsRegion || 'us-east-1',
|
|
17
|
-
* endpoint: cdn?.endpoint || 'http://minio:9000',
|
|
18
|
-
* accessKeyId: cdn?.awsAccessKey!,
|
|
19
|
-
* secretAccessKey: cdn?.awsSecretKey!,
|
|
20
|
-
* };
|
|
21
|
-
* }
|
|
22
|
-
*
|
|
23
|
-
* const preset = {
|
|
24
|
-
* extends: [
|
|
25
|
-
* BucketProvisionerPreset({
|
|
26
|
-
* connection: getConnection, // pass function ref, NOT getConnection()
|
|
27
|
-
* allowedOrigins: ['https://app.example.com'],
|
|
28
|
-
* }),
|
|
29
|
-
* ],
|
|
30
|
-
* };
|
|
31
|
-
* ```
|
|
4
|
+
* Provides an explicit `provisionBucket` reconciliation enqueue mutation for
|
|
5
|
+
* PostGraphile v5.
|
|
32
6
|
*/
|
|
33
7
|
export { BucketProvisionerPlugin, createBucketProvisionerPlugin } from './plugin';
|
|
34
8
|
export { BucketProvisionerPreset } from './preset';
|
package/esm/plugin.d.ts
CHANGED
|
@@ -3,13 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Adds S3 bucket provisioning support to PostGraphile v5:
|
|
5
5
|
*
|
|
6
|
-
* 1. `provisionBucket` mutation — explicitly
|
|
6
|
+
* 1. `provisionBucket` mutation — explicitly enqueue reconciliation for a
|
|
7
7
|
* logical bucket row in the database. Reads the bucket config via RLS,
|
|
8
|
-
* then
|
|
9
|
-
*
|
|
10
|
-
* This plugin uses `@constructive-io/bucket-provisioner` for the actual
|
|
11
|
-
* S3 operations (bucket creation, Block Public Access, CORS, policies,
|
|
12
|
-
* versioning, lifecycle rules).
|
|
8
|
+
* then queues the same storage reconciler job used by the INSERT trigger.
|
|
13
9
|
*
|
|
14
10
|
* Detection: Uses the `@storageBuckets` smart tag on the codec (table).
|
|
15
11
|
* The storage module generator in constructive-db sets this tag on the
|
|
@@ -17,18 +13,16 @@
|
|
|
17
13
|
* COMMENT ON TABLE buckets IS E'@storageBuckets\nStorage buckets table';
|
|
18
14
|
*/
|
|
19
15
|
import type { GraphileConfig } from 'graphile-config';
|
|
20
|
-
import type { BucketProvisionerPluginOptions } from './types';
|
|
21
16
|
/**
|
|
22
17
|
* Creates the bucket provisioner plugin.
|
|
23
18
|
*
|
|
24
|
-
* This plugin provides one
|
|
19
|
+
* This plugin provides one reconciliation pathway:
|
|
25
20
|
*
|
|
26
21
|
* 1. **Explicit `provisionBucket` mutation** — Call this mutation with a
|
|
27
|
-
* bucket key to
|
|
28
|
-
* by RLS on the buckets table.
|
|
22
|
+
* bucket key to enqueue reconciliation (or re-reconciliation) for the
|
|
23
|
+
* bucket. Protected by RLS on the buckets table.
|
|
29
24
|
*
|
|
30
|
-
* @param options - Plugin configuration (S3 credentials, CORS origins, naming)
|
|
31
25
|
*/
|
|
32
|
-
export declare function createBucketProvisionerPlugin(
|
|
26
|
+
export declare function createBucketProvisionerPlugin(): GraphileConfig.Plugin;
|
|
33
27
|
export declare const BucketProvisionerPlugin: typeof createBucketProvisionerPlugin;
|
|
34
28
|
export default BucketProvisionerPlugin;
|