/**
 * Saved-view **scope** — the structured location a saved view points at.
 *
 * Saved-Views architecture, Phase 2. A view's scope decouples the durable
 * lens (visualization + filters + sort) from *where* it looks. Three kinds
 * ship in P2 (a fourth, boards, is reserved):
 *   - `recent` — the cross-folder Recent aggregate (all accessible folders).
 *   - `type:<entityType>` — a single-type aggregate across folders.
 *   - `folder:<id>` — a specific folder, keyed by its **stable sidecar id**
 *     (D2) so the view survives folder rename / move. The path is never the
 *     stored key.
 *
 * This module is the single `parseScope()` validator with an explicit error
 * policy (§4a): an unrecognized / malformed scope string parses to
 * `{ kind: 'invalid' }` rather than throwing, so a corrupt row can never blank
 * the sidebar or a route — the caller renders a "this view's location is gone"
 * state instead.
 *
 * Pure + framework-free (no fs, no db, no web runtime) so it is shared by the
 * server route (which resolves `folder:<id>` → repo/path against the
 * filesystem) and the web client (which consumes the already-resolved scope),
 * and runs in the `web-unit` vitest project via the `@core/view-scope` alias.
 */
/** The stored-scope string for the Recent aggregate. */
export const VIEW_SCOPE_RECENT = 'recent';
/**
 * Parse a stored scope string. Never throws. `null` / `''` / `'recent'` /
 * `'all'` all map to Recent (the universal default); anything unrecognized or
 * empty-after-prefix maps to `{ kind: 'invalid' }`.
 */
export function parseScope(raw) {
    if (!raw)
        return { kind: 'recent' };
    const s = raw.trim();
    if (s === '' || s === VIEW_SCOPE_RECENT || s === 'all')
        return { kind: 'recent' };
    if (s.startsWith('type:')) {
        const entityType = s.slice('type:'.length).trim();
        return entityType ? { kind: 'type', entityType } : { kind: 'invalid', raw };
    }
    if (s.startsWith('folder:')) {
        const folderId = s.slice('folder:'.length).trim();
        return folderId ? { kind: 'folder', folderId } : { kind: 'invalid', raw };
    }
    return { kind: 'invalid', raw };
}
/** Build the stored scope string for a type-scoped view. */
export function buildTypeScope(entityType) {
    return `type:${entityType}`;
}
/** Build the stored scope string for a folder-scoped view from its stable id. */
export function buildFolderScope(folderId) {
    return `folder:${folderId}`;
}
/** Validate that a SaveScope is well-formed before persisting. */
export function isValidSaveScope(s) {
    if (!s || typeof s !== 'object')
        return false;
    const scope = s;
    switch (scope.kind) {
        case 'recent':
            return true;
        case 'type':
            return typeof scope.entityType === 'string' && scope.entityType.trim().length > 0;
        case 'folder':
            return typeof scope.repo === 'string' && scope.repo.length > 0 && typeof scope.folderPath === 'string';
        default:
            return false;
    }
}
//# sourceMappingURL=view-scope.js.map