ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Registry.WireSupport

Description

The floor every ecosystem's projection of an untrusted registry document sits on: per-entry lenient degradation, the shared name checks, and the upstream name-agreement test.

The three name checks travel together because skipping any one of them reaches an interpolated upstream URL. An ecosystem's grammar layers its own rules on top and never replaces them.

Synopsis

Per-entry lenient degradation

partitionLenientList :: InvalidEntryKind -> (Value -> Either String a) -> [(Text, Value)] -> ([(Text, a)], [InvalidEntry]) Source #

Partition a list of keyed raw entries into the ones that decode and the ones that do not, in input order. An array-shaped format pairs each element with its own key first.

Name agreement

data Projection a Source #

What an upstream document projected into, once its self-reported name has been checked. A mismatch carries no payload, so a disagreeing origin's contribution is unrepresentable.

Constructors

Projected a

The self-reported name agreed with the request, carrying what was projected.

NameMismatch Text

The document self-reported this different name (carried verbatim for the audit log).

Instances

Instances details
Show a => Show (Projection a) Source # 
Instance details

Defined in Ecluse.Core.Registry.WireSupport

Eq a => Eq (Projection a) Source # 
Instance details

Defined in Ecluse.Core.Registry.WireSupport

Methods

(==) :: Projection a -> Projection a -> Bool #

(/=) :: Projection a -> Projection a -> Bool #

checkNameAgreement :: PackageName -> PackageName -> a -> Projection a Source #

Compare through ecosystem-aware PackageName equality, never a byte compare an encoding variant could slip past. The proxy never substitutes the reported name for the requested one.

The name floor

data NameRefusal Source #

Why a name component did not clear the floor every ecosystem's grammar sits on.

Constructors

NameEmpty

The component was empty, so it names nothing.

NameNotAscii

The component carried a non-ASCII or control codepoint, which renders two names as one.

NameUnsafeComponent

The component was not a safe path component (a separator, a dot-dot, a control byte).

Instances

Instances details
Show NameRefusal Source # 
Instance details

Defined in Ecluse.Core.Registry.WireSupport

Eq NameRefusal Source # 
Instance details

Defined in Ecluse.Core.Registry.WireSupport

parseNameComponent :: Text -> Either NameRefusal Text Source #

Parse one component of a package name against the floor every ecosystem shares: non-empty, ASCII, and safe to interpolate into an upstream URL. The three travel together because one skip reaches that URL.

nameComponentWith :: Text -> (Text -> Bool) -> Text -> Either ParseError Text Source #

Clear the shared floor and then an ecosystem's own grammar. The noun names the component in every refusal, so each ecosystem keeps its own wording ("npm name component").

withinNameLimit :: Text -> Int -> Text -> Either ParseError () Source #

Refuse a name over an ecosystem's own cap, which the noun names in the refusal text. compareLength stops at the cap without measuring the whole input.