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
8484
8585 export type ProjectScriptIcon = z.infer<typeof projectScriptIconSchema>;
8686 export 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+ */
93+export 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+}
87124 export type ProjectRecord = z.infer<typeof projectRecordSchema>;
88125 export type ProjectListResult = z.infer<typeof projectListResultSchema>;
89126 export 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