System Information
- Strapi Version: 4.13.3
- Operating System: Ubuntu 22.04
- Database: MySQL 8
- Node Version: 18
- NPM Version: 9.3.1
- Yarn Version:
I would like to let end-user upload a CSV. Server parses the file and do something else like sending an email. Since file upload is on POST
/api/upload
I have to make a provider
so as to achieve the needs.
I have been following this guide to create a local
provider
:
/package.json
"dependencies": {
...
"strapi-provider-upload-stockcheck": "file:providers/strapi-provider-upload-stockcheck"
},
strapi/providers/strapi-provider-upload-stockcheck/package.json
{
"name": "strapi-provider-upload-stockcheck",
"version": "1.0.20",
"description": "",
"main": "index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "y2kbug",
"license": "ISC",
"dependencies": {
"csv-parse": "^5.5.0",
"fs-extra": "10.0.0"
}
}
Referencing to the official guide, and these two pages:
strapi/providers/strapi-provider-upload-stockcheck/index.ts
import { pipeline } from 'stream';
import fs, { ReadStream } from 'fs';
import path from 'path';
import fse from 'fs-extra';
const UPLOADS_FOLDER_NAME = 'uploads/stock-check';
export default {
init(providerOptions) {
const uploadPath = path.resolve(strapi.dirs.static.public, UPLOADS_FOLDER_NAME);
if (!fse.pathExistsSync(uploadPath)) {
throw new Error(
`The upload folder (${uploadPath}) doesn't exist or is not accessible. Please make sure it exists.`
);
}
return {
upload(file) {
console.log('OVERRIDE FUNCTION UPLOAD');
// upload the file in the provider
// file content is accessible by `file.buffer`
},
uploadStream(file): Promise<void> {
console.log('OVERRIDE FUNCTION uploadStream');
if (!file.stream) {
return Promise.reject(new Error('Missing file stream'));
}
const { stream } = file;
return new Promise((resolve, reject): void => {
pipeline(
stream,
fs.createWriteStream(path.join(uploadPath, `${file.hash}${file.ext}`)),
(err) => {
if (err) {
return reject(err);
}
file.url = `/${UPLOADS_FOLDER_NAME}/${file.hash}${file.ext}`;
}
);
resolve();
});
const headers = [
'SKU',
'Quantity',
];
const records = [];
const {parse} = require('csv-parse');
const parser = parse({
delimiter: ',',
});
// Use the readable stream api to consume records
parser.on('readable', function () {
let record;
while ((record = parser.read()) !== null) {
records.push(record);
}
});
// Catch any error
parser.on('error', function (err) {
console.error(err.message);
});
// Test that the parsed records matched the expected records
parser.on('end', function () {
console.log(records);
});
console.log(stream);
// parser.write(file.stream);
// Close the readable stream
parser.end();
},
delete(file) {
console.log('OVERRIDE FUNCTION delete');
// delete the file in the provider
},
checkFileSize(file, {sizeLimit}) {
// (optional)
// implement your own file size limit logic
},
getSignedUrl(file) {
// (optional)
// Generate a signed URL for the given file.
// The signed URL allows secure access to the file.
// Only Content Manager assets will be signed.
// Returns an object {url: string}.
},
isPrivate() {
// (optional)
// if it is private, file urls will be signed
// Returns a boolean
},
};
},
};
I have come up with some problems.
- all the
import
lines are problematic:
import { pipeline } from 'stream';
^^^^^^
SyntaxError: Cannot use import statement outside a module
export
is problematic:
export default {
^^^^^^
SyntaxError: Unexpected token 'export'
export = {
^^^^^^
SyntaxError: Unexpected token 'export'
export function init(providerOptions) {
^^^^^^
SyntaxError: Unexpected token 'export'
- Everytime
index.ts
is modified,npm install
does not update thenode_modules
.npm update
will update but updating everything. If I putnpm install && npm update
indockerfile
it will consume much time. What is the best way to update?
Thank you very much.