assistant-ui 0.0.79 → 0.0.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts +3 -0
- package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts.map +1 -0
- package/dist/codemods/v0-12/primitive-if-to-aui-if.js +308 -0
- package/dist/codemods/v0-12/primitive-if-to-aui-if.js.map +1 -0
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +1 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/lib/create-from-example.d.ts.map +1 -1
- package/dist/lib/create-from-example.js +2 -0
- package/dist/lib/create-from-example.js.map +1 -1
- package/dist/lib/upgrade.d.ts.map +1 -1
- package/dist/lib/upgrade.js +1 -0
- package/dist/lib/upgrade.js.map +1 -1
- package/package.json +4 -4
- package/src/codemods/v0-12/__tests__/assistant-api-to-aui.test.ts +6 -6
- package/src/codemods/v0-12/__tests__/primitive-if-to-aui-if.test.ts +839 -0
- package/src/codemods/v0-12/primitive-if-to-aui-if.ts +355 -0
- package/src/commands/create.ts +1 -2
- package/src/lib/create-from-example.ts +2 -0
- package/src/lib/upgrade.ts +1 -0
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import jscodeshift, { API } from "jscodeshift";
|
|
3
|
+
import transform from "../primitive-if-to-aui-if";
|
|
4
|
+
|
|
5
|
+
const j = jscodeshift.withParser("tsx");
|
|
6
|
+
|
|
7
|
+
function applyTransform(source: string): string | null {
|
|
8
|
+
const fileInfo = {
|
|
9
|
+
path: "test.tsx",
|
|
10
|
+
source,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const api: API = {
|
|
14
|
+
jscodeshift: j,
|
|
15
|
+
j,
|
|
16
|
+
stats: () => {},
|
|
17
|
+
report: () => {},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return transform(fileInfo, api, {});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe("primitive-if-to-aui-if", () => {
|
|
24
|
+
// ── ThreadPrimitive.If ─────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
describe("ThreadPrimitive.If", () => {
|
|
27
|
+
it("should migrate <ThreadPrimitive.If empty> to AuiIf", () => {
|
|
28
|
+
const input = `
|
|
29
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
30
|
+
|
|
31
|
+
function MyComponent() {
|
|
32
|
+
return (
|
|
33
|
+
<ThreadPrimitive.If empty>
|
|
34
|
+
<div>Empty</div>
|
|
35
|
+
</ThreadPrimitive.If>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
const expected = `
|
|
41
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
42
|
+
|
|
43
|
+
function MyComponent() {
|
|
44
|
+
return (
|
|
45
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
46
|
+
<div>Empty</div>
|
|
47
|
+
</AuiIf>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should migrate <ThreadPrimitive.If empty={false}>", () => {
|
|
56
|
+
const input = `
|
|
57
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
58
|
+
|
|
59
|
+
function MyComponent() {
|
|
60
|
+
return (
|
|
61
|
+
<ThreadPrimitive.If empty={false}>
|
|
62
|
+
<div>Not empty</div>
|
|
63
|
+
</ThreadPrimitive.If>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
const expected = `
|
|
69
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
70
|
+
|
|
71
|
+
function MyComponent() {
|
|
72
|
+
return (
|
|
73
|
+
<AuiIf condition={(s) => !s.thread.isEmpty}>
|
|
74
|
+
<div>Not empty</div>
|
|
75
|
+
</AuiIf>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("should migrate <ThreadPrimitive.If running>", () => {
|
|
84
|
+
const input = `
|
|
85
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
86
|
+
|
|
87
|
+
function MyComponent() {
|
|
88
|
+
return (
|
|
89
|
+
<ThreadPrimitive.If running>
|
|
90
|
+
<div>Running</div>
|
|
91
|
+
</ThreadPrimitive.If>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
const expected = `
|
|
97
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
98
|
+
|
|
99
|
+
function MyComponent() {
|
|
100
|
+
return (
|
|
101
|
+
<AuiIf condition={(s) => s.thread.isRunning}>
|
|
102
|
+
<div>Running</div>
|
|
103
|
+
</AuiIf>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should migrate <ThreadPrimitive.If running={false}>", () => {
|
|
112
|
+
const input = `
|
|
113
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
114
|
+
|
|
115
|
+
function MyComponent() {
|
|
116
|
+
return (
|
|
117
|
+
<ThreadPrimitive.If running={false}>
|
|
118
|
+
<div>Not running</div>
|
|
119
|
+
</ThreadPrimitive.If>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
`;
|
|
123
|
+
|
|
124
|
+
const expected = `
|
|
125
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
126
|
+
|
|
127
|
+
function MyComponent() {
|
|
128
|
+
return (
|
|
129
|
+
<AuiIf condition={(s) => !s.thread.isRunning}>
|
|
130
|
+
<div>Not running</div>
|
|
131
|
+
</AuiIf>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should migrate <ThreadPrimitive.If disabled>", () => {
|
|
140
|
+
const input = `
|
|
141
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
142
|
+
|
|
143
|
+
function MyComponent() {
|
|
144
|
+
return (
|
|
145
|
+
<ThreadPrimitive.If disabled>
|
|
146
|
+
<div>Disabled</div>
|
|
147
|
+
</ThreadPrimitive.If>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
|
|
152
|
+
const expected = `
|
|
153
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
154
|
+
|
|
155
|
+
function MyComponent() {
|
|
156
|
+
return (
|
|
157
|
+
<AuiIf condition={(s) => s.thread.isDisabled}>
|
|
158
|
+
<div>Disabled</div>
|
|
159
|
+
</AuiIf>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
|
|
164
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should handle self-closing ThreadPrimitive.If", () => {
|
|
168
|
+
const input = `
|
|
169
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
170
|
+
|
|
171
|
+
function MyComponent() {
|
|
172
|
+
return <ThreadPrimitive.If empty />;
|
|
173
|
+
}
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
const expected = `
|
|
177
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
178
|
+
|
|
179
|
+
function MyComponent() {
|
|
180
|
+
return <AuiIf condition={(s) => s.thread.isEmpty} />;
|
|
181
|
+
}
|
|
182
|
+
`;
|
|
183
|
+
|
|
184
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// ── MessagePrimitive.If ────────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
describe("MessagePrimitive.If", () => {
|
|
191
|
+
it("should migrate <MessagePrimitive.If user>", () => {
|
|
192
|
+
const input = `
|
|
193
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
194
|
+
|
|
195
|
+
function MyComponent() {
|
|
196
|
+
return (
|
|
197
|
+
<MessagePrimitive.If user>
|
|
198
|
+
<div>User message</div>
|
|
199
|
+
</MessagePrimitive.If>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
`;
|
|
203
|
+
|
|
204
|
+
const expected = `
|
|
205
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
206
|
+
|
|
207
|
+
function MyComponent() {
|
|
208
|
+
return (
|
|
209
|
+
<AuiIf condition={(s) => s.message.role === "user"}>
|
|
210
|
+
<div>User message</div>
|
|
211
|
+
</AuiIf>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
`;
|
|
215
|
+
|
|
216
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("should migrate <MessagePrimitive.If assistant>", () => {
|
|
220
|
+
const input = `
|
|
221
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
222
|
+
|
|
223
|
+
function MyComponent() {
|
|
224
|
+
return (
|
|
225
|
+
<MessagePrimitive.If assistant>
|
|
226
|
+
<div>Assistant message</div>
|
|
227
|
+
</MessagePrimitive.If>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
`;
|
|
231
|
+
|
|
232
|
+
const expected = `
|
|
233
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
234
|
+
|
|
235
|
+
function MyComponent() {
|
|
236
|
+
return (
|
|
237
|
+
<AuiIf condition={(s) => s.message.role === "assistant"}>
|
|
238
|
+
<div>Assistant message</div>
|
|
239
|
+
</AuiIf>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
`;
|
|
243
|
+
|
|
244
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("should migrate <MessagePrimitive.If copied>", () => {
|
|
248
|
+
const input = `
|
|
249
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
250
|
+
|
|
251
|
+
function MyComponent() {
|
|
252
|
+
return (
|
|
253
|
+
<MessagePrimitive.If copied>
|
|
254
|
+
<CheckIcon />
|
|
255
|
+
</MessagePrimitive.If>
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
`;
|
|
259
|
+
|
|
260
|
+
const expected = `
|
|
261
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
262
|
+
|
|
263
|
+
function MyComponent() {
|
|
264
|
+
return (
|
|
265
|
+
<AuiIf condition={(s) => s.message.isCopied}>
|
|
266
|
+
<CheckIcon />
|
|
267
|
+
</AuiIf>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
`;
|
|
271
|
+
|
|
272
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should migrate <MessagePrimitive.If copied={false}>", () => {
|
|
276
|
+
const input = `
|
|
277
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
278
|
+
|
|
279
|
+
function MyComponent() {
|
|
280
|
+
return (
|
|
281
|
+
<MessagePrimitive.If copied={false}>
|
|
282
|
+
<CopyIcon />
|
|
283
|
+
</MessagePrimitive.If>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
`;
|
|
287
|
+
|
|
288
|
+
const expected = `
|
|
289
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
290
|
+
|
|
291
|
+
function MyComponent() {
|
|
292
|
+
return (
|
|
293
|
+
<AuiIf condition={(s) => !s.message.isCopied}>
|
|
294
|
+
<CopyIcon />
|
|
295
|
+
</AuiIf>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
`;
|
|
299
|
+
|
|
300
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("should migrate <MessagePrimitive.If speaking>", () => {
|
|
304
|
+
const input = `
|
|
305
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
306
|
+
|
|
307
|
+
function MyComponent() {
|
|
308
|
+
return (
|
|
309
|
+
<MessagePrimitive.If speaking>
|
|
310
|
+
<StopIcon />
|
|
311
|
+
</MessagePrimitive.If>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
`;
|
|
315
|
+
|
|
316
|
+
const expected = `
|
|
317
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
318
|
+
|
|
319
|
+
function MyComponent() {
|
|
320
|
+
return (
|
|
321
|
+
<AuiIf condition={(s) => s.message.speech != null}>
|
|
322
|
+
<StopIcon />
|
|
323
|
+
</AuiIf>
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
`;
|
|
327
|
+
|
|
328
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it("should migrate <MessagePrimitive.If speaking={false}>", () => {
|
|
332
|
+
const input = `
|
|
333
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
334
|
+
|
|
335
|
+
function MyComponent() {
|
|
336
|
+
return (
|
|
337
|
+
<MessagePrimitive.If speaking={false}>
|
|
338
|
+
<SpeakIcon />
|
|
339
|
+
</MessagePrimitive.If>
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
`;
|
|
343
|
+
|
|
344
|
+
const expected = `
|
|
345
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
346
|
+
|
|
347
|
+
function MyComponent() {
|
|
348
|
+
return (
|
|
349
|
+
<AuiIf condition={(s) => !s.message.speech != null}>
|
|
350
|
+
<SpeakIcon />
|
|
351
|
+
</AuiIf>
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
`;
|
|
355
|
+
|
|
356
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it("should migrate <MessagePrimitive.If last>", () => {
|
|
360
|
+
const input = `
|
|
361
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
362
|
+
|
|
363
|
+
function MyComponent() {
|
|
364
|
+
return (
|
|
365
|
+
<MessagePrimitive.If last>
|
|
366
|
+
<div>Last message</div>
|
|
367
|
+
</MessagePrimitive.If>
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
`;
|
|
371
|
+
|
|
372
|
+
const expected = `
|
|
373
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
374
|
+
|
|
375
|
+
function MyComponent() {
|
|
376
|
+
return (
|
|
377
|
+
<AuiIf condition={(s) => s.message.isLast}>
|
|
378
|
+
<div>Last message</div>
|
|
379
|
+
</AuiIf>
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
`;
|
|
383
|
+
|
|
384
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it("should migrate <MessagePrimitive.If hasBranches>", () => {
|
|
388
|
+
const input = `
|
|
389
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
390
|
+
|
|
391
|
+
function MyComponent() {
|
|
392
|
+
return (
|
|
393
|
+
<MessagePrimitive.If hasBranches>
|
|
394
|
+
<BranchPicker />
|
|
395
|
+
</MessagePrimitive.If>
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
`;
|
|
399
|
+
|
|
400
|
+
const expected = `
|
|
401
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
402
|
+
|
|
403
|
+
function MyComponent() {
|
|
404
|
+
return (
|
|
405
|
+
<AuiIf condition={(s) => s.message.branchCount >= 2}>
|
|
406
|
+
<BranchPicker />
|
|
407
|
+
</AuiIf>
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
`;
|
|
411
|
+
|
|
412
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it("should migrate <MessagePrimitive.If hasAttachments>", () => {
|
|
416
|
+
const input = `
|
|
417
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
418
|
+
|
|
419
|
+
function MyComponent() {
|
|
420
|
+
return (
|
|
421
|
+
<MessagePrimitive.If hasAttachments>
|
|
422
|
+
<Attachments />
|
|
423
|
+
</MessagePrimitive.If>
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
`;
|
|
427
|
+
|
|
428
|
+
const expected = `
|
|
429
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
430
|
+
|
|
431
|
+
function MyComponent() {
|
|
432
|
+
return (
|
|
433
|
+
<AuiIf condition={(s) => s.message.role === "user" && !!s.message.attachments?.length}>
|
|
434
|
+
<Attachments />
|
|
435
|
+
</AuiIf>
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
`;
|
|
439
|
+
|
|
440
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it("should migrate <MessagePrimitive.If hasContent>", () => {
|
|
444
|
+
const input = `
|
|
445
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
446
|
+
|
|
447
|
+
function MyComponent() {
|
|
448
|
+
return (
|
|
449
|
+
<MessagePrimitive.If hasContent>
|
|
450
|
+
<Content />
|
|
451
|
+
</MessagePrimitive.If>
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
`;
|
|
455
|
+
|
|
456
|
+
const expected = `
|
|
457
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
458
|
+
|
|
459
|
+
function MyComponent() {
|
|
460
|
+
return (
|
|
461
|
+
<AuiIf condition={(s) => s.message.parts.length > 0}>
|
|
462
|
+
<Content />
|
|
463
|
+
</AuiIf>
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
`;
|
|
467
|
+
|
|
468
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it("should migrate <MessagePrimitive.If lastOrHover>", () => {
|
|
472
|
+
const input = `
|
|
473
|
+
import { MessagePrimitive } from "@assistant-ui/react";
|
|
474
|
+
|
|
475
|
+
function MyComponent() {
|
|
476
|
+
return (
|
|
477
|
+
<MessagePrimitive.If lastOrHover>
|
|
478
|
+
<ActionBar />
|
|
479
|
+
</MessagePrimitive.If>
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
`;
|
|
483
|
+
|
|
484
|
+
const expected = `
|
|
485
|
+
import { MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
486
|
+
|
|
487
|
+
function MyComponent() {
|
|
488
|
+
return (
|
|
489
|
+
<AuiIf condition={(s) => s.message.isHovering || s.message.isLast}>
|
|
490
|
+
<ActionBar />
|
|
491
|
+
</AuiIf>
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
`;
|
|
495
|
+
|
|
496
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
// ── ComposerPrimitive.If ──────────────────────────────────────────
|
|
501
|
+
|
|
502
|
+
describe("ComposerPrimitive.If", () => {
|
|
503
|
+
it("should migrate <ComposerPrimitive.If editing>", () => {
|
|
504
|
+
const input = `
|
|
505
|
+
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
506
|
+
|
|
507
|
+
function MyComponent() {
|
|
508
|
+
return (
|
|
509
|
+
<ComposerPrimitive.If editing>
|
|
510
|
+
<div>Editing</div>
|
|
511
|
+
</ComposerPrimitive.If>
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
`;
|
|
515
|
+
|
|
516
|
+
const expected = `
|
|
517
|
+
import { ComposerPrimitive, AuiIf } from "@assistant-ui/react";
|
|
518
|
+
|
|
519
|
+
function MyComponent() {
|
|
520
|
+
return (
|
|
521
|
+
<AuiIf condition={(s) => s.composer.isEditing}>
|
|
522
|
+
<div>Editing</div>
|
|
523
|
+
</AuiIf>
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
`;
|
|
527
|
+
|
|
528
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it("should migrate <ComposerPrimitive.If editing={false}>", () => {
|
|
532
|
+
const input = `
|
|
533
|
+
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
534
|
+
|
|
535
|
+
function MyComponent() {
|
|
536
|
+
return (
|
|
537
|
+
<ComposerPrimitive.If editing={false}>
|
|
538
|
+
<div>Not editing</div>
|
|
539
|
+
</ComposerPrimitive.If>
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
`;
|
|
543
|
+
|
|
544
|
+
const expected = `
|
|
545
|
+
import { ComposerPrimitive, AuiIf } from "@assistant-ui/react";
|
|
546
|
+
|
|
547
|
+
function MyComponent() {
|
|
548
|
+
return (
|
|
549
|
+
<AuiIf condition={(s) => !s.composer.isEditing}>
|
|
550
|
+
<div>Not editing</div>
|
|
551
|
+
</AuiIf>
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
`;
|
|
555
|
+
|
|
556
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it("should migrate <ComposerPrimitive.If dictation>", () => {
|
|
560
|
+
const input = `
|
|
561
|
+
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
562
|
+
|
|
563
|
+
function MyComponent() {
|
|
564
|
+
return (
|
|
565
|
+
<ComposerPrimitive.If dictation>
|
|
566
|
+
<div>Dictating</div>
|
|
567
|
+
</ComposerPrimitive.If>
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
`;
|
|
571
|
+
|
|
572
|
+
const expected = `
|
|
573
|
+
import { ComposerPrimitive, AuiIf } from "@assistant-ui/react";
|
|
574
|
+
|
|
575
|
+
function MyComponent() {
|
|
576
|
+
return (
|
|
577
|
+
<AuiIf condition={(s) => s.composer.dictation != null}>
|
|
578
|
+
<div>Dictating</div>
|
|
579
|
+
</AuiIf>
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
`;
|
|
583
|
+
|
|
584
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// ── ThreadPrimitive.Empty ───────────────────────────────────────────
|
|
589
|
+
|
|
590
|
+
describe("ThreadPrimitive.Empty", () => {
|
|
591
|
+
it("should migrate <ThreadPrimitive.Empty> to AuiIf", () => {
|
|
592
|
+
const input = `
|
|
593
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
594
|
+
|
|
595
|
+
function MyComponent() {
|
|
596
|
+
return (
|
|
597
|
+
<ThreadPrimitive.Empty>
|
|
598
|
+
<div>Welcome</div>
|
|
599
|
+
</ThreadPrimitive.Empty>
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
`;
|
|
603
|
+
|
|
604
|
+
const expected = `
|
|
605
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
606
|
+
|
|
607
|
+
function MyComponent() {
|
|
608
|
+
return (
|
|
609
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
610
|
+
<div>Welcome</div>
|
|
611
|
+
</AuiIf>
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
`;
|
|
615
|
+
|
|
616
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
it("should handle self-closing <ThreadPrimitive.Empty />", () => {
|
|
620
|
+
const input = `
|
|
621
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
622
|
+
|
|
623
|
+
function MyComponent() {
|
|
624
|
+
return <ThreadPrimitive.Empty />;
|
|
625
|
+
}
|
|
626
|
+
`;
|
|
627
|
+
|
|
628
|
+
const expected = `
|
|
629
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
630
|
+
|
|
631
|
+
function MyComponent() {
|
|
632
|
+
return <AuiIf condition={(s) => s.thread.isEmpty} />;
|
|
633
|
+
}
|
|
634
|
+
`;
|
|
635
|
+
|
|
636
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
it("should handle ThreadPrimitive.Empty alongside ThreadPrimitive.If", () => {
|
|
640
|
+
const input = `
|
|
641
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
642
|
+
|
|
643
|
+
function MyComponent() {
|
|
644
|
+
return (
|
|
645
|
+
<>
|
|
646
|
+
<ThreadPrimitive.Empty>
|
|
647
|
+
<div>Welcome</div>
|
|
648
|
+
</ThreadPrimitive.Empty>
|
|
649
|
+
<ThreadPrimitive.If running>
|
|
650
|
+
<div>Running</div>
|
|
651
|
+
</ThreadPrimitive.If>
|
|
652
|
+
</>
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
`;
|
|
656
|
+
|
|
657
|
+
const expected = `
|
|
658
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
659
|
+
|
|
660
|
+
function MyComponent() {
|
|
661
|
+
return (
|
|
662
|
+
<>
|
|
663
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
664
|
+
<div>Welcome</div>
|
|
665
|
+
</AuiIf>
|
|
666
|
+
<AuiIf condition={(s) => s.thread.isRunning}>
|
|
667
|
+
<div>Running</div>
|
|
668
|
+
</AuiIf>
|
|
669
|
+
</>
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
`;
|
|
673
|
+
|
|
674
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
// ── Edge cases ─────────────────────────────────────────────────────
|
|
679
|
+
|
|
680
|
+
describe("edge cases", () => {
|
|
681
|
+
it("should not add duplicate AuiIf import if already present", () => {
|
|
682
|
+
const input = `
|
|
683
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
684
|
+
|
|
685
|
+
function MyComponent() {
|
|
686
|
+
return (
|
|
687
|
+
<ThreadPrimitive.If empty>
|
|
688
|
+
<div>Empty</div>
|
|
689
|
+
</ThreadPrimitive.If>
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
`;
|
|
693
|
+
|
|
694
|
+
const expected = `
|
|
695
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
696
|
+
|
|
697
|
+
function MyComponent() {
|
|
698
|
+
return (
|
|
699
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
700
|
+
<div>Empty</div>
|
|
701
|
+
</AuiIf>
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
`;
|
|
705
|
+
|
|
706
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it("should handle multiple Primitive.If in the same file", () => {
|
|
710
|
+
const input = `
|
|
711
|
+
import { ThreadPrimitive, MessagePrimitive } from "@assistant-ui/react";
|
|
712
|
+
|
|
713
|
+
function MyComponent() {
|
|
714
|
+
return (
|
|
715
|
+
<>
|
|
716
|
+
<ThreadPrimitive.If running>
|
|
717
|
+
<div>Running</div>
|
|
718
|
+
</ThreadPrimitive.If>
|
|
719
|
+
<MessagePrimitive.If user>
|
|
720
|
+
<div>User</div>
|
|
721
|
+
</MessagePrimitive.If>
|
|
722
|
+
</>
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
`;
|
|
726
|
+
|
|
727
|
+
const expected = `
|
|
728
|
+
import { ThreadPrimitive, MessagePrimitive, AuiIf } from "@assistant-ui/react";
|
|
729
|
+
|
|
730
|
+
function MyComponent() {
|
|
731
|
+
return (
|
|
732
|
+
<>
|
|
733
|
+
<AuiIf condition={(s) => s.thread.isRunning}>
|
|
734
|
+
<div>Running</div>
|
|
735
|
+
</AuiIf>
|
|
736
|
+
<AuiIf condition={(s) => s.message.role === "user"}>
|
|
737
|
+
<div>User</div>
|
|
738
|
+
</AuiIf>
|
|
739
|
+
</>
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
`;
|
|
743
|
+
|
|
744
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it("should not transform if no @assistant-ui import", () => {
|
|
748
|
+
const input = `
|
|
749
|
+
function MyComponent() {
|
|
750
|
+
return (
|
|
751
|
+
<ThreadPrimitive.If empty>
|
|
752
|
+
<div>Empty</div>
|
|
753
|
+
</ThreadPrimitive.If>
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
`;
|
|
757
|
+
|
|
758
|
+
expect(applyTransform(input)).toBe(null);
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
it("should not transform non-If member expressions", () => {
|
|
762
|
+
const input = `
|
|
763
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
764
|
+
|
|
765
|
+
function MyComponent() {
|
|
766
|
+
return (
|
|
767
|
+
<ThreadPrimitive.Root>
|
|
768
|
+
<div>Hello</div>
|
|
769
|
+
</ThreadPrimitive.Root>
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
`;
|
|
773
|
+
|
|
774
|
+
expect(applyTransform(input)).toBe(null);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
it("should handle multiple props combined into a single condition", () => {
|
|
778
|
+
const input = `
|
|
779
|
+
import { ThreadPrimitive } from "@assistant-ui/react";
|
|
780
|
+
|
|
781
|
+
function MyComponent() {
|
|
782
|
+
return (
|
|
783
|
+
<ThreadPrimitive.If empty running={false}>
|
|
784
|
+
<div>Empty and not running</div>
|
|
785
|
+
</ThreadPrimitive.If>
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
`;
|
|
789
|
+
|
|
790
|
+
const expected = `
|
|
791
|
+
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
792
|
+
|
|
793
|
+
function MyComponent() {
|
|
794
|
+
return (
|
|
795
|
+
<AuiIf condition={(s) => s.thread.isEmpty && !s.thread.isRunning}>
|
|
796
|
+
<div>Empty and not running</div>
|
|
797
|
+
</AuiIf>
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
`;
|
|
801
|
+
|
|
802
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
it("should preserve other JSX elements alongside migrated ones", () => {
|
|
806
|
+
const input = `
|
|
807
|
+
import { ThreadPrimitive, ComposerPrimitive } from "@assistant-ui/react";
|
|
808
|
+
|
|
809
|
+
function MyComponent() {
|
|
810
|
+
return (
|
|
811
|
+
<ThreadPrimitive.Root>
|
|
812
|
+
<ThreadPrimitive.If empty>
|
|
813
|
+
<div>Welcome</div>
|
|
814
|
+
</ThreadPrimitive.If>
|
|
815
|
+
<ComposerPrimitive.Input />
|
|
816
|
+
</ThreadPrimitive.Root>
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
`;
|
|
820
|
+
|
|
821
|
+
const expected = `
|
|
822
|
+
import { ThreadPrimitive, ComposerPrimitive, AuiIf } from "@assistant-ui/react";
|
|
823
|
+
|
|
824
|
+
function MyComponent() {
|
|
825
|
+
return (
|
|
826
|
+
<ThreadPrimitive.Root>
|
|
827
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
828
|
+
<div>Welcome</div>
|
|
829
|
+
</AuiIf>
|
|
830
|
+
<ComposerPrimitive.Input />
|
|
831
|
+
</ThreadPrimitive.Root>
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
`;
|
|
835
|
+
|
|
836
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
});
|