@swell/cli
Version:
Swell's command line interface/utility
77 lines (76 loc) • 2.85 kB
JavaScript
/**
* Parse a content view identifier of the form `app.<appPart>.<name>` or
* `custom.<source>.<name>`. Returns null for anything that doesn't match.
*/
export function parseContentId(id) {
const match = id.match(/^(app|custom)\.([^.]+)\.(.+)$/);
if (!match)
return null;
return {
prefix: match[1],
middle: match[2],
name: match[3],
};
}
/**
* Produce the column-1 paste-back key for a content view. Rewrites
* `app.<hex>.<name>` to `app.<slug>.<name>` when the slug is known; passes
* `custom.*` and unresolvable app ids through unchanged (both remain valid
* paste-back forms against the detail endpoint).
*/
export function resolveContentKey(id, appSlugById) {
const parsed = parseContentId(id);
if (!parsed)
return id;
if (parsed.prefix === 'custom')
return id;
const slug = appSlugById[parsed.middle] ?? parsed.middle;
return `app.${slug}.${parsed.name}`;
}
/**
* Group a content view record for the vertical split. Records with no
* `app_id` belong to the platform's `custom.*` source and land in a
* single `<custom>` section at the top of the output.
*/
export function groupContentRecord(record, appSlugById) {
if (!record.app_id) {
return { slug: '<custom>', label: 'custom', order: 0 };
}
const resolved = appSlugById[record.app_id];
if (!resolved) {
return { slug: '<not resolved>', order: 2 };
}
return { slug: resolved };
}
/**
* Translate a user-supplied content identifier into the unresolved API
* form. Accepts:
* - `custom.<source>.<name>` → unchanged
* - `app.<hex>.<name>` → unchanged (already unresolved form)
* - `app.<slug>.<name>` → slug resolved to hex
* - bare `<name>` → combined with scope.appId to `app.<hex>.<name>`
*
* `resolveAppId` is injected so this function is testable without a live API.
*/
export async function reverseResolveContentId(identifier, scope, resolveAppId) {
if (/^custom\.[^.]+\..+$/.test(identifier)) {
return identifier;
}
if (/^app\.[\da-f]{24}\..+$/i.test(identifier)) {
return identifier;
}
const appMatch = identifier.match(/^app\.([^.]+)\.(.+)$/);
if (appMatch) {
const appId = await resolveAppId(appMatch[1]);
return `app.${appId}.${appMatch[2]}`;
}
if (/^[\w-]+$/i.test(identifier)) {
if (!scope.appId) {
throw new Error(`Bare content name '${identifier}' requires --app=<slug> or --app=. to scope. ` +
`Alternatively, pass a full identifier (app.<app>.<name> or custom.<source>.<name>).`);
}
return `app.${scope.appId}.${identifier}`;
}
throw new Error(`Invalid content identifier '${identifier}'. ` +
`Expected bare name, app.<app>.<name>, or custom.<source>.<name>.`);
}