Beispiel #1
0
class GithubDetail(jsl.Document):
    """JSL schema for Github worker results details."""
    class Options(object):
        """JSL schema for Github worker results details."""

        definition_id = "github_extracted_details"
        description = "Details of Github inspection"

    # we don't mandate any of these fields, because they may not be present
    forks_count = jsl.IntField()
    last_year_commits = jsl.DocumentField(GithubLastYearCommits, as_ref=True)
    open_issues_count = jsl.IntField()
    stargazers_count = jsl.IntField()
    subscribers_count = jsl.IntField()
    with removed_in(ROLE_v2_0_0) as until_v2_0_0:
        until_v2_0_0.updated_issues = jsl.DocumentField(GithubUpdatedIssues,
                                                        as_ref=True)
        until_v2_0_0.updated_pull_requests = jsl.DocumentField(
            GithubUpdatedPullRequests, as_ref=True)
    with added_in(ROLE_v1_0_2) as since_v1_0_2:
        since_v1_0_2.contributors_count = jsl.IntField()
    with jsl.Scope(ROLE_v1_0_3) as v1_0_3:
        v1_0_3.topics = jsl.ArrayField(jsl.StringField(), required=True)
    with added_in(ROLE_v1_0_4) as since_v1_0_4:
        since_v1_0_4.topics = jsl.ArrayField(jsl.StringField())
    with added_in(ROLE_v2_0_1) as since_v2_0_1:
        since_v2_0_1.license = jsl.DictField()
    with added_in(ROLE_v2_0_2) as since_v2_0_2:
        since_v2_0_2.updated_on = jsl.StringField(required=True)
Beispiel #2
0
class CVEDetail(jsl.Document):
    class Options(object):
        definition_id = "cvecheck_details"
        description = "Detail of one CVE"

    with removed_in(ROLE_v3_0_0) as removed_in_v3_0_0:
        # access/impact are now part of vector string in cvss dict
        removed_in_v3_0_0.access = jsl.DocumentField(CVEAccess,
                                                     as_ref=True,
                                                     required=True)
        removed_in_v3_0_0.impact = jsl.DocumentField(CVEImpact,
                                                     as_ref=True,
                                                     required=True)
        removed_in_v3_0_0.cvss = jsl.NumberField(
            required=True)  # cvss is now dict
        removed_in_v3_0_0.summary = jsl.StringField(
            required=True)  # renamed to description

    with added_in(ROLE_v3_0_0) as added_in_v3_0_0:
        added_in_v3_0_0.cvss = jsl.DocumentField(CVSS,
                                                 as_ref=True,
                                                 required=True)
        added_in_v3_0_0.description = jsl.StringField(required=True)
        added_in_v3_0_0.severity = jsl.StringField(required=True)

    with added_in(ROLE_v3_0_1) as added_in_v3_0_1:
        added_in_v3_0_1.attribution = jsl.StringField(required=False)

    id = jsl.StringField(required=True)
    references = jsl.ArrayField(jsl.UriField(), required=True)
    # Present if defined for the particular CVE
    cwe = jsl.StringField(required=False)
    class RedHatUsage(jsl.Document):
        class Options:
            description = "Red Hat internal usage information for a single component"
            definition_id = "component_redhat_usage"

        package_names = jsl.ArrayField(jsl.StringField(), required=True)
        published_in = jsl.ArrayField(jsl.StringField(), required=True)
        registered_srpms = jsl.ArrayField(jsl.DocumentField(RegisteredSRPM, as_ref=True), required=True)
        with added_in(ROLE_v2_1_1) as added_in_v2_1_1:
            added_in_v2_1_1.all_rhn_channels = jsl.ArrayField(jsl.StringField())
            added_in_v2_1_1.all_rhsm_content_sets = jsl.ArrayField(jsl.StringField())
        with added_in(ROLE_v2_1_2) as added_in_v2_1_2:
            added_in_v2_1_2.all_rhsm_product_names = jsl.ArrayField(jsl.StringField())
        with added_in(ROLE_v2_1_3) as added_in_v2_1_3:
            added_in_v2_1_3.rh_mvn_matched_versions = jsl.ArrayField(jsl.StringField())
