@wp-typia/project-tools 0.16.5 → 0.16.7
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 +9 -7
- package/dist/runtime/built-in-block-code-artifacts.js +5 -5
- package/dist/runtime/cli-add-block.d.ts +36 -0
- package/dist/runtime/cli-add-block.js +518 -0
- package/dist/runtime/cli-add-shared.d.ts +93 -0
- package/dist/runtime/cli-add-shared.js +201 -0
- package/dist/runtime/cli-add-workspace.d.ts +81 -0
- package/dist/runtime/cli-add-workspace.js +582 -0
- package/dist/runtime/cli-add.d.ts +11 -131
- package/dist/runtime/cli-add.js +10 -1250
- package/dist/runtime/cli-prompt.d.ts +25 -0
- package/dist/runtime/cli-prompt.js +32 -20
- package/dist/runtime/cli-scaffold.js +1 -2
- package/dist/runtime/migration-types.d.ts +9 -53
- package/dist/runtime/scaffold.js +1 -2
- package/dist/runtime/template-source.js +1 -2
- package/package.json +6 -8
- package/templates/_shared/base/package.json.mustache +1 -0
- package/templates/_shared/compound/core/package.json.mustache +1 -1
- package/templates/_shared/compound/core/scripts/add-compound-child.ts.mustache +5 -5
- package/templates/_shared/compound/persistence/package.json.mustache +1 -1
- package/templates/_shared/persistence/core/package.json.mustache +1 -0
- package/templates/interactivity/package.json.mustache +2 -1
|
@@ -12,10 +12,35 @@ export interface ReadlinePrompt {
|
|
|
12
12
|
select<T extends string>(message: string, options: PromptOption<T>[], defaultValue?: number): Promise<T>;
|
|
13
13
|
text(message: string, defaultValue: string, validate?: ValidateInput): Promise<string>;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Adapter interface for readline-style prompt interactions.
|
|
17
|
+
*
|
|
18
|
+
* Public CLI code uses the native readline implementation, while tests can
|
|
19
|
+
* substitute lightweight doubles that expose the same `question` and `close`
|
|
20
|
+
* methods.
|
|
21
|
+
*/
|
|
22
|
+
export interface ReadlineQuestionAdapter {
|
|
23
|
+
/** Close the underlying prompt interface and release any open handles. */
|
|
24
|
+
close(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Render one prompt and resolve with the collected answer string.
|
|
27
|
+
*
|
|
28
|
+
* @param query Prompt text written to the active output stream.
|
|
29
|
+
* @param callback Callback that receives the entered answer.
|
|
30
|
+
*/
|
|
31
|
+
question(query: string, callback: (answer: string) => void): void;
|
|
32
|
+
}
|
|
15
33
|
/**
|
|
16
34
|
* Create the default readline-backed prompt implementation for the CLI.
|
|
17
35
|
*
|
|
18
36
|
* @returns A prompt adapter that reads from stdin and writes to stdout.
|
|
19
37
|
*/
|
|
20
38
|
export declare function createReadlinePrompt(): ReadlinePrompt;
|
|
39
|
+
/**
|
|
40
|
+
* Build a prompt adapter around a supplied readline-style question interface.
|
|
41
|
+
*
|
|
42
|
+
* This keeps the production CLI path unchanged while letting tests validate
|
|
43
|
+
* retry behavior without stubbing global stdin/stdout.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createReadlinePromptWithInterface(rl: ReadlineQuestionAdapter): ReadlinePrompt;
|
|
21
46
|
export {};
|
|
@@ -9,21 +9,32 @@ export function createReadlinePrompt() {
|
|
|
9
9
|
input: process.stdin,
|
|
10
10
|
output: process.stdout,
|
|
11
11
|
});
|
|
12
|
+
return createReadlinePromptWithInterface(rl);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build a prompt adapter around a supplied readline-style question interface.
|
|
16
|
+
*
|
|
17
|
+
* This keeps the production CLI path unchanged while letting tests validate
|
|
18
|
+
* retry behavior without stubbing global stdin/stdout.
|
|
19
|
+
*/
|
|
20
|
+
export function createReadlinePromptWithInterface(rl) {
|
|
12
21
|
return {
|
|
13
22
|
async text(message, defaultValue, validate) {
|
|
14
23
|
const suffix = defaultValue ? ` (${defaultValue})` : "";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
while (true) {
|
|
25
|
+
const answer = await new Promise((resolve) => {
|
|
26
|
+
rl.question(`${message}${suffix}: `, resolve);
|
|
27
|
+
});
|
|
28
|
+
const value = String(answer).trim() || defaultValue;
|
|
29
|
+
if (validate) {
|
|
30
|
+
const result = validate(value);
|
|
31
|
+
if (result !== true) {
|
|
32
|
+
console.error(`❌ ${typeof result === "string" ? result : "Invalid input"}`);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
24
35
|
}
|
|
36
|
+
return value;
|
|
25
37
|
}
|
|
26
|
-
return value;
|
|
27
38
|
},
|
|
28
39
|
async select(message, options, defaultValue = 1) {
|
|
29
40
|
if (options.length === 0) {
|
|
@@ -34,17 +45,18 @@ export function createReadlinePrompt() {
|
|
|
34
45
|
const hint = option.hint ? ` - ${option.hint}` : "";
|
|
35
46
|
console.log(` ${index + 1}. ${option.label}${hint}`);
|
|
36
47
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
while (true) {
|
|
49
|
+
const answer = await this.text("Choice", String(defaultValue));
|
|
50
|
+
const numericChoice = Number(answer);
|
|
51
|
+
if (!Number.isNaN(numericChoice) && options[numericChoice - 1]) {
|
|
52
|
+
return options[numericChoice - 1].value;
|
|
53
|
+
}
|
|
54
|
+
const directChoice = options.find((option) => option.value === answer);
|
|
55
|
+
if (directChoice) {
|
|
56
|
+
return directChoice.value;
|
|
57
|
+
}
|
|
58
|
+
console.error(`❌ Invalid selection: ${answer}`);
|
|
45
59
|
}
|
|
46
|
-
console.error(`❌ Invalid selection: ${answer}`);
|
|
47
|
-
return this.select(message, options, defaultValue);
|
|
48
60
|
},
|
|
49
61
|
close() {
|
|
50
62
|
rl.close();
|
|
@@ -4,8 +4,7 @@ import { collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDat
|
|
|
4
4
|
import { formatInstallCommand, formatRunScript, } from "./package-managers.js";
|
|
5
5
|
import { getPrimaryDevelopmentScript } from "./local-dev-presets.js";
|
|
6
6
|
import { getOptionalOnboardingNote, getOptionalOnboardingSteps, } from "./scaffold-onboarding.js";
|
|
7
|
-
import { isBuiltInTemplateId } from "./template-registry.js";
|
|
8
|
-
const OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE = "@wp-typia/create-workspace-template";
|
|
7
|
+
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, isBuiltInTemplateId, } from "./template-registry.js";
|
|
9
8
|
function templateUsesPersistenceSettings(templateId, options) {
|
|
10
9
|
if (templateId === "persistence") {
|
|
11
10
|
return true;
|
|
@@ -1,56 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
maxLength?: number | null;
|
|
11
|
-
maxItems?: number | null;
|
|
12
|
-
maximum?: number | null;
|
|
13
|
-
minLength?: number | null;
|
|
14
|
-
minItems?: number | null;
|
|
15
|
-
minimum?: number | null;
|
|
16
|
-
multipleOf?: number | null;
|
|
17
|
-
pattern?: string | null;
|
|
18
|
-
typeTag?: string | null;
|
|
19
|
-
}
|
|
20
|
-
export interface ManifestUnionMetadata {
|
|
21
|
-
discriminator: string;
|
|
22
|
-
branches: Record<string, ManifestAttribute>;
|
|
23
|
-
}
|
|
24
|
-
export interface ManifestTsMetadata {
|
|
25
|
-
items?: ManifestAttribute | null;
|
|
26
|
-
kind: ManifestTsKind;
|
|
27
|
-
properties?: Record<string, ManifestAttribute> | null;
|
|
28
|
-
required?: boolean;
|
|
29
|
-
union?: ManifestUnionMetadata | null;
|
|
30
|
-
}
|
|
31
|
-
export interface ManifestTypiaMetadata {
|
|
32
|
-
constraints: ManifestConstraints;
|
|
33
|
-
defaultValue?: JsonValue | null;
|
|
34
|
-
hasDefault?: boolean;
|
|
35
|
-
}
|
|
36
|
-
export interface ManifestWpMetadata {
|
|
37
|
-
defaultValue?: JsonValue | null;
|
|
38
|
-
enum?: JsonValue[] | null;
|
|
39
|
-
hasDefault?: boolean;
|
|
40
|
-
selector?: string | null;
|
|
41
|
-
source?: "html" | "text" | "rich-text" | null;
|
|
42
|
-
type?: string | null;
|
|
43
|
-
}
|
|
44
|
-
export interface ManifestAttribute {
|
|
45
|
-
ts: ManifestTsMetadata;
|
|
46
|
-
typia: ManifestTypiaMetadata;
|
|
47
|
-
wp: ManifestWpMetadata;
|
|
48
|
-
}
|
|
49
|
-
export interface ManifestDocument {
|
|
50
|
-
attributes?: Record<string, ManifestAttribute>;
|
|
51
|
-
manifestVersion?: number | null;
|
|
52
|
-
sourceType?: string | null;
|
|
53
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Shared migration contract facade for project-tools runtime.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports canonical manifest and migration contracts from
|
|
5
|
+
* `@wp-typia/block-runtime/migration-types` and layers project-tools-specific
|
|
6
|
+
* migration workspace types on top.
|
|
7
|
+
*/
|
|
8
|
+
import type { JsonValue, ManifestAttribute, ManifestDocument } from "@wp-typia/block-runtime/migration-types";
|
|
9
|
+
export type { JsonPrimitive, JsonValue, ManifestAttribute, ManifestConstraints, ManifestDocument, ManifestTsKind, ManifestTsMetadata, ManifestTypiaMetadata, ManifestUnionMetadata, ManifestWpMetadata, } from "@wp-typia/block-runtime/migration-types";
|
|
54
10
|
export interface ManifestSummaryAttribute {
|
|
55
11
|
constraints: ManifestAttribute["typia"]["constraints"];
|
|
56
12
|
defaultValue: ManifestAttribute["typia"]["defaultValue"] | null;
|
package/dist/runtime/scaffold.js
CHANGED
|
@@ -13,13 +13,12 @@ import { getStarterManifestFiles, stringifyStarterManifest } from "./starter-man
|
|
|
13
13
|
import { toKebabCase, toPascalCase, toSnakeCase, toTitleCase, } from "./string-case.js";
|
|
14
14
|
import { BUILTIN_BLOCK_METADATA_VERSION, COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS, getBuiltInTemplateMetadataDefaults, getRemovedBuiltInTemplateMessage, isRemovedBuiltInTemplateId, } from "./template-defaults.js";
|
|
15
15
|
import { copyInterpolatedDirectory } from "./template-render.js";
|
|
16
|
-
import { PROJECT_TOOLS_PACKAGE_ROOT, TEMPLATE_IDS, getTemplateById, isBuiltInTemplateId, } from "./template-registry.js";
|
|
16
|
+
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, PROJECT_TOOLS_PACKAGE_ROOT, TEMPLATE_IDS, getTemplateById, isBuiltInTemplateId, } from "./template-registry.js";
|
|
17
17
|
import { resolveTemplateSource } from "./template-source.js";
|
|
18
18
|
import { BlockGeneratorService, buildTemplateVariablesFromBlockSpec, createBuiltInBlockSpec, } from "./block-generator-service.js";
|
|
19
19
|
const BLOCK_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
20
20
|
const PHP_PREFIX_PATTERN = /^[a-z_][a-z0-9_]*$/;
|
|
21
21
|
const PHP_PREFIX_MAX_LENGTH = 50;
|
|
22
|
-
const OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE = "@wp-typia/create-workspace-template";
|
|
23
22
|
const WORKSPACE_TEMPLATE_ALIAS = "workspace";
|
|
24
23
|
const EPHEMERAL_NODE_MODULES_LINK_TYPE = process.platform === "win32" ? "junction" : "dir";
|
|
25
24
|
const LOCKFILES = {
|
|
@@ -9,7 +9,7 @@ import { pathToFileURL } from "node:url";
|
|
|
9
9
|
import npa from "npm-package-arg";
|
|
10
10
|
import semver from "semver";
|
|
11
11
|
import { x as extractTarball } from "tar";
|
|
12
|
-
import { BUILTIN_TEMPLATE_IDS, PROJECT_TOOLS_PACKAGE_ROOT, isBuiltInTemplateId, } from "./template-registry.js";
|
|
12
|
+
import { BUILTIN_TEMPLATE_IDS, OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, PROJECT_TOOLS_PACKAGE_ROOT, isBuiltInTemplateId, } from "./template-registry.js";
|
|
13
13
|
import { isPlainObject } from "./object-utils.js";
|
|
14
14
|
import { getRemovedBuiltInTemplateMessage, isRemovedBuiltInTemplateId, } from "./template-defaults.js";
|
|
15
15
|
import { getBuiltInTemplateLayerDirs, isOmittableBuiltInTemplateLayerDir, resolveBuiltInTemplateSource, } from "./template-builtins.js";
|
|
@@ -18,7 +18,6 @@ import { toSegmentPascalCase } from "./string-case.js";
|
|
|
18
18
|
import { copyRawDirectory, copyRenderedDirectory } from "./template-render.js";
|
|
19
19
|
const EXTERNAL_TEMPLATE_ENTRY_CANDIDATES = ["index.js", "index.cjs", "index.mjs"];
|
|
20
20
|
const TEMPLATE_WARNING_MESSAGE = "wp-typia owns package/tooling/sync setup for generated projects, so this external template setting is ignored.";
|
|
21
|
-
const OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE = "@wp-typia/create-workspace-template";
|
|
22
21
|
function isTemplatePathLocator(templateId) {
|
|
23
22
|
return path.isAbsolute(templateId) || templateId.startsWith("./") || templateId.startsWith("../");
|
|
24
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wp-typia/project-tools",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.7",
|
|
4
4
|
"description": "Project orchestration and programmatic tooling for wp-typia",
|
|
5
5
|
"packageManager": "bun@1.3.11",
|
|
6
6
|
"type": "module",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"prepack": "bun run build && node ./scripts/publish-manifest.mjs prepare",
|
|
76
76
|
"postpack": "node ./scripts/publish-manifest.mjs restore",
|
|
77
77
|
"test": "bun run build && bun test tests/*.test.ts",
|
|
78
|
-
"test:scaffold-core": "bun run build && bun test tests/block-generator-service.test.ts tests/built-in-block-artifacts.test.ts tests/scaffold-basic.test.ts tests/scaffold-persistence.test.ts tests/template-source.test.ts tests/cli-entry.test.ts tests/import-policy.test.ts",
|
|
78
|
+
"test:scaffold-core": "bun run build && bun test tests/block-generator-service.test.ts tests/built-in-block-artifacts.test.ts tests/scaffold-basic.test.ts tests/scaffold-persistence.test.ts tests/template-source.test.ts tests/cli-entry.test.ts tests/cli-prompt.test.ts tests/import-policy.test.ts",
|
|
79
79
|
"test:workspace": "bun run build && bun test tests/workspace-add.test.ts tests/workspace-doctor.test.ts",
|
|
80
80
|
"test:compound": "bun run build && bun test tests/scaffold-compound.test.ts",
|
|
81
81
|
"test:migration-planning": "bun run build && bun test tests/migration-init.test.ts tests/migration-config.test.ts tests/migration-plan-wizard.test.ts",
|
|
@@ -114,9 +114,9 @@
|
|
|
114
114
|
"bun": ">=1.3.11"
|
|
115
115
|
},
|
|
116
116
|
"dependencies": {
|
|
117
|
-
"@wp-typia/api-client": "^0.4.
|
|
118
|
-
"@wp-typia/block-runtime": "^0.4.
|
|
119
|
-
"@wp-typia/rest": "^0.3.
|
|
117
|
+
"@wp-typia/api-client": "^0.4.4",
|
|
118
|
+
"@wp-typia/block-runtime": "^0.4.7",
|
|
119
|
+
"@wp-typia/rest": "^0.3.7",
|
|
120
120
|
"@wp-typia/block-types": "^0.2.1",
|
|
121
121
|
"mustache": "^4.2.0",
|
|
122
122
|
"npm-package-arg": "^13.0.0",
|
|
@@ -126,8 +126,6 @@
|
|
|
126
126
|
"typescript": "^5.9.2"
|
|
127
127
|
},
|
|
128
128
|
"devDependencies": {
|
|
129
|
-
"react": "^19.2.0"
|
|
130
|
-
"react-devtools-core": "^7.0.1",
|
|
131
|
-
"ws": "^8.18.0"
|
|
129
|
+
"react": "^19.2.0"
|
|
132
130
|
}
|
|
133
131
|
}
|
|
@@ -460,7 +460,8 @@ function renderEditFile(
|
|
|
460
460
|
): string {
|
|
461
461
|
const childCssClassName = buildBlockCssClassName( PARENT_BLOCK_NAMESPACE, childFolderSlug );
|
|
462
462
|
|
|
463
|
-
return `import {
|
|
463
|
+
return `import type { BlockEditProps } from '@wordpress/blocks';
|
|
464
|
+
import { RichText, useBlockProps } from '@wordpress/block-editor';
|
|
464
465
|
import { Notice } from '@wordpress/components';
|
|
465
466
|
import { __ } from '@wordpress/i18n';
|
|
466
467
|
|
|
@@ -471,13 +472,12 @@ import {
|
|
|
471
472
|
\tvalidate${ childInterfaceName },
|
|
472
473
|
} from './validators';
|
|
473
474
|
|
|
475
|
+
type EditProps = BlockEditProps< ${ childTypeName } >;
|
|
476
|
+
|
|
474
477
|
export default function Edit( {
|
|
475
478
|
\tattributes,
|
|
476
479
|
\tsetAttributes,
|
|
477
|
-
}: {
|
|
478
|
-
\tattributes: ${ childTypeName };
|
|
479
|
-
\tsetAttributes: ( attrs: Partial< ${ childTypeName } > ) => void;
|
|
480
|
-
} ) {
|
|
480
|
+
}: EditProps ) {
|
|
481
481
|
\tconst updateAttribute = createAttributeUpdater( attributes, setAttributes );
|
|
482
482
|
\tconst { errorMessages, isValid } = useTypiaValidation(
|
|
483
483
|
\t\tattributes,
|
|
@@ -25,9 +25,10 @@
|
|
|
25
25
|
"@types/wordpress__block-editor": "^11.5.17",
|
|
26
26
|
"@types/wordpress__blocks": "^12.5.18",
|
|
27
27
|
"@wordpress/browserslist-config": "^6.42.0",
|
|
28
|
-
|
|
28
|
+
"@wordpress/scripts": "^30.22.0",
|
|
29
29
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
30
30
|
"@typia/unplugin": "^12.0.1",
|
|
31
|
+
"prettier": "3.8.2",
|
|
31
32
|
"tsx": "^4.20.5",
|
|
32
33
|
"typescript": "^5.9.2",
|
|
33
34
|
"typia": "^12.0.1"
|