Packages/Mappings/B
STATUS: PROPOSAL
-1: Ash Berlin, Isaac Schlueter, Charles Jolley
+1: Kris Zyp, ChristophDorn, Irakli Gozalishvili, Kris Kowal
Contents
Package Mappings
This specification describes an addition to the CommonJS package format for packages to define how they expect their module namespace to be mapped into the module name spaces of referenced packages. This specification introduces a "mappings" property that describes special behavior of the "require" function that is scoped to all modules in the given package, such that top level identifiers starting with particular values for their first slash-delimited term correspond to top-level modules in the respectively mapped package. This specification does not define how the modules of referenced packages are installed or retrieved, and it does not define how any module identifiers are resolved apart from those that are mapped.
Example:
{ "name": "mypackage", "mappings": { "theirpackage": "http://github.com/them/theirpackage/zipball/master" } }
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Packages
- The
package.json
at the root of a package directory tree or archive MAY have a"mappings"
property. - The
"mappings"
property maps single-term top-level module identifiers to external package references. - A single-term top-level module identifier MUST consist of only lower-case letters, digits, underscore, and hyphen. Note: It MUST not include a slash (
"/"
) or dot ("."
). - If an external package reference is a string, it is equivalent to an object with that string as its
"location"
property. - An external package reference MUST have a
"location"
property.- The
"location"
MUST be an HTTP URL String. - If the
"location"
ends with a slash ("/"
), it MUST refer to the root of a directory tree conforming to the content of a package as described by Packages and where every contained file is retrievable with an HTTP GET request for a path resolved based on the given location. - If the
"location"
does not end with a slash ("/"
), it MUST refer to an archive as described by Packages and retrievable with a single HTTP GET request.
- The
- An external package reference MAY have a
"descriptor"
property that is a limited package descriptor object, a strict subset of thepackage.json
schema as described in Packages.- A package descriptor MAY have a
"index"
propertyString
that is a path relative to the root of the package URL or archive. - A package descriptor MAY have a
"directories"
property.- The
"directories"
Object MAY have a"lib"
property, which MUST be aString
describing a relative path, resolved from the root of a package or archive.
- The
- A package descriptor MAY have a
- If
package.json
contains an"overlay"
property, and any of the applicable values of the overlay property (as defined by Packages) contain a "mappings" property, the (key, value) pairs of the main "mappings" property MUST be updated with each applicable overlaid mappings property, overriding existing (key, value) pairs. - If the
"location"
of the package refers to a retrievable archive, an external package reference MAY have a"verify"
property that is anObject
.- The
"verify"
object MUST have a"algorithm"
property that refers to the algorithm with which the"signature"
was generated. - The
"verify"
object MUST have a"signature"
property that is a signature or hash of the referenced archive. - The
"signature"
MUST be a lower-case base-16 value represented as a string of colon-delimited bytes. - The
"algorithm"
MAY be"md5"
, in which case the"signature"
MUST be a MD5 digest of the package archive file, computed as described in RFC 1321. - The
"algorithm"
MAY be"sha1"
, in which case the"signature"
MUST be an SHA-1 digest of the package archive file, computed as described in RFC 3174.
- The
Note: this specification does not define the behavior of any other verification algorithms. These may be amended in a future revision.
Note: this specification does not define any archival formats apart from zip since this is the only standard format described in Packages, and may be amended in a future revision of that specification, in which case corresponding verbiage must be added to this specification to indicate the archival format of the an external package.
Modules
Within a package, the semantics of the require
function are augmented as follows:
- If the required module identifier is not relative, it is a candidate for referencing a module in an external package.
- If the identifier has only one term (That is, contains no slashes (
"/"
)), it is a candidate for referencing the index module of an external package.- If this package is external to another package, and the parent package has an
"index"
property in its mapping for this package,require
MUST return the exports of the specified index module of the external package. - Otherwise, if the external package does have an
"index"
property in itspackage.json
file,require
MUST return the exports of the index module of the external package. - Otherwise,
require
MUST throw anError
.
- If this package is external to another package, and the parent package has an
- If the identifier has multiple terms delimited by slashes, it is a candidate for referencing a module in the library directory of an external package.
- If the first term of the module identifier as delimited by slashes is not a property of the
"mappings"
object in the current package'spackage.json
, the behavior ofrequire
is beyond the scope of this specification and follows through with the behavior defined in Packages in the context of the current package. - If the first term of the module identifier as delimited by slashes is a property of the
"mappings"
object in the current package'spackage.json
,require
MUST return the exports of the module with the top-level identifier composed of all subsequent slash-delimited terms in the required module identifier in the context of the referenced external package as defined in Packages.- If the external package reference contains a
descriptor.directories.lib
property, the modules from the external package MUST be found in the named lib directory, resolved relative to the root of the external package.
- If the external package reference contains a
- If the first term of the module identifier as delimited by slashes is not a property of the
- If the identifier has only one term (That is, contains no slashes (
The Index Module
- In the evaluation context of an index module, the value of the
module
free variable does not have an"id"
property.
Examples
{ "name": "mypackage", "mappings": { "theirpackage": "http://github.com/them/theirpackage/zipball/master" } }
This example is equivalent to the above example, by virtue of rotating the package location into an external package reference object.
{ "name": "mypackage", "mappings": { "theirpackage": { "location": "http://github.com/them/theirpackage/zipball/master" } } }
This example includes an annotation on where to find the index module of a legacy Narwhal external package, and an annotation describing the SHA-1 hash of the package archive for verification purposes.
{ "name": "jill", "mappings": { "jack": { "location": "http://github.com/280north/jack/zipball/master", "descriptor": "index": "lib/jack.js", "directories": { "lib": "lib/jack" } }, "verify": { "signature": "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87", "algorithm": "sha1" } } } }
The following example indicates how you might externally reference a package that was not designed for CommonJS:
{ "name": "mypackage", "mappings": { "dojox": { "location": "http://download.dojotoolkit.org/release-1.4.3/dojo-release-1.4.3.zip", "descriptor": { "directories": { "lib": "dojox" } } } } }