class PulpCDNResponse(jsl.Document):
    class Options(object):
        definition_id = "pulp_cdn_response"
        description = "The Pulp CDN handles Red Hat's SRPM publication"
        additional_properties = True

    with added_in(ROLE_v2_1_0) as since_v2_1:
        since_v2_1.srpm_filename = jsl.StringField(required=True)
    with added_in(ROLE_v2_2_0) as since_v2_2:
        since_v2_2.rhn_channels = jsl.ArrayField(jsl.StringField(),
                                                 required=True)
        since_v2_2.rhsm_content_sets = jsl.ArrayField(jsl.StringField(),
                                                      required=True)
        since_v2_2.rhsm_product_names = jsl.ArrayField(jsl.StringField(),
                                                       required=True)
class ToolchainResponses(jsl.Document):
    class Options(object):
        definition_id = "toolchain_responses"

    # These fields are optional, as this spec currently covers error responses
    # in addition to successful toolchain queries.
    # They can change to being required once a "standard error schema"
    # is implemented

    redhat_anitya = jsl.DocumentField(
        AnityaResponse,
        description="Results from Red Hat's internal Anitya instance",
        required=False,
        as_ref=True)
    brew = jsl.ArrayField(
        jsl.DocumentField(
            DownstreamPatchset,
            description="Results from Brew, Red Hat's internal Koji instance",
            required=False,
            as_ref=True))
    # The Pulp CDN details field became an array in v2-1-0
    _pulp_document_ref = jsl.DocumentField(
        PulpCDNResponse,
        description="Results from the Pulp CDN backing RPM delivery",
        required=False,
        as_ref=True)
    with removed_in(ROLE_v2_1_0) as before_v2_1:
        before_v2_1.pulp_cdn = _pulp_document_ref
    with added_in(ROLE_v2_1_0) as since_v2_1:
        since_v2_1.pulp_cdn = jsl.ArrayField(_pulp_document_ref)
    del _pulp_document_ref
Beispiel #6
0
class LicenseScanDetails(jsl.Document):
    class Options(object):
        definition_id = "license_scan_details"
        additional_properties = True

    with removed_in(ROLE_v3_0_0) as removed_in_v3_0_0:
        removed_in_v3_0_0.files = jsl.ArrayField(
            jsl.DocumentField(FileDetails, as_ref=True))
        removed_in_v3_0_0.license_stats = jsl.ArrayField(
            jsl.DocumentField(LicenseDetailsPre30, as_ref=True))
        removed_in_v3_0_0.oslc_stats = jsl.DocumentField(OSLCStats,
                                                         as_ref=True)

    with added_in(ROLE_v3_0_0) as added_in_v3_0_0:
        added_in_v3_0_0.files_count = jsl.IntField(required=True)
        added_in_v3_0_0.licenses = jsl.DictField(pattern_properties=jsl.Var({
            'role': {
                '*': jsl.DocumentField(LicenseDetails,
                                       as_ref=True,
                                       required=True),
            }
        }),
                                                 required=True)
        added_in_v3_0_0.scancode_notice = jsl.StringField(required=True)
        added_in_v3_0_0.scancode_version = jsl.StringField(required=True)
class LockFile(jsl.Document):
    """JSL schema for dependency lock file description."""
    class Options(object):
        """JSL schema for dependency lock file description."""

        definition_id = "metadata_lockfile"
        description = "Dependency lock file description"

    runtime = jsl.StringField()
    version = jsl.StringField()
    dependencies = jsl.ArrayField(
        jsl.DocumentField(LockedDependency, as_ref=True))
    with added_in(ROLE_v3_0_0) as since_v3_0_0:
        since_v3_0_0.name = jsl.StringField()
    with added_in(ROLE_v3_3_0) as added_in_v3_3_0:  # go glide
        added_in_v3_3_0.hash = jsl.StringField()
        added_in_v3_3_0.updated = jsl.StringField()
