graphile-upload-plugin 1.1.0 → 2.2.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/esm/preset.js ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * PostGraphile v5 Upload Preset
3
+ *
4
+ * Provides a convenient preset for including upload support in PostGraphile.
5
+ */
6
+ import { createUploadPlugin } from './plugin';
7
+ /**
8
+ * Creates a preset that includes the upload plugin with the given options.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { UploadPreset } from 'graphile-upload-plugin';
13
+ *
14
+ * const preset = {
15
+ * extends: [
16
+ * UploadPreset({
17
+ * uploadFieldDefinitions: [
18
+ * {
19
+ * tag: 'upload',
20
+ * resolve: async (upload, args, context, info) => {
21
+ * // Process the upload and return the value to store in the column
22
+ * const stream = upload.createReadStream();
23
+ * const url = await uploadToStorage(stream, upload.filename);
24
+ * return url;
25
+ * },
26
+ * },
27
+ * ],
28
+ * }),
29
+ * ],
30
+ * };
31
+ * ```
32
+ */
33
+ export function UploadPreset(options = {}) {
34
+ return {
35
+ plugins: [createUploadPlugin(options)]
36
+ };
37
+ }
38
+ export default UploadPreset;
package/esm/types.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ import type { Readable } from 'stream';
2
+ /**
3
+ * Represents a file upload received from the client.
4
+ */
5
+ export interface FileUpload {
6
+ filename: string;
7
+ mimetype?: string;
8
+ encoding?: string;
9
+ createReadStream: () => Readable;
10
+ }
11
+ /**
12
+ * Additional metadata passed to the upload resolver via the info parameter.
13
+ */
14
+ export interface UploadPluginInfo {
15
+ tags: Record<string, any>;
16
+ type?: string;
17
+ }
18
+ /**
19
+ * A function that processes an uploaded file and returns the value to store
20
+ * in the database column (e.g., a URL string or a JSON object).
21
+ *
22
+ * Called with the upload stream. The filename comes from user input
23
+ * and MUST be sanitized by the implementation before use in file paths
24
+ * or storage keys (e.g., strip path separators, limit length, validate characters).
25
+ */
26
+ export type UploadResolver = (upload: FileUpload, args: any, context: any, info: {
27
+ uploadPlugin: UploadPluginInfo;
28
+ }) => Promise<any>;
29
+ /**
30
+ * Defines which columns should receive upload handling.
31
+ *
32
+ * Two forms are supported:
33
+ * 1. Type-name based: match columns by their PG type name and namespace.
34
+ * 2. Smart-tag based: match columns that have a specific smart tag.
35
+ */
36
+ export type UploadFieldDefinition = {
37
+ /** PG type name (e.g., 'text') */
38
+ name: string;
39
+ /** PG schema name (e.g., 'pg_catalog') */
40
+ namespaceName: string;
41
+ /** The GraphQL type name to override to (e.g., 'Upload') */
42
+ type: string;
43
+ /** The resolver function to process the upload */
44
+ resolve: UploadResolver;
45
+ tag?: never;
46
+ } | {
47
+ /** Smart tag name to match (e.g., '@upload') */
48
+ tag: string;
49
+ /** The resolver function to process the upload */
50
+ resolve: UploadResolver;
51
+ name?: never;
52
+ namespaceName?: never;
53
+ /** Optional type hint for the resolver */
54
+ type?: string;
55
+ };
56
+ /**
57
+ * Plugin options for the upload plugin.
58
+ */
59
+ export interface UploadPluginOptions {
60
+ /**
61
+ * Array of upload field definitions that configure which columns
62
+ * should get upload handling.
63
+ */
64
+ uploadFieldDefinitions?: UploadFieldDefinition[];
65
+ /**
66
+ * Maximum file size in bytes. If set, streams exceeding this are rejected.
67
+ * Default: no limit (rely on graphql-upload middleware).
68
+ */
69
+ maxFileSize?: number;
70
+ }
package/esm/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/index.d.ts CHANGED
@@ -1,4 +1,31 @@
1
- import UploadPostGraphilePlugin, { type FileUpload, type UploadPluginInfo, type UploadResolver, type UploadFieldDefinition } from './plugin';
2
- export { UploadPostGraphilePlugin, type FileUpload, type UploadPluginInfo, type UploadResolver, type UploadFieldDefinition, };
3
- export { Uploader, type UploaderOptions } from './resolvers/upload';
4
- export default UploadPostGraphilePlugin;
1
+ /**
2
+ * PostGraphile v5 Upload Plugin
3
+ *
4
+ * Provides file upload capabilities for PostGraphile v5 mutations.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { UploadPlugin, UploadPreset } from 'graphile-upload-plugin';
9
+ *
10
+ * // Option 1: Use the preset (recommended)
11
+ * const preset = {
12
+ * extends: [
13
+ * UploadPreset({
14
+ * uploadFieldDefinitions: [
15
+ * { tag: 'upload', resolve: myUploadResolver },
16
+ * ],
17
+ * }),
18
+ * ],
19
+ * };
20
+ *
21
+ * // Option 2: Use the plugin directly
22
+ * const plugin = UploadPlugin({
23
+ * uploadFieldDefinitions: [
24
+ * { tag: 'upload', resolve: myUploadResolver },
25
+ * ],
26
+ * });
27
+ * ```
28
+ */
29
+ export { UploadPlugin, createUploadPlugin } from './plugin';
30
+ export { UploadPreset } from './preset';
31
+ export type { FileUpload, UploadFieldDefinition, UploadPluginInfo, UploadPluginOptions, UploadResolver } from './types';
package/index.js CHANGED
@@ -1,11 +1,36 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ /**
3
+ * PostGraphile v5 Upload Plugin
4
+ *
5
+ * Provides file upload capabilities for PostGraphile v5 mutations.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { UploadPlugin, UploadPreset } from 'graphile-upload-plugin';
10
+ *
11
+ * // Option 1: Use the preset (recommended)
12
+ * const preset = {
13
+ * extends: [
14
+ * UploadPreset({
15
+ * uploadFieldDefinitions: [
16
+ * { tag: 'upload', resolve: myUploadResolver },
17
+ * ],
18
+ * }),
19
+ * ],
20
+ * };
21
+ *
22
+ * // Option 2: Use the plugin directly
23
+ * const plugin = UploadPlugin({
24
+ * uploadFieldDefinitions: [
25
+ * { tag: 'upload', resolve: myUploadResolver },
26
+ * ],
27
+ * });
28
+ * ```
29
+ */
5
30
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Uploader = exports.UploadPostGraphilePlugin = void 0;
7
- const plugin_1 = __importDefault(require("./plugin"));
8
- exports.UploadPostGraphilePlugin = plugin_1.default;
9
- var upload_1 = require("./resolvers/upload");
10
- Object.defineProperty(exports, "Uploader", { enumerable: true, get: function () { return upload_1.Uploader; } });
11
- exports.default = plugin_1.default;
31
+ exports.UploadPreset = exports.createUploadPlugin = exports.UploadPlugin = void 0;
32
+ var plugin_1 = require("./plugin");
33
+ Object.defineProperty(exports, "UploadPlugin", { enumerable: true, get: function () { return plugin_1.UploadPlugin; } });
34
+ Object.defineProperty(exports, "createUploadPlugin", { enumerable: true, get: function () { return plugin_1.createUploadPlugin; } });
35
+ var preset_1 = require("./preset");
36
+ Object.defineProperty(exports, "UploadPreset", { enumerable: true, get: function () { return preset_1.UploadPreset; } });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "graphile-upload-plugin",
3
- "version": "1.1.0",
4
- "description": "Graphile upload plugin for PostGraphile",
3
+ "version": "2.2.0",
4
+ "description": "File upload support for PostGraphile v5",
5
5
  "author": "Constructive <developers@constructive.io>",
