upload method
- @Route.post('/api/packages/versions/newUpload')
Future<Response>
upload(
- Request req
)
Implementation
@Route.post('/api/packages/versions/newUpload')
Future<shelf.Response> upload(shelf.Request req) async {
try {
var uploader = await _getUploaderEmail(req);
var contentType = req.headers['content-type'];
if (contentType == null) throw 'invalid content type';
var mediaType = MediaType.parse(contentType);
var boundary = mediaType.parameters['boundary'];
if (boundary == null) throw 'invalid boundary';
var transformer = MimeMultipartTransformer(boundary);
MimeMultipart? fileData;
// The map below makes the runtime type checker happy.
// https://github.com/dart-lang/pub-dev/blob/19033f8154ca1f597ef5495acbc84a2bb368f16d/app/lib/fake/server/fake_storage_server.dart#L74
final stream = req.read().map((a) => a).transform(transformer);
await for (var part in stream) {
if (fileData != null) continue;
fileData = part;
}
var bb = await fileData!.fold(
BytesBuilder(), (BytesBuilder byteBuilder, d) => byteBuilder..add(d));
var tarballBytes = bb.takeBytes();
var tarBytes = GZipDecoder().decodeBytes(tarballBytes);
var archive = TarDecoder().decodeBytes(tarBytes);
ArchiveFile? pubspecArchiveFile;
ArchiveFile? readmeFile;
ArchiveFile? changelogFile;
for (var file in archive.files) {
if (file.name == 'pubspec.yaml') {
pubspecArchiveFile = file;
continue;
}
if (file.name.toLowerCase() == 'readme.md') {
readmeFile = file;
continue;
}
if (file.name.toLowerCase() == 'changelog.md') {
changelogFile = file;
continue;
}
}
if (pubspecArchiveFile == null) {
throw 'Did not find any pubspec.yaml file in upload. Aborting.';
}
var pubspecYaml = utf8.decode(pubspecArchiveFile.content);
var pubspec = loadYamlAsMap(pubspecYaml)!;
if (uploadValidator != null) {
await uploadValidator!(pubspec, uploader);
}
// TODO: null
var name = pubspec['name'] as String;
var version = pubspec['version'] as String;
var package = await metaStore.queryPackage(name);
// Package already exists
if (package != null) {
if (package.private == false) {
throw '$name is not a private package. Please upload it to https://pub.dev';
}
// Check uploaders
if (package.uploaders?.contains(uploader) == false) {
throw '$uploader is not an uploader of $name';
}
// Check duplicated version
var duplicated = package.versions
.firstWhereOrNull((item) => version == item.version);
if (duplicated != null) {
throw 'version invalid: $name@$version already exists.';
}
}
// Upload package tarball to storage
await packageStore.upload(name, version, tarballBytes);
String? readme;
String? changelog;
if (readmeFile != null) {
readme = utf8.decode(readmeFile.content);
}
if (changelogFile != null) {
changelog = utf8.decode(changelogFile.content);
}
// Write package meta to database
var unpubVersion = UnpubVersion(
version,
pubspec,
pubspecYaml,
uploader,
readme,
changelog,
DateTime.now(),
);
await metaStore.addVersion(name, unpubVersion);
// TODO: Upload docs
return shelf.Response.found(
_resolveUrl(req, '/api/packages/versions/newUploadFinish'));
} catch (err) {
return shelf.Response.found(_resolveUrl(
req, '/api/packages/versions/newUploadFinish?error=$err'));
}
}