@swell/cli
Version:
Swell's command line interface/utility
116 lines (115 loc) • 5.03 kB
TypeScript
import { GroupInfo } from './table.js';
export interface NotificationRecord {
api?: string;
app_id?: string;
enabled?: boolean;
id?: string;
model?: string;
name?: string;
v2?: boolean;
}
export type ParsedNotificationKey = {
id: string;
kind: 'hex';
} | {
id: string;
kind: 'system_id';
} | {
kind: 'app_full';
model: string;
name: string;
slug: string;
} | {
kind: 'app_short';
name: string;
slug: string;
} | {
kind: 'bare';
name: string;
} | {
input: string;
kind: 'invalid';
};
/**
* Translate a stored model path into its display form.
*
* apps/<own-hex>/<x> → <x> (own-app prefix is implicit in the slug)
* apps/<other-hex>/<x> → apps/<other-slug>/<x>
* apps/<unknown-hex>/<x> → unchanged (preserve a paste-back form)
* <built-in-model> → unchanged
*
* Stripping `apps/<own>/` keeps the common case readable; the rare collision
* with a same-named built-in (e.g. an app model literally named
* `subscriptions`) is recovered by `expandModelCandidates` at lookup time.
*/
export declare function normalizeModelForDisplay(model: string, ownAppId: string | undefined, appSlugById: Record<string, string>): string;
/**
* Produce the column-1 paste-back key for a notification.
*
* System (no app_id): record.id verbatim — already in `com.<model>.<name>` form.
* App with model+name: `app.<slug>.<model-display>.<name>`
* Anything else: record.id (degenerate, no meaningful slug)
*
* Notification identity is `(api, model, name, app_id?)`; collapsing on
* `(app_id, name)` alone caused two `notify_me.back-in-stock` rows
* (different `model`) to render identically.
*/
export declare function formatNotificationKey(record: NotificationRecord, appSlugById: Record<string, string>): string;
/**
* Group a notification record. System rows (no app_id) are not store data —
* they belong to the platform and render under a `system` divider at the top.
*/
export declare function groupNotificationRecord(record: NotificationRecord, appSlugById: Record<string, string>): GroupInfo;
/**
* Classify a notification identifier. The base `classifyIdentifier` collapses
* every dot-segment after `app.<part>.` into `name`, which loses the model.
* Notifications need a model-aware split, so they bypass the base classifier.
*
* Recognised shapes:
* - 24-char hex → hex (delegate to base GET-by-id)
* - com.<rest> → system_id (canonical platform id)
* - app.<slug>.<model>.<name> → app_full (triplet lookup)
* - app.<slug>.<name> → app_short (3-part legacy; ambiguous)
* - bare <name> → bare (requires --app= scope; ambiguous)
* - anything else → invalid
*
* Multi-segment names (e.g. `unpaid.v2`) only appear in system notifications,
* which arrive via the `com.*` form and never go through `app.*` parsing.
*/
export declare function parseNotificationKey(input: string): ParsedNotificationKey;
/**
* Render the disambiguation error body when a `(app_id, name)` query returns
* multiple notifications. Caller fetches with `limit = displayLimit + 1` so
* we can detect overflow without paging through the whole result set; if
* `results.length > displayLimit`, the surplus rows are dropped and a hint
* line is appended directing the user to the full key form.
*/
export declare function formatDisambiguationError(results: NotificationRecord[], appSlugById: Record<string, string>, identifier: string, displayLimit?: number): string;
/**
* Build the `template` value used on send records at `/notifications` from a
* manifest record's fields. Three shapes:
*
* System (no app_id): <model>.<name>
* App on a standard model: app_<app_id>.<model>.<name>
* App on a custom (apps/<hex>/x) model: app_<app_id>.apps_<hex>_<x>.<name>
*
* The custom-model branch transforms slashes to underscores in the model
* segment.
*
* V2 system notifications have `name` literally ending in `.v2` (mirroring the
* `id` and the `v2: true` flag), but the send-record `template` strips that
* suffix. App notifications carry `v2: true` without the suffix in `name`, so
* they pass through unchanged.
*
* Returns undefined when `model` or `name` is missing.
*/
export declare function buildNotificationTemplate(record: NotificationRecord): string | undefined;
/**
* Expand a display-form model into the candidate stored values to try at
* lookup time. A bare display token can mean either:
* - the literal built-in model (e.g. `subscriptions`)
* - an own-app model whose `apps/<own>/` prefix was stripped for display
* so we try both. `apps/<slug>/x` is resolved to `apps/<hex>/x`; an already-hex
* `apps/<hex>/x` passes through unchanged.
*/
export declare function expandModelCandidates(modelDisplay: string, appId: string, resolveAppId: (slug: string) => Promise<string>): Promise<string[]>;