@krizaka/organize
A name, an avatar, tags and collections for any entity, with a conformance kit.
Install
npm install @krizaka/organizeA name, an avatar, a description, tags, collections and an undeletable default collection for any entity of a Krizaka product
(ADR-006). No ORM, no framework, no image library: you pass a query function and, for uploaded avatars, an AvatarProcessor and an ObjectStore.
import { createOrganize, organizeMigration } from "@krizaka/organize";
const schema = { defaultName: { fr: "Mes boutiques", en: "My shops" }, kinds: { shop: { table: "shops" } } };
await db.query(organizeMigration(schema)); // once, in your migrations
const organize = createOrganize({ query: (sql, params) => pool.query(sql, params).then((r) => r.rows), schema, images });
await organize.collections.create(owner, { name: "Quartier Est" });
await organize.profile("shop").rename(owner, shopId, "Salon Cèdre");
await organize.tags.assign(owner, "shop", shopId, [tagId]);- The invariants are the database's: one default collection per owner (exclusion constraint + deferred trigger), never deleted while its owner exists, created with the owner in its language, and every entity given no collection falls into it.
- Refusals are
OrganizeErrorwith a stablecodeandstatus(DEFAULT_COLLECTION,NAME_TAKEN,AVATAR_NOT_ALLOWED…): a product maps them to its own answers. - Pure rules for the URL:
parseTagsParam,toggleTag,tagsHref.
Exports
The 33 names the package exports, read from its types.
| Name | Kind | What it is |
|---|---|---|
Avatar | type | An avatar: one of a set (a seed the UI draws) or an uploaded image (served at an address that carries its version). |
AVATAR_KIND | constant | |
AvatarImageError | class | The processor refuses an image with a stable reason; the service turns it into AVATAR_UNREADABLE or a pass-through error. |
AvatarProcessor | type | Makes an uploaded image an avatar: checked, square, upright, without metadata. |
AvatarRules | type | |
cleanDescription | function | A description: trimmed, at most DESCRIPTION_MAX characters; empty means none (null). |
cleanName | function | What an entity or a collection may be called: spaces collapsed, trimmed, 1 to NAME_MAX characters; null when it is not. |
Collection | type | |
createOrganize | function | « organize »: for every kind a product declares, a name, a description, an avatar, tags and a place in a collection; collections with an undeletable default… |
DEFAULTS | constant | |
DESCRIPTION_MAX | constant | |
ident | function | A SQL identifier from the product's declaration: lower-case letters, digits, underscore. |
isId | function | |
isTagColor | function | |
KindDecl | type | |
NAME_MAX | constant | The pure rules of « organize »: names, tag colours, ids, and the tags parameter of a view (the URL is the state). |
ObjectStore | type | What an uploaded avatar is kept in: the same shape as a document store (put, get, delete), so a product passes the one it has. |
Organize | type | |
ORGANIZE_CODE | constant | Stable refusal codes: a product turns them into its own HTTP answers and messages. |
OrganizeCode | type | |
OrganizeDeps | type | |
OrganizeError | class | |
organizeMigration | function | |
OrganizeSchema | type | |
parseTagsParam | function | ?tags=a,b (or the repeated form) → the ids, in order, without duplicates and without anything that is not an id. |
Profile | type | |
Query | type | Runs one SQL statement with its parameters and returns the rows. |
storedAvatarKey | function | Where an uploaded avatar lives in the product's object store (a signed link to it is the product's to make). |
Tag | type | |
TAG_COLORS | constant | Tag colours are NAMES that the UI maps to its tokens — never a hex in the database. |
TagColor | type | |
tagsHref | function | The same path with another set of tags: the URL is the state. |
toggleTag | function |
Package
Changelog
0.3.0
Minor changes
legacyAvatarKey: a product's older image keys are read and deleted as a fallback, never written.
0.2.0
Minor changes
storedAvatarKey(where an uploaded avatar lives in the object store, so a product can sign a link to it) andcollectionTags(the collections' tag join table, for a product that already has one under another name).
0.1.0
Minor changes
- First release: the pure rules of « organize » — names, descriptions, tag colours, ids and the
tagsURL parameter. - A kind may say how an entity is its owner's (
owns) when its table has no owner column, a collection takes a product's extra columns on creation, and tagging needs no name or avatar column. - The service: collections with an undeletable default one (invariants in the database), tags, and the name, description, avatar (a set or an uploaded image behind two ports) and collection of any declared kind; the migration generator; tests against PostgreSQL.