blob: 19f103922cf398c4663a2a85b52c15715857a906 [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Implementations of [Packages] that may be used in either server or browser
/// based applications. For implementations that can only run in the browser,
/// see [package_config.packages_io_impl].
@Deprecated("Use the package_config.json based API")
library package_config.packages_impl;
import "dart:collection" show UnmodifiableMapView;
import "../packages.dart";
import "util.dart" show checkValidPackageUri;
/// A [Packages] null-object.
class NoPackages implements Packages {
const NoPackages();
Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
var packageName = checkValidPackageUri(packageUri, "packageUri");
if (notFound != null) return notFound(packageUri);
throw ArgumentError.value(
packageUri, "packageUri", 'No package named "$packageName"');
}
Iterable<String> get packages => Iterable<String>.empty();
Map<String, Uri> asMap() => const <String, Uri>{};
String get defaultPackageName => null;
String packageMetadata(String packageName, String key) => null;
String libraryMetadata(Uri libraryUri, String key) => null;
}
/// Base class for [Packages] implementations.
///
/// This class implements the [resolve] method in terms of a private
/// member
abstract class PackagesBase implements Packages {
Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
packageUri = packageUri.normalizePath();
var packageName = checkValidPackageUri(packageUri, "packageUri");
var packageBase = getBase(packageName);
if (packageBase == null) {
if (notFound != null) return notFound(packageUri);
throw ArgumentError.value(
packageUri, "packageUri", 'No package named "$packageName"');
}
var packagePath = packageUri.path.substring(packageName.length + 1);
return packageBase.resolve(packagePath);
}
/// Find a base location for a package name.
///
/// Returns `null` if no package exists with that name, and that can be
/// determined.
Uri getBase(String packageName);
String get defaultPackageName => null;
String packageMetadata(String packageName, String key) => null;
String libraryMetadata(Uri libraryUri, String key) => null;
}
/// A [Packages] implementation based on an existing map.
class MapPackages extends PackagesBase {
final Map<String, Uri> _mapping;
MapPackages(this._mapping);
Uri getBase(String packageName) =>
packageName.isEmpty ? null : _mapping[packageName];
Iterable<String> get packages => _mapping.keys;
Map<String, Uri> asMap() => UnmodifiableMapView<String, Uri>(_mapping);
String get defaultPackageName => _mapping[""]?.toString();
String packageMetadata(String packageName, String key) {
if (packageName.isEmpty) return null;
var uri = _mapping[packageName];
if (uri == null || !uri.hasFragment) return null;
// This can be optimized, either by caching the map or by
// parsing incrementally instead of parsing the entire fragment.
return Uri.splitQueryString(uri.fragment)[key];
}
String libraryMetadata(Uri libraryUri, String key) {
if (libraryUri.isScheme("package")) {
return packageMetadata(libraryUri.pathSegments.first, key);
}
var defaultPackageNameUri = _mapping[""];
if (defaultPackageNameUri != null) {
return packageMetadata(defaultPackageNameUri.toString(), key);
}
return null;
}
}
/// A [Packages] implementation based on a remote (e.g., HTTP) directory.
///
/// There is no way to detect which packages exist short of trying to use
/// them. You can't necessarily check whether a directory exists,
/// except by checking for a know file in the directory.
class NonFilePackagesDirectoryPackages extends PackagesBase {
final Uri _packageBase;
NonFilePackagesDirectoryPackages(this._packageBase);
Uri getBase(String packageName) => _packageBase.resolve("$packageName/");
Error _failListingPackages() {
return UnsupportedError(
"Cannot list packages for a ${_packageBase.scheme}: "
"based package root");
}
Iterable<String> get packages {
throw _failListingPackages();
}
Map<String, Uri> asMap() {
throw _failListingPackages();
}
}