wp-typia 0.12.0 → 0.13.0

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/README.md CHANGED
@@ -8,6 +8,8 @@ Use this package for new installs:
8
8
  - `bunx wp-typia create my-block`
9
9
  - `npx wp-typia create my-plugin --template @wp-typia/create-workspace-template`
10
10
  - `wp-typia add block counter-card --template basic`
11
+ - `wp-typia add binding-source hero-data`
12
+ - `wp-typia add hooked-block counter-card --anchor core/post-content --position after`
11
13
 
12
14
  `wp-typia <project-dir>` remains available as a backward-compatible alias to
13
15
  `wp-typia create <project-dir>`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wp-typia",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Canonical CLI package for wp-typia scaffolding and project workflows",
5
5
  "packageManager": "bun@1.3.11",
6
6
  "type": "module",
@@ -64,7 +64,7 @@
64
64
  "@bunli/runtime": "0.3.1",
65
65
  "@bunli/tui": "0.6.0",
66
66
  "@bunli/utils": "0.6.0",
67
- "@wp-typia/project-tools": "0.12.0",
67
+ "@wp-typia/project-tools": "0.13.0",
68
68
  "better-result": "^2.7.0",
69
69
  "react": "19.2.0",
70
70
  "react-dom": "19.2.0",
@@ -27,9 +27,11 @@ export const WP_TYPIA_TOP_LEVEL_COMMAND_NAMES = [
27
27
 
28
28
  const STRING_OPTION_NAMES_BY_COMMAND = {
29
29
  add: new Set([
30
+ "anchor",
30
31
  "block",
31
32
  "data-storage",
32
33
  "persistence-policy",
34
+ "position",
33
35
  "template",
34
36
  ]),
35
37
  create: new Set([
@@ -109,7 +111,7 @@ export const WP_TYPIA_FUTURE_COMMAND_TREE = [
109
111
  {
110
112
  description: "Extend an official wp-typia workspace.",
111
113
  name: "add",
112
- subcommands: ["block", "variation", "pattern"],
114
+ subcommands: ["block", "variation", "pattern", "binding-source", "hooked-block"],
113
115
  },
114
116
  {
115
117
  description: "Run migration workflows.",
@@ -21,6 +21,10 @@ function loadAddFlow() {
21
21
  }
22
22
 
23
23
  const addOptions = {
24
+ anchor: {
25
+ description: "Anchor block name for hooked-block workflows.",
26
+ schema: z.string().optional(),
27
+ },
24
28
  block: {
25
29
  description: "Target block slug for variation workflows.",
26
30
  schema: z.string().optional(),
@@ -33,6 +37,10 @@ const addOptions = {
33
37
  description: "Persistence write policy for persistence-capable templates.",
34
38
  schema: z.string().optional(),
35
39
  },
40
+ position: {
41
+ description: "Hook position for hooked-block workflows.",
42
+ schema: z.string().optional(),
43
+ },
36
44
  template: {
37
45
  description: "Built-in block family for the new block.",
38
46
  schema: z.string().optional(),
@@ -40,7 +48,7 @@ const addOptions = {
40
48
  };
41
49
 
42
50
  export const addCommand = defineCommand({
43
- description: "Extend an official wp-typia workspace with blocks, variations, or patterns.",
51
+ description: "Extend an official wp-typia workspace with blocks, variations, patterns, binding sources, or hooked blocks.",
44
52
  handler: async (args) => {
45
53
  await executeAddCommand({
46
54
  cwd: args.cwd,
@@ -67,17 +75,21 @@ export const addCommand = defineCommand({
67
75
  "data-storage":
68
76
  (args.flags["data-storage"] as string | undefined) ??
69
77
  config["data-storage"],
78
+ anchor: (args.flags.anchor as string | undefined) ?? "",
70
79
  block: (args.flags.block as string | undefined) ?? "",
71
80
  kind:
72
81
  (args.positional[0] as
73
82
  | "block"
74
83
  | "variation"
75
84
  | "pattern"
85
+ | "binding-source"
86
+ | "hooked-block"
76
87
  | undefined) ?? "block",
77
88
  name: args.positional[1] ?? "",
78
89
  "persistence-policy":
79
90
  (args.flags["persistence-policy"] as string | undefined) ??
80
91
  config["persistence-policy"],
92
+ position: (args.flags.position as string | undefined) ?? "after",
81
93
  template:
82
94
  (args.flags.template as string | undefined) ?? config.template,
83
95
  },
@@ -11,7 +11,9 @@ import {
11
11
  listTemplates,
12
12
  parseMigrationArgs,
13
13
  tryResolveWorkspaceProject,
14
+ runAddBindingSourceCommand,
14
15
  runAddBlockCommand,
16
+ runAddHookedBlockCommand,
15
17
  runAddPatternCommand,
16
18
  runAddVariationCommand,
17
19
  runDoctor,
@@ -259,8 +261,56 @@ export async function executeAddCommand({
259
261
  return;
260
262
  }
261
263
 
264
+ if (kind === "binding-source") {
265
+ if (!name) {
266
+ throw new Error(
267
+ "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name>.",
268
+ );
269
+ }
270
+
271
+ const result = await runAddBindingSourceCommand({
272
+ bindingSourceName: name,
273
+ cwd,
274
+ });
275
+ console.log(`✅ Added binding source ${result.bindingSourceSlug} in ${result.projectDir}.`);
276
+ return;
277
+ }
278
+
279
+ if (kind === "hooked-block") {
280
+ if (!name) {
281
+ throw new Error(
282
+ "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.",
283
+ );
284
+ }
285
+
286
+ const anchorBlockName = readOptionalStringFlag(flags, "anchor");
287
+ if (!anchorBlockName) {
288
+ throw new Error("`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
289
+ }
290
+
291
+ const position = readOptionalStringFlag(flags, "position");
292
+ if (!position) {
293
+ throw new Error(
294
+ "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.",
295
+ );
296
+ }
297
+
298
+ const result = await runAddHookedBlockCommand({
299
+ anchorBlockName,
300
+ blockName: name,
301
+ cwd,
302
+ position,
303
+ });
304
+ console.log(
305
+ `✅ Added blockHooks metadata for ${result.blockSlug} relative to ${result.anchorBlockName} (${result.position}) in ${result.projectDir}.`,
306
+ );
307
+ return;
308
+ }
309
+
262
310
  if (kind !== "block") {
263
- throw new Error(`Unknown add kind "${kind}". Expected one of: block, variation, pattern.`);
311
+ throw new Error(
312
+ `Unknown add kind "${kind}". Expected one of: block, variation, pattern, binding-source, hooked-block.`,
313
+ );
264
314
  }
265
315
 
266
316
  if (!name) {
@@ -2,16 +2,19 @@ import { useState } from "react";
2
2
 
3
3
  import { useRuntime } from "@bunli/runtime/app";
4
4
  import { Alert, SchemaForm } from "@bunli/tui";
5
+ import { HOOKED_BLOCK_POSITION_IDS } from "@wp-typia/project-tools";
5
6
  import { z } from "zod";
6
7
 
7
8
  import { executeAddCommand } from "../runtime-bridge";
8
9
 
9
10
  const addFlowSchema = z.object({
11
+ anchor: z.string().optional(),
10
12
  block: z.string().optional(),
11
13
  "data-storage": z.string().optional(),
12
- kind: z.enum(["block", "variation", "pattern"]).default("block"),
14
+ kind: z.enum(["block", "variation", "pattern", "binding-source", "hooked-block"]).default("block"),
13
15
  name: z.string().optional(),
14
16
  "persistence-policy": z.string().optional(),
17
+ position: z.string().optional(),
15
18
  template: z.string().optional(),
16
19
  });
17
20
 
@@ -27,6 +30,16 @@ type AddFlowProps = {
27
30
  }>;
28
31
  };
29
32
 
33
+ const HOOKED_BLOCK_POSITION_DESCRIPTIONS: Record<
34
+ (typeof HOOKED_BLOCK_POSITION_IDS)[number],
35
+ string
36
+ > = {
37
+ after: "Insert after the anchor block",
38
+ before: "Insert before the anchor block",
39
+ firstChild: "Insert as the first child of the anchor block",
40
+ lastChild: "Insert as the last child of the anchor block",
41
+ };
42
+
30
43
  export function AddFlow({ cwd, initialValues, workspaceBlockOptions }: AddFlowProps) {
31
44
  const runtime = useRuntime();
32
45
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
@@ -54,6 +67,16 @@ export function AddFlow({ cwd, initialValues, workspaceBlockOptions }: AddFlowPr
54
67
  description: "Add a PHP block pattern shell",
55
68
  value: "pattern",
56
69
  },
70
+ {
71
+ name: "binding-source",
72
+ description: "Add a shared block bindings source",
73
+ value: "binding-source",
74
+ },
75
+ {
76
+ name: "hooked-block",
77
+ description: "Add block.json hook metadata to an existing block",
78
+ value: "hooked-block",
79
+ },
57
80
  ],
58
81
  },
59
82
  {
@@ -105,6 +128,36 @@ export function AddFlow({ cwd, initialValues, workspaceBlockOptions }: AddFlowPr
105
128
  name: "name",
106
129
  visibleWhen: (values) => values.kind === "pattern",
107
130
  },
131
+ {
132
+ kind: "text",
133
+ label: "Binding source name",
134
+ name: "name",
135
+ visibleWhen: (values) => values.kind === "binding-source",
136
+ },
137
+ {
138
+ kind: workspaceBlockOptions.length > 0 ? "select" : "text",
139
+ label: "Target block",
140
+ name: "name",
141
+ options: workspaceBlockOptions,
142
+ visibleWhen: (values) => values.kind === "hooked-block",
143
+ },
144
+ {
145
+ kind: "text",
146
+ label: "Anchor block name",
147
+ name: "anchor",
148
+ visibleWhen: (values) => values.kind === "hooked-block",
149
+ },
150
+ {
151
+ kind: "select",
152
+ label: "Hook position",
153
+ name: "position",
154
+ options: HOOKED_BLOCK_POSITION_IDS.map((position) => ({
155
+ name: position,
156
+ description: HOOKED_BLOCK_POSITION_DESCRIPTIONS[position],
157
+ value: position,
158
+ })),
159
+ visibleWhen: (values) => values.kind === "hooked-block",
160
+ },
108
161
  {
109
162
  kind: "select",
110
163
  label: "Data storage",