wp-typia 0.16.1 → 0.16.2

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.
@@ -1,175 +1,205 @@
1
- import { SchemaForm } from "@bunli/tui";
2
- import { z } from "zod";
1
+ import { createElement, useMemo } from "react";
2
+
3
+ import {
4
+ Form,
5
+ type SelectOption,
6
+ useFormContext,
7
+ useTerminalDimensions,
8
+ } from "@bunli/tui";
3
9
 
4
10
  import { executeMigrateCommand } from "../runtime-bridge";
5
11
  import { useAlternateBufferLifecycle } from "./alternate-buffer-lifecycle";
12
+ import {
13
+ type MigrateFlowValues,
14
+ getMigrateScrollTop,
15
+ getMigrateViewportHeight,
16
+ getVisibleMigrateFieldNames,
17
+ migrateFlowSchema,
18
+ sanitizeMigrateSubmitValues,
19
+ } from "./migrate-flow-model";
20
+ import {
21
+ FirstPartyCheckboxField,
22
+ FirstPartyScrollBox,
23
+ FirstPartySelectField,
24
+ FirstPartyTextField,
25
+ } from "./first-party-form";
26
+ import { getWrappedFieldNeighbors } from "./first-party-form-model";
6
27
 
7
- const migrateFlowSchema = z.object({
8
- all: z.boolean().default(false),
9
- command: z.enum([
10
- "init",
11
- "snapshot",
12
- "plan",
13
- "wizard",
14
- "diff",
15
- "scaffold",
16
- "verify",
17
- "doctor",
18
- "fixtures",
19
- "fuzz",
20
- ]),
21
- "current-migration-version": z.string().optional(),
22
- force: z.boolean().default(false),
23
- "from-migration-version": z.string().optional(),
24
- iterations: z.string().optional(),
25
- "migration-version": z.string().optional(),
26
- seed: z.string().optional(),
27
- "to-migration-version": z.string().optional(),
28
- });
29
-
30
- type MigrateFlowValues = z.infer<typeof migrateFlowSchema>;
28
+ const migrateCommandOptions: SelectOption[] = [
29
+ { name: "init", description: "Initialize migration config", value: "init" },
30
+ {
31
+ name: "snapshot",
32
+ description: "Capture the current schema snapshot",
33
+ value: "snapshot",
34
+ },
35
+ { name: "plan", description: "Preview migration work", value: "plan" },
36
+ {
37
+ name: "wizard",
38
+ description: "Guided migration preview",
39
+ value: "wizard",
40
+ },
41
+ { name: "diff", description: "Diff migration snapshots", value: "diff" },
42
+ {
43
+ name: "scaffold",
44
+ description: "Generate migration rules and artifacts",
45
+ value: "scaffold",
46
+ },
47
+ {
48
+ name: "verify",
49
+ description: "Verify generated migration fixtures",
50
+ value: "verify",
51
+ },
52
+ {
53
+ name: "doctor",
54
+ description: "Diagnose migration workspace health",
55
+ value: "doctor",
56
+ },
57
+ {
58
+ name: "fixtures",
59
+ description: "Refresh migration fixtures",
60
+ value: "fixtures",
61
+ },
62
+ { name: "fuzz", description: "Run migration fuzzing", value: "fuzz" },
63
+ ];
31
64
 
32
65
  type MigrateFlowProps = {
33
66
  cwd: string;
34
67
  initialValues: Partial<MigrateFlowValues>;
35
68
  };
36
69
 
37
- function sanitizeMigrateValues(values: MigrateFlowValues): Record<string, unknown> {
38
- return Object.fromEntries(
39
- Object.entries(values).flatMap(([key, value]) => {
40
- if (typeof value === "string" && value.trim().length === 0) {
41
- return [];
42
- }
43
- return [[key, value]];
44
- }),
45
- );
46
- }
70
+ type MigrateSelectFieldName = {
71
+ [K in keyof MigrateFlowValues]-?: MigrateFlowValues[K] extends string | undefined ? K : never;
72
+ }[keyof MigrateFlowValues];
47
73
 