6
6
  "homepage": "https://github.com/constructive-io/constructive",
7
7
  "license": "MIT",
@@ -10,12 +10,11 @@
10
10
  "types": "index.d.ts",
11
11
  "scripts": {
12
12
  "clean": "makage clean",
13
- "prepack": "pnpm run build",
13
+ "prepack": "npm run build",
14
14
  "build": "makage build",
15
15
  "build:dev": "makage build --dev",
16
16
  "lint": "eslint . --fix",
17
- "test": "jest --passWithNoTests",
18
- "test:watch": "jest --watch"
17
+ "test": "jest"
19
18
  },
20
19
  "publishConfig": {
21
20
  "access": "public",
@@ -29,32 +28,26 @@
29
28
  "postgraphile",
30
29
  "graphile",
31
30
  "constructive",
32
- "pgpm",
33
31
  "plugin",
34
32
  "postgres",
35
33
  "graphql",
36
- "upload"
34
+ "upload",
35
+ "file-upload",
36
+ "s3"
37
37
  ],
38
38
  "bugs": {
39
39
  "url": "https://github.com/constructive-io/constructive/issues"
40
40
  },
41
- "devDependencies": {
42
- "@aws-sdk/client-s3": "^3.971.0",
43
- "@constructive-io/graphql-env": "^2.10.0",
44
- "@constructive-io/s3-utils": "^2.6.0",
45
- "@types/pg": "^8.16.0",
46
- "graphile-test": "^3.1.0",
47
- "graphql-tag": "^2.12.6",
48
- "makage": "^0.1.12",
49
- "pgsql-test": "^3.1.0",
50
- "ts-jest": "^29.4.6"
41
+ "peerDependencies": {
42
+ "graphile-build": "^5.0.0-rc.4",
43
+ "graphile-build-pg": "^5.0.0-rc.5",
44
+ "graphile-config": "^1.0.0-rc.5",
45
+ "graphql": "^16.9.0",
46
+ "postgraphile": "^5.0.0-rc.4"
51
47
  },
52
- "dependencies": {
53
- "@constructive-io/s3-streamer": "^2.11.0",
54
- "@constructive-io/upload-names": "^2.5.0",
55
- "@pgpmjs/types": "^2.16.0",
56
- "graphile-build": "^4.14.1",
57
- "graphql": "15.10.1"
48
+ "devDependencies": {
49
+ "@types/node": "^22.19.1",
50
+ "makage": "^0.1.10"
58
51
  },
59
- "gitHead": "048188f6b43ffaa6146e7694b2b0d35d34cb2945"
52
+ "gitHead": "b758178b808ce0bf451e86c0bd7e92079155db7c"
60
53
  }
package/plugin.d.ts CHANGED
@@ -1,31 +1,32 @@
1
- import type { ReadStream } from 'fs';
2
- import type { Plugin } from 'graphile-build';
3
- import type { GraphQLResolveInfo } from 'graphql';
4
- export interface FileUpload {
5
- filename: string;
6
- mimetype?: string;
7
- encoding?: string;
8
- createReadStream: () => ReadStream;
9
- }
10
- export interface UploadPluginInfo {
11
- tags: Record<string, any>;
12
- type?: string;
13
- }
14
- export type UploadResolver = (upload: FileUpload, args: any, context: any, info: GraphQLResolveInfo & {
15
- uploadPlugin: UploadPluginInfo;
16
- }) => Promise<any>;
17
- export type UploadFieldDefinition = {
18
- name: string;
19
- namespaceName: string;
20
- type: string;
21
- resolve: UploadResolver;
22
- tag?: never;
23
- } | {
24
- tag: string;
25
- resolve: UploadResolver;
26
- name?: never;
27
- namespaceName?: never;
28
- type?: string;
29
- };
30
- declare const UploadPostGraphilePlugin: Plugin;
31
- export default UploadPostGraphilePlugin;
1
+ /**
2
+ * PostGraphile v5 Upload Plugin
3
+ *
4
+ * Adds file upload support to PostGraphile v5 mutations. For columns that match
5
+ * the configured upload field definitions (by PG type name/namespace or by smart
6
+ * tag), this plugin:
7
+ *
8
+ * 1. Registers a GraphQL `Upload` scalar type
9
+ * 2. Adds `*Upload` input fields on mutation input types
10
+ * 3. Wraps mutation field resolvers to process file uploads before the mutation
11
+ * executes, calling the user-supplied resolver for each upload
12
+ *
13
+ * In v5, the `GraphQLObjectType_fields_field` hook wraps the `resolve` function
14
+ * (which still exists on mutation fields alongside `plan`) to intercept uploads
15
+ * at the HTTP layer before the plan executes.
16
+ *
17
+ * COMPATIBILITY NOTE:
18
+ * This plugin uses v4-style resolver wrapping via GraphQLObjectType_fields_field hook.
19
+ * grafserv v5 supports this through its backwards-compatibility layer.
20
+ * This plugin requires grafserv's resolver support to be enabled (default in v5 RC).
21
+ * It will NOT work in a pure grafast plan-only execution context.
22
+ */
23
+ import 'graphile-build';
24
+ import 'graphile-build-pg';
25
+ import type { GraphileConfig } from 'graphile-config';
26
+ import type { UploadPluginOptions } from './types';
27
+ /**
28
+ * Creates the Upload plugin with the given options.
29
+ */
30
+ export declare function createUploadPlugin(options?: UploadPluginOptions): GraphileConfig.Plugin;
31
+ export declare const UploadPlugin: typeof createUploadPlugin;
32
+ export default UploadPlugin;