History

refactor: extract shared normalizeProjectScripts into @t3tools/contracts

Move the duplicated script normalization logic (dedup-by-id + single runOnWorktreeCreate enforcement) from apps/web/src/store.ts and apps/server/src/projectRegistry.ts into packages/contracts/src/project.ts so both consumers share one canonical implementation. Applied via @cursor push command

Cursor Agent committed 8 months ago

Commit b236dcc1 parent ac05ddc3 files · +41 −66Browse files

Showing the changes to packages (1 of 3 files). Show all

Unified · Split

packages/contracts/src/project.ts+37−0
@@ -84,6 +84,43 @@ export const projectUpdateScriptsResultSchema = z.object({ · 83 unmodified lines
84 84
85export type ProjectScriptIcon = z.infer<typeof projectScriptIconSchema>;85export type ProjectScriptIcon = z.infer<typeof projectScriptIconSchema>;
86export type ProjectScript = z.infer<typeof projectScriptSchema>;86export type ProjectScript = z.infer<typeof projectScriptSchema>;
87
88/**
89 * Deduplicate scripts by ID and enforce at most one `runOnWorktreeCreate: true`
90 * flag (the first one wins). Fields are trimmed defensively so this is safe to
91 * call on data that hasn't been through Zod parsing.
92 */
93export function normalizeProjectScripts(scripts: readonly ProjectScript[]): ProjectScript[] {
94 const seenIds = new Set<string>();
95 const deduped: ProjectScript[] = [];
96 for (const script of scripts) {
97 const id = script.id.trim();
98 if (id.length === 0 || seenIds.has(id)) continue;
99 seenIds.add(id);
100 deduped.push({
101 ...script,
102 id,
103 name: script.name.trim(),
104 command: script.command.trim(),
105 });
106 }
107
108 let setupAssigned = false;
109 const normalized: ProjectScript[] = [];
110 for (const script of deduped) {
111 if (!script.runOnWorktreeCreate) {
112 normalized.push(script);
113 continue;
114 }
115 if (!setupAssigned) {
116 setupAssigned = true;
117 normalized.push(script);
118 continue;
119 }
120 normalized.push({ ...script, runOnWorktreeCreate: false });
121 }
122 return normalized;
123}
87export type ProjectRecord = z.infer<typeof projectRecordSchema>;124export type ProjectRecord = z.infer<typeof projectRecordSchema>;
88export type ProjectListResult = z.infer<typeof projectListResultSchema>;125export type ProjectListResult = z.infer<typeof projectListResultSchema>;
89export type ProjectAddInput = z.input<typeof projectAddInputSchema>;126export type ProjectAddInput = z.input<typeof projectAddInputSchema>;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t