class ResultInner(JSLSchemaBase):
    class Options(object):
        definition_id = "result_inner"
        description = "Set of Result inner"

    with removed_in(ROLE_v1_2_0) as removed_in_v1_2_0:
        removed_in_v1_2_0.data = jsl.ArrayField(jsl.DocumentField(ResultData,
                                                                  as_ref=True),
                                                required=True)
    with added_in(ROLE_v1_2_0) as added_in_v1_2_0:
        added_in_v1_2_0.data = jsl.DocumentField(ResultData,
                                                 as_ref=True,
                                                 required=True)
    with added_in(ROLE_v1_2_0) as added_in_v1_2_0:
        added_in_v1_2_0.recommendation = jsl.DictField(
            additional_properties=True)
    meta = jsl.DictField(additional_properties=True)
class BlackduckLicenseDetails(jsl.Document):
    class Options:
        description = "Blackduck information about one license for a single component"
        definition_id = "component_blackduck_license_info"

    with removed_in(ROLE_v2_2_0) as removed_in_v2_2_0:
        removed_in_v2_2_0.codeSharing = jsl.StringField(required=True)
    with added_in(ROLE_v2_2_0) as added_in_v2_2_0:
        added_in_v2_2_0.code_sharing = jsl.StringField(required=True)
    name = jsl.StringField(required=True)
Beispiel #10
0
class ResultInner(JSLSchemaBase):
    """Class with the schema definition based on JSL domain specific language."""
    class Options(object):
        """A container for options."""

        definition_id = "result_inner"
        description = "Set of Result inner"

    with removed_in(ROLE_v1_2_0) as removed_in_v1_2_0:
        removed_in_v1_2_0.data = jsl.ArrayField(jsl.DocumentField(ResultData,
                                                                  as_ref=True),
                                                required=True)
    with added_in(ROLE_v1_2_0) as added_in_v1_2_0:
        added_in_v1_2_0.data = jsl.DocumentField(ResultData,
                                                 as_ref=True,
                                                 required=True)
    with added_in(ROLE_v1_2_0) as added_in_v1_2_0:
        added_in_v1_2_0.recommendation = jsl.DictField(
            additional_properties=True)
    meta = jsl.DictField(additional_properties=True)
Beispiel #11
0
class LockFile(jsl.Document):
    class Options(object):
        definition_id = "metadata_lockfile"
        description = "Dependency lock file description"

    runtime = jsl.StringField()
    version = jsl.StringField()
    dependencies = jsl.ArrayField(
        jsl.DocumentField(LockedDependency, as_ref=True))
    with added_in(ROLE_v3_0_0) as since_v3_0_0:
        since_v3_0_0.name = jsl.StringField()
class GithubUpdatedPullRequests(GithubUpdatedIssues):
    class Options(object):
        definition_id = "github_pull_requests_details"
        description = "Details of updated Github pull requests"

    with jsl.Scope(ROLE_v1_0_0) as v1_0_0:
        v1_0_0.open = jsl.IntField(required=True)
        v1_0_0.closed = jsl.IntField(required=True)
    with added_in(ROLE_v1_0_1) as since_v1_0_1:
        since_v1_0_1.year = jsl.DocumentField(GithubItemsByTime, as_ref=True)
        since_v1_0_1.month = jsl.DocumentField(GithubItemsByTime, as_ref=True)
class AnalysesGraphDB(JSLSchemaBase):
    class Options(object):
        definition_id = "analyses_graphdb"
        description = "Component Analysis from GraphDB"

    with removed_in(ROLE_v1_1_0) as removed_in_v1_1_0:
        removed_in_v1_1_0.requestId = jsl.StringField(required=True)
    with added_in(ROLE_v1_1_0) as added_in_v1_1_0:
        added_in_v1_1_0.request_id = jsl.StringField(required=True)

    result = jsl.DocumentField(ResultInner, as_ref=True, required=True)
    status = jsl.DocumentField(Status, as_ref=True, required=True)
