We’re trying to use AWS SDK (S3Client) but it makes the client grow by 800kb (and it makes the app not load on old iPhones).
So 2 questions:
1-How can we install the npm package so it goes into the server package only (and not the client/cordova)
2-How can I check what gets included in the Cordova package (and client as well)
We’re using S3 to upload Excel files we create on the server.
We’d also like to use it for our users to upload their documents directly from the client and not through the server.
Ok so as I understand, what you need is a server side upload and a “sling” upload from the client.
You can start from here: GitHub - activitree/s3up-meta
You will need to polish the code a bit, I haven’t touched it in a while. You will need to remove this.unblock() where you find it (no longer required in the async env)
You will need to install NPM @aws-sdk/client-s3 as a direct dependency in your project. This package has 2-3 updates every week and I didn’t want to have it hooked into the Meteor package and then struggle to update the package every week.
Here is an example of a server side method that takes an image url and saves the image to S3 with a cacheing configuration:
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
new ValidatedMethod({
name: 'saveLinkPreviewToAWS',
validate: new SimpleSchema({
url: String,
key: String
}).validator(),
async run ({ url, key }) {
if (!this.userId) { throw new Meteor.Error('not-authorized') }
const s3 = new S3Client({
region: process.env.AWS_S3_REGION || 'eu-central-1',
sslEnabled: true, // optional
httpOptions: {
timeout: 6000,
agent: false
}
})
const putFromUrl = async url => {
try {
const response = await fetch(url, { method: 'get' }) // fetch the image
const command = new PutObjectCommand({
Bucket: process.env.AWS_S3_BUCKET,
Key: `postsProxy/${this.userId}/${key}.jpg`, // path to where you want it saved in your S3 bucket
ContentType: response.headers.get('Content-Type'),
ContentLength: response.headers.get('Content-Length'),
// Expires: 'Thu, 15 Dec 2050 04:08:00 GMT',
CacheControl: 'max-age=8460000',
Body: await response.buffer() // buffer
})
s3.send(command, err => {
if (err) { console.error('Could not upload photo to S3, ', err) }
})
} catch (error) {
if (error /* instanceof fetch.AbortError */) {
console.error('Could not upload General Post photo to S3, ', error)
}
}
}
putFromUrl(url)
.catch(err => console.log(err))
}
})
One more mention. In this setup you should have no import of S3 components onto the client.
The way it works, the client requests an authorization from the Meteor server and proceeds with an XMLHttpRequest() directly to S3.
At this line, you capture the status of the upload (10% …20% …etc)