MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / runAdd

Function runAdd

packages/cli/src/commands/add.ts:152–220  ·  view source on GitHub ↗
(opts: RunAddArgs)

Source from the content-addressed store, hash-verified

150}
151
152export async function runAdd(opts: RunAddArgs): Promise<RunAddResult> {
153 const projectDir = resolve(opts.projectDir);
154
155 // 1. Load (or write default) project config.
156 let config = loadProjectConfig(projectDir);
157 const hasConfig = existsSync(projectConfigPath(projectDir));
158 if (!hasConfig && existsSync(resolve(projectDir, "index.html"))) {
159 writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
160 config = DEFAULT_PROJECT_CONFIG;
161 }
162
163 // 2. Resolve the requested item and its transitive registryDependencies.
164 // The list comes back topologically sorted: dependencies first, the
165 // requested item last.
166 let resolved: RegistryItem[];
167 try {
168 resolved = await resolveItemWithDependencies(opts.name, { baseUrl: config.registry });
169 } catch (err) {
170 throw new AddError(err instanceof Error ? err.message : String(err), "unknown-item");
171 }
172 // `resolveItemWithDependencies` always pushes the requested item last (or throws),
173 // so the final element is the item the user asked for.
174 const item = resolved[resolved.length - 1]!;
175
176 if (item.type === "hyperframes:example") {
177 throw new AddError(
178 `"${item.name}" is an example — use \`hyperframes init <dir> --example ${item.name}\` instead.`,
179 "example-type",
180 );
181 }
182
183 // 3. Compatibility-gate every item we're about to install (dependencies
184 // included) before writing anything.
185 const warnings = assertCompatibleOrThrow(resolved, opts.cliVersion);
186
187 // 4. Remap targets per project config — each item by its own type.
188 const installPlan: RegistryItem[] = resolved.map((resolvedItem) => ({
189 ...resolvedItem,
190 files: resolvedItem.files.map((f) => ({
191 ...f,
192 target: remapTarget(resolvedItem, f.target, config.paths),
193 })),
194 }));
195
196 // 5. Install — dependencies first, requested item last.
197 const written = await installAll(installPlan, projectDir, config.registry);
198
199 // 6. Build include snippet + clipboard copy for the requested item.
200 const itemForInstall = installPlan[installPlan.length - 1]!;
201 const primaryFile =
202 itemForInstall.files.find((f) => f.type === "hyperframes:snippet") ??
203 itemForInstall.files.find((f) => f.type === "hyperframes:composition") ??
204 itemForInstall.files[0];
205 const snippetTargetRel = primaryFile?.target ?? "";
206 const snippet = buildSnippet(item, snippetTargetRel);
207 const clipboardCopied = !opts.skipClipboard && snippet ? copyToClipboard(snippet) : false;
208
209 return {

Callers 3

runFunction · 0.85
runFunction · 0.85
add.test.tsFile · 0.85

Calls 11

resolveFunction · 0.85
loadProjectConfigFunction · 0.85
projectConfigPathFunction · 0.85
writeProjectConfigFunction · 0.85
assertCompatibleOrThrowFunction · 0.85
remapTargetFunction · 0.85
installAllFunction · 0.85
buildSnippetFunction · 0.85
copyToClipboardFunction · 0.85
findMethod · 0.65

Tested by

no test coverage detected