Beispiel #14
0
class BlackduckLicenseDetails(jsl.Document):
    """Class with the schema definition based on JSL domain specific language."""
    class Options:
        """A container for options."""

        description = "Blackduck information about one license for a single component"
        definition_id = "component_blackduck_license_info"

    with removed_in(ROLE_v2_2_0) as removed_in_v2_2_0:
        removed_in_v2_2_0.codeSharing = jsl.StringField(required=True)
    with added_in(ROLE_v2_2_0) as added_in_v2_2_0:
        added_in_v2_2_0.code_sharing = jsl.StringField(required=True)
    name = jsl.StringField(required=True)
class DownstreamUsageSummary(jsl.Document):
    class Options(object):
        definition_id = "downstream_usage_summary"

    package_names = jsl.ArrayField(jsl.StringField(), required=True)
    # Brew query integration
    registered_srpms = jsl.ArrayField(jsl.DocumentField(SRPMRecord,
                                                        as_ref=True),
                                      required=True)
    # Pulp CDN query integration
    with jsl.Scope(ROLE_v1_0_0) as v1:
        v1.published_in = jsl.ArrayField(jsl.StringField(), required=True)
    with added_in(ROLE_v2_1_0) as since_v2_1:
        since_v2_1.all_rhn_channels = jsl.ArrayField(jsl.StringField(),
                                                     required=True)
        since_v2_1.all_rhsm_content_sets = jsl.ArrayField(jsl.StringField(),
                                                          required=True)
    with added_in(ROLE_v2_2_0) as since_v2_2:
        since_v2_2.all_rhsm_product_names = jsl.ArrayField(jsl.StringField(),
                                                           required=True)
    with added_in(ROLE_v2_2_1) as since_v2_2_1:
        since_v2_2_1.rh_mvn_matched_versions = jsl.ArrayField(
            jsl.StringField(), required=True)
Beispiel #16
0
class GithubUpdatedIssues(jsl.Document):
    """JSL schema for Details of updated Github issues."""
    class Options(object):
        """JSL schema for Details of updated Github issues."""

        definition_id = "github_issues_details"
        description = "Details of updated Github issues"

    with jsl.Scope(ROLE_v1_0_0) as v1_0_0:
        v1_0_0.open = jsl.IntField(required=True)
        v1_0_0.closed = jsl.IntField(required=True)
    with added_in(ROLE_v1_0_1) as since_v1_0_1:
        since_v1_0_1.year = jsl.DocumentField(GithubItemsByTime, as_ref=True)
        since_v1_0_1.month = jsl.DocumentField(GithubItemsByTime, as_ref=True)
class BlackduckSecurityDetails(jsl.Document):
    class Options:
        description = "Blackduck information about one vulnerability for a single component"
        definition_id = "component_blackduck_security_info"

    with removed_in(ROLE_v2_2_0) as removed_in_v2_2_0:
        removed_in_v2_2_0.baseScore = jsl.NumberField(required=True)
        removed_in_v2_2_0.exploitabilitySubscore = jsl.NumberField(required=True)
    with added_in(ROLE_v2_2_0) as added_in_v2_2_0:
        added_in_v2_2_0.base_score = jsl.NumberField(required=True)
        added_in_v2_2_0.exploitability_subscore = jsl.NumberField(required=True)
    id = jsl.StringField(required=True)
    severity = jsl.StringField(required=True)
    source = jsl.StringField(required=True)
