Issue #3620166: Add the paragraphs shape
Paragraphs are the most divergent thing in this codebase - four handlers on one site, twenty-nine on another, thirty-four on the third, nine types in common - and that is exactly why this shape is small. What differs between the sites is what a paragraph type contains, and that is a structure per type, filed separately. What does not differ is the frame around them, and the frame is what this is: a list, in field order, of published paragraphs, each rendered by the structure of its own type, each saying which type it is.
Every fragment carries paragraph_type, under the name the module was written against rather than the machine name of this site. A list of heterogeneous objects cannot be read without a discriminator, every front end built on this module switches on that key, and a site that renamed a type should not rename it in everybody's front end.
A type that nothing describes is visible rather than silent: its fragment says so. The gap is then found by whoever reads the response instead of by whoever eventually notices a block missing from a page. A type that is described and rendered nothing is a different thing - an editor left the fields empty - and that paragraph is simply left out, because it is not a gap in the model.
hook_myrest_structure_alter() fires from here as well as from the paragraph builder, and an implementation cannot tell the two apart. The hook is documented as receiving the empty structure of a type this module has no builder for, which is exactly the case above, so a site answering for a type of its own goes on answering for it as the resources move onto the shape library.
An unpublished paragraph is left out. That is not a permission question: a paragraph belongs to the entity holding it and is not addressable on its own, which is why this shape does not check access where the card shape must.
Closes #3620166