Skip to content

Commit f9a72d0

Browse files
committed
Allow multipart uploads of large files
Change-type: minor
1 parent cf97b7f commit f9a72d0

File tree

6 files changed

+749
-2
lines changed

6 files changed

+749
-2
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"webpack-build": "npm run webpack-browser && npm run webpack-module && npm run webpack-server",
2121
"lint": "balena-lint -t tsconfig.dev.json -e js -e ts src test build typings Gruntfile.cts && npx tsc --project tsconfig.dev.json --noEmit",
2222
"test": "npm run build && npm run lint && npm run webpack-build && npm run test:compose && npm run test:generated-types",
23-
"test:compose": "trap 'docker compose -f docker-compose.npm-test.yml down ; echo Stopped ; exit 0' INT; docker compose -f docker-compose.npm-test.yml up -d && sleep 2 && DATABASE_URL=postgres://docker:docker@localhost:5431/postgres PINEJS_WEBRESOURCE_MAXFILESIZE=1000000000 S3_ENDPOINT=http://localhost:43680 S3_ACCESS_KEY=USERNAME S3_SECRET_KEY=PASSWORD S3_STORAGE_ADAPTER_BUCKET=balena-pine-web-resources S3_REGION=us-east-1 PINEJS_QUEUE_CONCURRENCY=1 TZ=UTC npx mocha",
23+
"test:compose": "trap 'docker compose -f docker-compose.npm-test.yml down ; echo Stopped ; exit 0' INT; docker compose -f docker-compose.npm-test.yml up -d && sleep 2 && DATABASE_URL=postgres://docker:docker@localhost:5431/postgres PINEJS_WEBRESOURCE_MAXFILESIZE=1000000000 S3_ENDPOINT=http://localhost:43680 S3_ACCESS_KEY=USERNAME S3_SECRET_KEY=PASSWORD S3_STORAGE_ADAPTER_BUCKET=balena-pine-web-resources S3_REGION=us-east-1 PINEJS_QUEUE_CONCURRENCY=1 TZ=UTC PINEJS_WEBRESOURCE_MULTIPART_ENABLED=true npx mocha",
2424
"test:generated-types": "npm run generate-types && git diff --exit-code ./src/sbvr-api/user.ts ./src/migrator/migrations.ts ./src/sbvr-api/dev.ts",
2525
"lint-fix": "balena-lint -t tsconfig.dev.json -e js -e ts --fix src test build typings Gruntfile.cts",
2626
"generate-types": "node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/user.sbvr ./src/sbvr-api/user.ts && node ./bin/sbvr-compiler.js generate-types ./src/migrator/migrations.sbvr ./src/migrator/migrations.ts && node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/dev.sbvr ./src/sbvr-api/dev.ts && node ./bin/sbvr-compiler.js generate-types ./src/tasks/tasks.sbvr ./src/tasks/tasks.ts && node ./bin/sbvr-compiler.js generate-types ./src/webresource-handler/webresource.sbvr ./src/webresource-handler/webresource.ts && balena-lint -t tsconfig.dev.json --fix ./src/sbvr-api/user.ts ./src/migrator/migrations.ts ./src/sbvr-api/dev.ts"
@@ -70,7 +70,7 @@
7070
"devDependencies": {
7171
"@balena/lint": "^9.1.6",
7272
"@balena/pinejs": "file:./",
73-
"@balena/pinejs-webresource-s3": "^1.0.4",
73+
"@balena/pinejs-webresource-s3": "2.0.0-build-new-multiparthandle-interface-66b03581234eaa7ce15c6f389e39b5b7ed3d1bc5-1",
7474
"@faker-js/faker": "^9.6.0",
7575
"@types/busboy": "^1.5.4",
7676
"@types/chai": "^5.2.1",

src/config-loader/env.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ export const tasks = {
159159
queueIntervalMS: intVar('PINEJS_QUEUE_INTERVAL_MS', 1000),
160160
};
161161

162+
export const webResource = {
163+
multipartUploadEnabled: boolVar(
164+
'PINEJS_WEBRESOURCE_MULTIPART_ENABLED',
165+
false,
166+
),
167+
singleUploadMaxFilesize: intVar(
168+
'PINEJS_WEBRESOURCE_MAXFILESIZE',
169+
299 * 1024 * 1024,
170+
),
171+
};
172+
162173
export const guardTestMockOnly = () => {
163174
if (process.env.DEPLOYMENT !== 'TEST') {
164175
throw new Error('Attempting to use TEST_MOCK_ONLY outside of tests');

src/webresource-handler/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ import { TypedError } from 'typed-error';
1818
import type { Resolvable } from '../sbvr-api/common-types.js';
1919
import type WebresourceModel from './webresource.js';
2020
import { importSBVR } from '../server-glue/sbvr-loader.js';
21+
import {
22+
isMultipartUploadAvailable,
23+
multipartUploadHooks,
24+
} from './multipartUpload.js';
2125

2226
export * from './handlers/index.js';
27+
export type { BeginUploadResponse } from './multipartUpload.js';
2328

2429
export interface IncomingFile {
2530
fieldname: string;
@@ -332,6 +337,9 @@ const throwIfWebresourceNotInMultipart = (
332337
{ req, request }: HookArgs,
333338
) => {
334339
if (
340+
request.custom.isAction !== 'beginUpload' &&
341+
request.custom.isAction !== 'commitUpload' &&
342+
request.custom.isAction !== 'cancelUpload' &&
335343
!req.is?.('multipart') &&
336344
webResourceFields.some((field) => request.values[field] != null)
337345
) {
@@ -528,6 +536,15 @@ export const setupUploadHooks = (
528536
resourceName,
529537
getCreateWebResourceHooks(handler),
530538
);
539+
540+
if (isMultipartUploadAvailable(handler)) {
541+
sbvrUtils.addPureHook(
542+
'POST',
543+
apiRoot,
544+
resourceName,
545+
multipartUploadHooks(handler),
546+
);
547+
}
531548
};
532549

533550
const initSql = `

0 commit comments

Comments
 (0)