Beispiel #18
0
class NpmShrinkwrap(jsl.Document):
    class Options(object):
        definition_id = "npm_shrinkwrap"
        description = "npm-shrinkwrap description"

    name = jsl.StringField()
    version = jsl.StringField()
    npm_shrinkwrap_version = jsl.StringField()
    node_version = jsl.StringField()
    with jsl.Scope(lambda v: v in (ROLE_v1_0_1, ROLE_v1_1_0)) as v1_0_1_v1_1_0:
        v1_0_1_v1_1_0.resolved_dependencies = jsl.ArrayField(jsl.StringField())
    with added_in(ROLE_v2_0_0) as since_v2_0_0:
        since_v2_0_0.dependencies = jsl.ArrayField(jsl.StringField())
        since_v2_0_0._system = jsl.StringField()
Beispiel #19
0
class AnalysesGraphDB(JSLSchemaBase):
    """Class with the schema definition based on JSL domain specific language."""
    class Options(object):
        """A container for options."""

        definition_id = "analyses_graphdb"
        description = "Component Analysis from GraphDB"

    with removed_in(ROLE_v1_1_0) as removed_in_v1_1_0:
        removed_in_v1_1_0.requestId = jsl.StringField(required=True)
    with added_in(ROLE_v1_1_0) as added_in_v1_1_0:
        added_in_v1_1_0.request_id = jsl.StringField(required=True)

    result = jsl.DocumentField(ResultInner, as_ref=True, required=True)
    status = jsl.DocumentField(Status, as_ref=True, required=True)
class LockedDependency(jsl.Document):
    """JSL schema for locked dependency description."""
    class Options(object):
        """JSL schema for locked dependency description."""

        definition_id = "metadata_locked_dependency"
        description = "Locked dependency description"

    name = jsl.StringField()
    version = jsl.StringField()
    specification = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    resolved = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    dependencies = jsl.ArrayField(
        jsl.DocumentField(jsl.RECURSIVE_REFERENCE_CONSTANT, as_ref=True))
    with added_in(ROLE_v3_3_0) as added_in_v3_3_0:
        added_in_v3_3_0.subpackages = jsl.ArrayField(
            jsl.StringField())  # go glide
Beispiel #21
0
class BlackduckSecurityDetails(jsl.Document):
    """Class with the schema definition based on JSL domain specific language."""
    class Options:
        """A container for options."""

        description = "Blackduck information about one vulnerability for a single component"
        definition_id = "component_blackduck_security_info"

    with removed_in(ROLE_v2_2_0) as removed_in_v2_2_0:
        removed_in_v2_2_0.baseScore = jsl.NumberField(required=True)
        removed_in_v2_2_0.exploitabilitySubscore = jsl.NumberField(
            required=True)
    with added_in(ROLE_v2_2_0) as added_in_v2_2_0:
        added_in_v2_2_0.base_score = jsl.NumberField(required=True)
        added_in_v2_2_0.exploitability_subscore = jsl.NumberField(
            required=True)
    id = jsl.StringField(required=True)
    severity = jsl.StringField(required=True)
    source = jsl.StringField(required=True)
class SRPMRecord(jsl.Document):
    class Options(object):
        definition_id = "srpm_record"
        description = "Summary of Red Hat tracked SRPM"

    # Proposed contents, TBC by Brew query integration work
    package_name = jsl.StringField(required=True)
    epoch = jsl.NumberField(required=True)
    version = jsl.StringField(required=True)
    release = jsl.StringField(required=True)
    patch_count = jsl.NumberField(required=True)
    modified_line_count = jsl.NumberField(required=True)
    modified_file_count = jsl.NumberField(required=True)
    with added_in(ROLE_v2_0_0) as since_v2_0:
        since_v2_0.published_in = jsl.ArrayField(jsl.StringField())
    tags = jsl.ArrayField(jsl.StringField())  # Maybe?
    architectures = jsl.ArrayField(jsl.StringField())  # Maybe?
    hashes = jsl.DictField(properties=OrderedDict((
        ("md5", jsl.StringField()),
        ("sha1", jsl.StringField()),
        ("sha256", jsl.StringField()),
    )))  # Maybe?