48
- export function MigrateFlow({ cwd, initialValues }: MigrateFlowProps) {
49
- const { handleCancel, handleSubmit } = useAlternateBufferLifecycle("wp-typia migrate failed");
74
+ type MigrateCheckboxFieldName = {
75
+ [K in keyof MigrateFlowValues]-?: MigrateFlowValues[K] extends boolean | undefined ? K : never;
76
+ }[keyof MigrateFlowValues];
50
77
 
51
- return (
52
- <SchemaForm
53
- fields={[
54
- {
55
- kind: "select",
56
- label: "Migration command",
57
- name: "command",
58
- options: [
59
- { name: "init", description: "Initialize migration config", value: "init" },
60
- {
61
- name: "snapshot",
62
- description: "Capture the current schema snapshot",
63
- value: "snapshot",
64
- },
65
- { name: "plan", description: "Preview migration work", value: "plan" },
66
- {
67
- name: "wizard",
68
- description: "Guided migration preview",
69
- value: "wizard",
70
- },
71
- { name: "diff", description: "Diff migration snapshots", value: "diff" },
72
- {
73
- name: "scaffold",
74
- description: "Generate migration rules and artifacts",
75
- value: "scaffold",
76
- },
77
- {
78
- name: "verify",
79
- description: "Verify generated migration fixtures",
80
- value: "verify",
81
- },
82
- {
83
- name: "doctor",
84
- description: "Diagnose migration workspace health",
85
- value: "doctor",
86
- },
87
- {
88
- name: "fixtures",
89
- description: "Refresh migration fixtures",
90
- value: "fixtures",
91
- },
92
- { name: "fuzz", description: "Run migration fuzzing", value: "fuzz" },
93
- ],
94
- required: true,
95
- },
96
- {
97
- kind: "text",
78
+ function MigrateFlowFields() {
79
+ const { activeFieldName, values } = useFormContext();
80
+ const { height: terminalHeight = 24 } = useTerminalDimensions();
81
+ const migrateValues = values as Partial<MigrateFlowValues>;
82
+ const command = migrateValues.command ?? "plan";
83
+ const viewportHeight = getMigrateViewportHeight(terminalHeight);
84
+ const scrollValues = useMemo(() => ({ command }), [command]);
85
+ const scrollTop = useMemo(
86
+ () =>
87
+ getMigrateScrollTop({
88
+ activeFieldName,
89
+ values: scrollValues,
90
+ viewportHeight,
91
+ }),
92
+ [activeFieldName, scrollValues, viewportHeight],
93
+ );
94
+ const visibleFields = new Set(getVisibleMigrateFieldNames(migrateValues));
95
+ const orderedVisibleFields = useMemo(
96
+ () => getVisibleMigrateFieldNames(migrateValues),
97
+ [migrateValues],
98
+ );
99
+
100
+ return createElement(
101
+ FirstPartyScrollBox,
102
+ { scrollTop, viewportHeight },
103
+ [
104
+ createElement(FirstPartySelectField, {
105
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "command"),
106
+ key: "command",
107
+ label: "Migration command",
108
+ name: "command" satisfies MigrateSelectFieldName,
109
+ options: migrateCommandOptions,
110
+ }),
111
+ visibleFields.has("current-migration-version")
112
+ ? createElement(FirstPartyTextField, {
113
+ ...getWrappedFieldNeighbors(
114
+ orderedVisibleFields,
115
+ "current-migration-version",
116
+ ),
117
+ key: "current-migration-version",
98
118
  label: "Current migration version",
99
119
  name: "current-migration-version",
100
- visibleWhen: (values) => values.command === "init",
101
- },
102
- {
103
- kind: "text",
120
+ })
121
+ : null,
122
+ visibleFields.has("migration-version")
123
+ ? createElement(FirstPartyTextField, {
124
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "migration-version"),
125
+ key: "migration-version",
104
126
  label: "Migration version",
105
127
  name: "migration-version",
106
- visibleWhen: (values) => values.command === "snapshot",
107
- },
108
- {
109
- kind: "text",
128
+ })
129
+ : null,
130
+ visibleFields.has("from-migration-version")
131
+ ? createElement(FirstPartyTextField, {
132
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "from-migration-version"),
133
+ key: "from-migration-version",
110
134
  label: "From migration version",
111
135
  name: "from-migration-version",
112
- visibleWhen: (values) =>
113
- values.command === "plan" ||
114
- values.command === "diff" ||
115
- values.command === "scaffold" ||
116
- values.command === "verify" ||
117
- values.command === "doctor" ||
118
- values.command === "fixtures" ||
119
- values.command === "fuzz",
120
- },
121
- {
122
- kind: "text",
136
+ })
137
+ : null,
138
+ visibleFields.has("to-migration-version")
139
+ ? createElement(FirstPartyTextField, {
140
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "to-migration-version"),
141
+ key: "to-migration-version",
123
142
  label: "To migration version",
124
143
  name: "to-migration-version",
125
- visibleWhen: (values) =>
126
- values.command === "plan" ||
127
- values.command === "diff" ||
128
- values.command === "scaffold" ||
129
- values.command === "fixtures",
130
- },
131
- {
132
- kind: "checkbox",
144
+ })
145
+ : null,
146
+ visibleFields.has("all")
147
+ ? createElement(FirstPartyCheckboxField, {
148
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "all"),
149
+ key: "all",
133
150
  label: "All configured migration versions",
134
- name: "all",
135
- visibleWhen: (values) =>
136
- values.command === "verify" ||
137
- values.command === "doctor" ||
138
- values.command === "fixtures" ||
139
- values.command === "fuzz",
140
- },
141
- {
142
- kind: "checkbox",
151
+ name: "all" satisfies MigrateCheckboxFieldName,
152
+ })
153
+ : null,
154
+ visibleFields.has("force")
155
+ ? createElement(FirstPartyCheckboxField, {
156
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "force"),
157
+ key: "force",
143
158
  label: "Force overwrite",
144
- name: "force",
145
- visibleWhen: (values) => values.command === "fixtures",
146
- },
147
- {
148
- kind: "text",
159
+ name: "force" satisfies MigrateCheckboxFieldName,
160
+ })
161
+ : null,
162
+ visibleFields.has("iterations")
163
+ ? createElement(FirstPartyTextField, {
164
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "iterations"),
165
+ key: "iterations",
149
166
  label: "Iterations",
150
167
  name: "iterations",
151
- visibleWhen: (values) => values.command === "fuzz",
152
- },
153
- {
154
- kind: "text",
168
+ })
169
+ : null,
170
+ visibleFields.has("seed")
171
+ ? createElement(FirstPartyTextField, {
172
+ ...getWrappedFieldNeighbors(orderedVisibleFields, "seed"),
173
+ key: "seed",
155
174
  label: "Seed",
156
175
  name: "seed",
157
- visibleWhen: (values) => values.command === "fuzz",
158
- },
159
- ]}
176
+ })
177
+ : null,
178
+ ],
179
+ );
180
+ }
181
+
182
+ export function MigrateFlow({ cwd, initialValues }: MigrateFlowProps) {
183
+ const { handleCancel, handleSubmit } = useAlternateBufferLifecycle("wp-typia migrate failed");
184
+
185
+ return (
186
+ <Form
160
187
  initialValues={initialValues}
161
188
  onCancel={handleCancel}
162
189
  onSubmit={async (values) =>
163
190
  handleSubmit(async () => {
164
- await executeMigrateCommand({
165
- command: values.command,
166
- cwd,
167
- flags: sanitizeMigrateValues(values),
168
- });
191
+ const flags = sanitizeMigrateSubmitValues(values);
192
+ await executeMigrateCommand({
193
+ command: values.command,
194
+ cwd,
195
+ flags,
196
+ });
169
197
  })
170
198
  }
171
199
  schema={migrateFlowSchema}
172
200
  title="Run wp-typia migration workflows"
173
- />
201
+ >
202
+ <MigrateFlowFields />
203
+ </Form>
174
204
  );
175
205
  }