@galadrim/galadmin 0.2.9 → 0.2.11
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/.github/workflows/ci.yml +37 -0
- package/.github/workflows/main.yml +1 -28
- package/README.md +41 -4
- package/dist/api.js +5 -7
- package/dist/api.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/config.d.ts +2 -2
- package/package.json +3 -2
- package/src/api.ts +6 -4
- package/src/types/config.ts +2 -2
- package/tests/integration/routes.upload.integration.test.ts +55 -0
package/dist/types/config.d.ts
CHANGED
|
@@ -132,8 +132,8 @@ export type FileUploadProperties = {
|
|
|
132
132
|
originalNameField?: string;
|
|
133
133
|
s3Config?: {
|
|
134
134
|
host: string;
|
|
135
|
-
accessKeyId
|
|
136
|
-
secretAccessKey
|
|
135
|
+
accessKeyId?: string;
|
|
136
|
+
secretAccessKey?: string;
|
|
137
137
|
bucket: string;
|
|
138
138
|
subfolder?: string;
|
|
139
139
|
signedUrlNeeded?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@galadrim/galadmin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "jest",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"test:coverage": "TEST_INTEGRATION=1 jest --coverage --runInBand --projects jest.config.js jest.integration.config.js",
|
|
10
10
|
"test:integration": "TEST_INTEGRATION=1 jest --config jest.integration.config.js --runInBand",
|
|
11
11
|
"test:all": "npm run test:unit && npm run test:integration",
|
|
12
|
-
"build": "tsc"
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"typecheck": "tsc --noEmit --incremental false"
|
|
13
14
|
},
|
|
14
15
|
"engines": {
|
|
15
16
|
"node": ">=22"
|
package/src/api.ts
CHANGED
|
@@ -1390,10 +1390,12 @@ export default (db, config) => {
|
|
|
1390
1390
|
const s3 = new S3Client({
|
|
1391
1391
|
endpoint,
|
|
1392
1392
|
region: s3Config.region,
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1393
|
+
...(s3Config.accessKeyId && {
|
|
1394
|
+
credentials: {
|
|
1395
|
+
accessKeyId: s3Config.accessKeyId,
|
|
1396
|
+
secretAccessKey: s3Config.secretAccessKey ?? "",
|
|
1397
|
+
},
|
|
1398
|
+
}),
|
|
1397
1399
|
forcePathStyle: false,
|
|
1398
1400
|
});
|
|
1399
1401
|
if (s3Config.signedUrlNeeded) {
|
package/src/types/config.ts
CHANGED
|
@@ -147,8 +147,8 @@ export type FileUploadProperties = {
|
|
|
147
147
|
originalNameField?: string;
|
|
148
148
|
s3Config?: {
|
|
149
149
|
host: string;
|
|
150
|
-
accessKeyId
|
|
151
|
-
secretAccessKey
|
|
150
|
+
accessKeyId?: string;
|
|
151
|
+
secretAccessKey?: string;
|
|
152
152
|
bucket: string;
|
|
153
153
|
subfolder?: string;
|
|
154
154
|
signedUrlNeeded?: boolean;
|
|
@@ -162,6 +162,61 @@ describeIntegration("upload routes against real databases", () => {
|
|
|
162
162
|
expect(Buffer.isBuffer(sentCommand.Body)).toBe(true);
|
|
163
163
|
});
|
|
164
164
|
|
|
165
|
+
it("lets the SDK resolve credentials when no accessKeyId is configured", async () => {
|
|
166
|
+
const s3Mock = jest.requireMock("@aws-sdk/client-s3");
|
|
167
|
+
const column = fileColumn({
|
|
168
|
+
s3Config: {
|
|
169
|
+
host: "s3.example.com",
|
|
170
|
+
bucket: "b",
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
const { app, colId } = appWithColumn(column);
|
|
174
|
+
await s3Request(app, colId).expect(200);
|
|
175
|
+
expect(s3Mock.S3Client.mock.calls[0][0]).not.toHaveProperty(
|
|
176
|
+
"credentials",
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it("lets the SDK resolve credentials when accessKeyId is an empty string", async () => {
|
|
181
|
+
const s3Mock = jest.requireMock("@aws-sdk/client-s3");
|
|
182
|
+
const column = fileColumn({
|
|
183
|
+
s3Config: {
|
|
184
|
+
host: "s3.example.com",
|
|
185
|
+
accessKeyId: "",
|
|
186
|
+
secretAccessKey: "",
|
|
187
|
+
bucket: "b",
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
const { app, colId } = appWithColumn(column);
|
|
191
|
+
await s3Request(app, colId).expect(200);
|
|
192
|
+
expect(s3Mock.S3Client.mock.calls[0][0]).not.toHaveProperty(
|
|
193
|
+
"credentials",
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("lets the SDK resolve credentials in the signed-URL flow when no accessKeyId is configured", async () => {
|
|
198
|
+
const presignerMock = jest.requireMock("@aws-sdk/s3-request-presigner");
|
|
199
|
+
const s3Mock = jest.requireMock("@aws-sdk/client-s3");
|
|
200
|
+
const column = fileColumn({
|
|
201
|
+
s3Config: {
|
|
202
|
+
host: "s3.example.com",
|
|
203
|
+
bucket: "b",
|
|
204
|
+
signedUrlNeeded: true,
|
|
205
|
+
region: "eu-west-3",
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
const { app, colId } = appWithColumn(column);
|
|
209
|
+
await s3Request(app, colId).expect(200);
|
|
210
|
+
expect(s3Mock.S3Client.mock.calls[0][0]).not.toHaveProperty(
|
|
211
|
+
"credentials",
|
|
212
|
+
);
|
|
213
|
+
expect(presignerMock.getSignedUrl).toHaveBeenCalledWith(
|
|
214
|
+
s3Mock.S3Client.mock.results[0].value,
|
|
215
|
+
expect.anything(),
|
|
216
|
+
{ expiresIn: 150 },
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
|
|
165
220
|
it("prefixes https:// to hosts missing a scheme", async () => {
|
|
166
221
|
const s3Mock = jest.requireMock("@aws-sdk/client-s3");
|
|
167
222
|
const column = fileColumn({
|