Beispiel #23
0
class MercatorResult(JSLSchemaBaseWithRelease):
    """JSL schema for Mercator worker results."""

    class Options(object):
        """JSL schema for Mercator worker results."""

        definition_id = "metadata"
        description = "Result of Mercator worker"

    # TODO: Any ideas how to reuse MetadataDict here ?
    with jsl.Scope(lambda v: v in (ROLE_v1_0_1, ROLE_v1_1_0)) as v1_0_1_v1_1_0:
        v1_0_1_v1_1_0.npm_shrinkwrap = jsl.OneOfField(
            [jsl.DocumentField(NpmShrinkwrap, as_ref=True), jsl.NullField()])
    with jsl.Scope(lambda v: v < ROLE_v1_1_0) as before_v1_1_0:
        before_v1_1_0.maintainers = jsl.OneOfField(
            [jsl.ArrayField(jsl.DocumentField(Maintainer, as_ref=True)), jsl.NullField()])
    with jsl.Scope(ROLE_v1_1_0) as v1_1_0:
        v1_1_0.contributors = jsl.OneOfField(
            [jsl.ArrayField(jsl.StringField()), jsl.NullField()])
        v1_1_0.maintainers = jsl.OneOfField(
            [jsl.ArrayField(jsl.StringField()), jsl.NullField()])
    with jsl.Scope(lambda v: v < ROLE_v2_0_0) as before_v2_0_0:
        # some of these may be missing in some ecosystem, so no required=True
        before_v2_0_0.author = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.bug_reporting = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.code_repository = jsl.OneOfField(
            [jsl.DocumentField(CodeRepository, as_ref=True), jsl.NullField()]
        )
        before_v2_0_0.declared_license = jsl.OneOfField(
            [jsl.StringField(), jsl.NullField()]
        )
        before_v2_0_0.dependencies = jsl.OneOfField(
            [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
        )
        before_v2_0_0.description = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.devel_dependencies = jsl.OneOfField(
            [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
        )
        # engines are NPM thingie and can contain lots of various keys
        # so we just allow pretty much anything in that dict
        before_v2_0_0.engines = jsl.OneOfField(
            [jsl.DictField(additional_properties=True), jsl.NullField()]
        )
        before_v2_0_0.files = jsl.OneOfField(
            [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
        )
        before_v2_0_0.git_head = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.homepage = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.keywords = jsl.OneOfField(
            [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
        )

        before_v2_0_0.maintainers = jsl.OneOfField(
                [jsl.ArrayField(jsl.StringField()), jsl.NullField()])

        # metadata is a rubygems thing and can contain arbitrary key/value pairs
        before_v2_0_0.metadata = jsl.OneOfField(
            [jsl.DictField(additional_properties=True), jsl.NullField()]
                )
        before_v2_0_0.name = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.platform = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
        before_v2_0_0.readme = jsl.OneOfField([jsl.StringField(), jsl.NullField()])

        before_v2_0_0.scripts = jsl.OneOfField(
            [jsl.DictField(additional_properties=True), jsl.NullField()]
        )
        before_v2_0_0.version = jsl.OneOfField([jsl.StringField(), jsl.NullField()])


# 2.0.0

    with jsl.Scope(ROLE_v2_0_0) as v2_0_0:
        v2_0_0.details = jsl.ArrayField(jsl.OneOfField(
            [jsl.DocumentField(MetadataDict, as_ref=True),
             jsl.DocumentField(NpmShrinkwrap, as_ref=True)]
        ))

# 2.1.0
    with added_in(ROLE_v2_1_0) as since_v2_1_0:
        since_v2_1_0.details = jsl.ArrayField(jsl.DocumentField(MetadataDict, as_ref=True))

# 3.1.0
    with added_in(ROLE_v3_1_0) as since_v3_1:
        since_v3_1.status = jsl.StringField(enum=["success", "error"], required=True)
        since_v3_1.summary = jsl.ArrayField(jsl.StringField(), required=True)
Beispiel #24
0
class MetadataDict(jsl.Document):
    """JSL schema for generic metadata dict in details list."""

    class Options(object):
        """JSL schema for generic metadata dict in details list."""

        definition_id = "details_metadata"
        description = "generic metadata dict in details list"

    # some of these may be missing in some ecosystem, so no required=True
    author = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    bug_reporting = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    code_repository = jsl.OneOfField(
        [jsl.DocumentField(CodeRepository, as_ref=True), jsl.NullField()]
    )

    with removed_in(ROLE_v3_2_0) as removed_in_v3_2_0:
        removed_in_v3_2_0.declared_license = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    with added_in(ROLE_v3_2_0) as added_in_v3_2_0:
        added_in_v3_2_0.declared_licenses = jsl.OneOfField([jsl.ArrayField(jsl.StringField()),
                                                            jsl.NullField()])

    dependencies = jsl.OneOfField(
        [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
    )
    description = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    devel_dependencies = jsl.OneOfField(
        [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
    )
    # engines are NPM thingie and can contain lots of various keys
    # so we just allow pretty much anything in that dict
    engines = jsl.OneOfField(
        [jsl.DictField(additional_properties=True), jsl.NullField()]
    )
    files = jsl.OneOfField(
        [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
    )
    git_head = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    homepage = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    keywords = jsl.OneOfField(
        [jsl.ArrayField(jsl.StringField()), jsl.NullField()]
    )

    # metadata is a rubygems thing and can contain arbitrary key/value pairs
    metadata = jsl.OneOfField(
        [jsl.DictField(additional_properties=True), jsl.NullField()]
    )
    name = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    platform = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    readme = jsl.OneOfField([jsl.StringField(), jsl.NullField()])
    scripts = jsl.OneOfField(
        [jsl.DictField(additional_properties=True), jsl.NullField()]
    )
    version = jsl.OneOfField([jsl.StringField(), jsl.NullField()])

    with jsl.Scope(lambda v: v in (ROLE_v1_0_1, ROLE_v1_1_0)) as v1_0_1_v1_1_0:
        v1_0_1_v1_1_0.npm_shrinkwrap = jsl.OneOfField(
            [jsl.DocumentField(NpmShrinkwrap, as_ref=True), jsl.NullField()])
    with jsl.Scope(lambda v: v < ROLE_v1_1_0) as before_v1_1_0:
        before_v1_1_0.maintainers = jsl.OneOfField(
                    [jsl.ArrayField(jsl.DocumentField(Maintainer, as_ref=True)), jsl.NullField()])
    with added_in(ROLE_v1_1_0) as since_v1_1_0:
        since_v1_1_0.contributors = jsl.OneOfField(
                    [jsl.ArrayField(jsl.StringField()), jsl.NullField()])
        since_v1_1_0.maintainers = jsl.OneOfField(
                    [jsl.ArrayField(jsl.StringField()), jsl.NullField()])
    with jsl.Scope(ROLE_v2_0_0) as v2_0_0:
        v2_0_0._system = jsl.StringField()
    with jsl.Scope(lambda v: ROLE_v2_1_0 <= v < ROLE_v3_0_0) as since_v2_1_0:
        since_v2_1_0._bayesian_dependency_tree_lock = jsl.OneOfField([
            jsl.DocumentField(LockFile, as_ref=True), jsl.NullField()
        ])
    with added_in(ROLE_v2_1_1) as since_v2_1_1:
        since_v2_1_1._tests_implemented = jsl.BooleanField()
    with added_in(ROLE_v3_0_0) as since_v3_0_0:
        since_v3_0_0.ecosystem = jsl.StringField()
        since_v3_0_0._dependency_tree_lock = jsl.OneOfField([
            jsl.DocumentField(LockFile, as_ref=True), jsl.NullField()
        ])
    with added_in(ROLE_v3_1_1) as since_v3_1_1:
        since_v3_1_1.path = jsl.OneOfField(
            [jsl.StringField(), jsl.NullField()],
            required=False
        )