Packages/Mappings/C

From CommonJS Spec Wiki
Jump to: navigation, search

STATUS: PROPOSAL

Implementations
[[Implementations/PINF|]]

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.

Examples

A package that provides the URL of an archive that is known to work as a subpackage.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
           "archive": "http://github.com/them/theirpackage/zipball/master"
        }
    }
}

This can be written more tersely:

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": "http://github.com/them/theirpackage/zipball/master"
    }
}

A package that provides the exact version number of a subpackage that is known to work. A version number implies that this package is a member of some registry or catalog with consistently named and versioned packages.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
            "version": "0.0.1"
        }
    }
}

The URL of the registry or catalog may be provided for informational purposes, but this specification does not impose any restrictions on the format or content of the registry.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
            "version": "0.0.1"
        }
    },
    "catalog": "http://example.com/packages-catalog.json"
}

If a package uses sub-packages from a variety of catalogs, the informational catalog URL may be provided for specific mappings.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
            "version": "0.0.1"
        },
        "otherpackage": {
            "version": "0.0.1",
            "catalog": "http://example.org/some/other/catalog.json"
        }
    },
    "catalog": "http://example.com/packages-catalog.json"
}

The key of the mapping indicates how the package will be known in modules. In these examples, the "main" module of "theirpackage" would be imported as "theirpackage".

require("theirpackage");

If the package comes from a registry of coordinated package names, the name of the package in the repository is assumed to be the same as the key of the mapping. However, it may be overridden.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
            "version": "0.0.1",
            "name": "theirpackagename"
        }
    },
    "catalog": "http://example.com/packages-catalog.json"
}

Some package managers can fetch individual files from an unpacked package, provided over HTTP at a particular location. The "location" key indicates the URL of an unpacked package that is known to work as a subpackage.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
            "location": "http://example.com/packages/theirpackage/"
        }
    }
}

To be compatible with a wide variety of package managers, packages should include a variety of metadata, and may provide all of the defined attributes.

{
    "name": "mypackage",
    "mappings": {
        "theirpackage": {
            "name": "theirpackagename",
            "version": "0.0.1",
            "archive": "http://example.com/packages/theirpackage.zip",
            "location": "http://example.com/packages/theirpackage/"
        }
    },
    "catalog": "http://example.com/packages-catalog.json"
}
  1. To be compliant with this specification, a package manager must be able to handle any package that provides all of the recommended metadata.
  2. To be usable by any package manager, a package must provide all of the recommended metadata.

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

  1. The package.json at the root of a package directory tree or archive MAY have a "mappings" property.
  2. package.json's "mappings" property maps single-term top-level module identifiers to external package references.
  3. 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 (".").
  4. If an external package reference is a string and the string is an absolute URL, it is equivalent to an object with that string as its "archive" property.
  5. If an external package reference is a string and the string is a relative URL, it is equivalent to an object with that string as its "location" property.
  6. An external package reference SHOULD have an "archive" property. Package managers MAY depend on the provision of this property.
    1. The "archive" property MUST be an URL String from which an archive as described by Packages can be downloaded with an HTTP GET request.
  7. An external package reference SHOULD have a "location" property. Package managers MAY depend on the provision of this property.
    1. The "location" property 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 by the URL resolved based on the given location. If the "location" property is a relative URL, it MUST be resolved relative to the package root of the parent package that is being described and contains the mappings (i.e. relative to this package.json file). If the package has been expanded from an archive, the relative URLs MAY point to another directory within the archive.
  8. An external package reference MAY have a "version" property. Package managers MAY depend on the provision of this property.
    1. If "version" exists, an external package reference MAY contain a "name" property that indicates the name of the package in a coordinated registry of packages. If omitted, this property defaults to the key of the mapping.
  9. An external package reference MAY have a "descriptor" property that is a package descriptor object, conforming to the package.json schema as described in Packages.
  10. An external package reference MAY have a "catalog" property that notes the URL of the catalog or registry with which a package manager is expected to associate this external package reference with additional or missing details.
  11. package.json may have a "catalog" property that notes the URL of the catalog or registry with which to associate package names and versions with further corresponding external package reference details.
  12. If the external package reference has a "archive" property, an external package reference MAY have a "verify" property that is an Object.
    1. The "verify" object MUST have a "algorithm" property that refers to the algorithm with which the "signature" was generated.
    2. The "verify" object MUST have a "signature" property that is a signature or hash of the referenced archive.
    3. The "signature" MUST be a lower-case base-16 value represented as a string of colon-delimited bytes.
    4. 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.
    5. 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.

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.

Note: This specification does not impose any restrictions on the format of the catalog file, nor even whether it is retrievable. Package registries or catalogs may opt to disqualify a package based on whether it supports a particular catalog URL, the format of the catalog, or for not providing a catalog URL.

Note: An external package reference may contain further properties. This specification recommends that these properties be prefixed with an implementation name to avoid collisions with properties of other implementations and future versions of this specification.

Modules

Within a package, the semantics of the require function are augmented as follows:

  1. If the required module identifier is not relative, it is a candidate for referencing a module in an external package.
    1. If the identifier has only one term (That is, contains no slashes ("/")), it is a candidate for referencing the main module of an external package.
      1. If this package is external to another package, and the parent package has an "main" property in its mapping for this package, require MUST return the exports of the specified main module of the external package.
      2. Otherwise, if the external package does have an "main" property in its package.json file, require MUST return the exports of the main module of the external package.
      3. Otherwise, require MUST throw an Error.
    2. 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.
      1. If the first term of the module identifier as delimited by slashes is not a property of the "mappings" object in the current package's package.json, the behavior of require is beyond the scope of this specification and follows through with the behavior defined in Packages in the context of the current package.
      2. If the first term of the module identifier as delimited by slashes is a property of the "mappings" object in the current package's package.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.
        1. 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.

Related Discussions