create-wp-typia 0.1.0 → 1.0.1
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 +8 -28
- package/bin/create-wp-typia.js +3 -0
- package/package.json +9 -37
- package/dist/cli.js +0 -87837
- package/dist/highlights-eq9cgrbb.scm +0 -604
- package/dist/highlights-ghv9g403.scm +0 -205
- package/dist/highlights-hk7bwhj4.scm +0 -284
- package/dist/highlights-r812a2qc.scm +0 -150
- package/dist/highlights-x6tmsnaa.scm +0 -115
- package/dist/injections-73j83es3.scm +0 -27
- package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/lib/entry.js +0 -29
- package/lib/node-cli.js +0 -326
- package/lib/package-managers.d.ts +0 -29
- package/lib/package-managers.js +0 -170
- package/lib/scaffold.d.ts +0 -64
- package/lib/scaffold.js +0 -565
- package/lib/template-registry.d.ts +0 -18
- package/lib/template-registry.js +0 -58
- package/src/cli.ts +0 -329
- package/templates/advanced/README.md.mustache +0 -70
- package/templates/advanced/block.json.mustache +0 -42
- package/templates/advanced/index.js +0 -21
- package/templates/advanced/package.json.mustache +0 -48
- package/templates/advanced/scripts/generate-migrations.ts.mustache +0 -267
- package/templates/advanced/scripts/lib/typia-metadata-core.ts +0 -806
- package/templates/advanced/scripts/migration-cli.ts.mustache +0 -260
- package/templates/advanced/scripts/sync-types-to-block-json.ts.mustache +0 -25
- package/templates/advanced/src/admin/migration-dashboard.tsx.mustache +0 -450
- package/templates/advanced/src/components/ErrorBoundary.tsx.mustache +0 -47
- package/templates/advanced/src/deprecated.ts.mustache +0 -184
- package/templates/advanced/src/edit.tsx.mustache +0 -93
- package/templates/advanced/src/hooks/useDebounce.ts.mustache +0 -20
- package/templates/advanced/src/hooks/useLocalStorage.ts.mustache +0 -31
- package/templates/advanced/src/hooks.ts.mustache +0 -56
- package/templates/advanced/src/index.tsx.mustache +0 -16
- package/templates/advanced/src/migration-detector.ts.mustache +0 -417
- package/templates/advanced/src/migrations/index.ts.mustache +0 -361
- package/templates/advanced/src/save.tsx.mustache +0 -40
- package/templates/advanced/src/style.scss.mustache +0 -84
- package/templates/advanced/src/types/versions.ts.mustache +0 -108
- package/templates/advanced/src/types.ts.mustache +0 -45
- package/templates/advanced/src/utils/classnames.ts.mustache +0 -51
- package/templates/advanced/src/utils/debounce.ts.mustache +0 -37
- package/templates/advanced/src/utils/index.ts.mustache +0 -7
- package/templates/advanced/src/utils/uuid.ts.mustache +0 -17
- package/templates/advanced/src/validators.ts.mustache +0 -39
- package/templates/advanced/src/view.ts.mustache +0 -59
- package/templates/advanced/tsconfig.json.mustache +0 -9
- package/templates/advanced/webpack.config.js.mustache +0 -85
- package/templates/basic/package.json.mustache +0 -39
- package/templates/basic/scripts/lib/typia-metadata-core.ts +0 -806
- package/templates/basic/scripts/sync-types-to-block-json.ts +0 -25
- package/templates/basic/src/block.json +0 -51
- package/templates/basic/src/edit.tsx +0 -85
- package/templates/basic/src/hooks.ts +0 -75
- package/templates/basic/src/index.tsx +0 -37
- package/templates/basic/src/save.tsx +0 -27
- package/templates/basic/src/style.scss +0 -42
- package/templates/basic/src/types.ts +0 -47
- package/templates/basic/src/validators.ts +0 -39
- package/templates/basic/tsconfig.json +0 -20
- package/templates/basic/webpack.config.js +0 -85
- package/templates/full/package.json.mustache +0 -40
- package/templates/full/scripts/lib/typia-metadata-core.ts +0 -806
- package/templates/full/scripts/sync-types-to-block-json.ts.mustache +0 -25
- package/templates/full/src/block.json.mustache +0 -121
- package/templates/full/src/edit.tsx.mustache +0 -300
- package/templates/full/src/editor.scss.mustache +0 -251
- package/templates/full/src/hooks.ts.mustache +0 -140
- package/templates/full/src/index.tsx.mustache +0 -27
- package/templates/full/src/save.tsx.mustache +0 -39
- package/templates/full/src/style.scss.mustache +0 -224
- package/templates/full/src/types.ts.mustache +0 -34
- package/templates/full/src/validators.ts.mustache +0 -84
- package/templates/full/tsconfig.json.mustache +0 -9
- package/templates/full/webpack.config.js.mustache +0 -85
- package/templates/interactivity/package.json.mustache +0 -41
- package/templates/interactivity/scripts/lib/typia-metadata-core.ts +0 -806
- package/templates/interactivity/scripts/sync-types-to-block-json.ts.mustache +0 -25
- package/templates/interactivity/src/block.json.mustache +0 -75
- package/templates/interactivity/src/edit.tsx.mustache +0 -206
- package/templates/interactivity/src/interactivity.ts.mustache +0 -183
- package/templates/interactivity/src/save.tsx.mustache +0 -87
- package/templates/interactivity/src/types.ts.mustache +0 -29
- package/templates/interactivity/tsconfig.json.mustache +0 -9
- package/templates/interactivity/webpack.config.js.mustache +0 -85
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { syncBlockMetadata } from "./lib/typia-metadata-core";
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
const result = await syncBlockMetadata({
|
|
5
|
-
blockJsonFile: "src/block.json",
|
|
6
|
-
manifestFile: "src/typia.manifest.json",
|
|
7
|
-
sourceTypeName: "{{pascalCase}}Attributes",
|
|
8
|
-
typesFile: "src/types.ts",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
console.log("✅ block.json and typia.manifest.json were generated from TypeScript types!");
|
|
12
|
-
console.log("📝 Generated attributes:", result.attributeNames);
|
|
13
|
-
|
|
14
|
-
if (result.lossyProjectionWarnings.length > 0) {
|
|
15
|
-
console.warn("⚠️ Some Typia constraints were preserved only in typia.manifest.json:");
|
|
16
|
-
for (const warning of result.lossyProjectionWarnings) {
|
|
17
|
-
console.warn(` - ${warning}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
main().catch((error) => {
|
|
23
|
-
console.error("❌ Type sync failed:", error);
|
|
24
|
-
process.exit(1);
|
|
25
|
-
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://schemas.wp.org/trunk/block.json",
|
|
3
|
-
"apiVersion": 3,
|
|
4
|
-
"name": "{{namespace}}/{{slug}}",
|
|
5
|
-
"version": "0.1.0",
|
|
6
|
-
"title": "{{title}}",
|
|
7
|
-
"category": "text",
|
|
8
|
-
"icon": "smiley",
|
|
9
|
-
"description": "{{description}}",
|
|
10
|
-
"keywords": ["{{keyword}}", "typia", "block"],
|
|
11
|
-
"example": {
|
|
12
|
-
"attributes": {
|
|
13
|
-
"content": "예제 콘텐츠",
|
|
14
|
-
"alignment": "center",
|
|
15
|
-
"isVisible": true
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"supports": {
|
|
19
|
-
"html": false
|
|
20
|
-
},
|
|
21
|
-
"textdomain": "{{textDomain}}",
|
|
22
|
-
"editorScript": "file:./index.js",
|
|
23
|
-
"editorStyle": "file:./index.css",
|
|
24
|
-
"style": "file:./style-index.css",
|
|
25
|
-
"attributes": {
|
|
26
|
-
"content": {
|
|
27
|
-
"type": "string",
|
|
28
|
-
"default": ""
|
|
29
|
-
},
|
|
30
|
-
"alignment": {
|
|
31
|
-
"type": "string",
|
|
32
|
-
"enum": ["left", "center", "right", "justify"],
|
|
33
|
-
"default": "left"
|
|
34
|
-
},
|
|
35
|
-
"className": {
|
|
36
|
-
"type": "string",
|
|
37
|
-
"default": ""
|
|
38
|
-
},
|
|
39
|
-
"isVisible": {
|
|
40
|
-
"type": "boolean",
|
|
41
|
-
"default": true
|
|
42
|
-
},
|
|
43
|
-
"id": {
|
|
44
|
-
"type": "string"
|
|
45
|
-
},
|
|
46
|
-
"version": {
|
|
47
|
-
"type": "number",
|
|
48
|
-
"default": 1
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Editor component for {{title}} Block
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { BlockEditProps } from '@wordpress/blocks';
|
|
6
|
-
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
|
|
7
|
-
import { PanelBody, TextControl, ToggleControl, SelectControl } from '@wordpress/components';
|
|
8
|
-
import { __ } from '@wordpress/i18n';
|
|
9
|
-
import { {{pascalCase}}Attributes } from './types';
|
|
10
|
-
import { validators, createAttributeUpdater } from './validators';
|
|
11
|
-
import { useValidation } from './hooks';
|
|
12
|
-
|
|
13
|
-
type EditProps = BlockEditProps<{{pascalCase}}Attributes>;
|
|
14
|
-
|
|
15
|
-
function Edit({ attributes, setAttributes }: EditProps) {
|
|
16
|
-
const blockProps = useBlockProps();
|
|
17
|
-
const { errors, isValid } = useValidation(attributes, validators.validate);
|
|
18
|
-
const updateAttribute = createAttributeUpdater(
|
|
19
|
-
attributes,
|
|
20
|
-
setAttributes,
|
|
21
|
-
validators.validate
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<>
|
|
26
|
-
<InspectorControls>
|
|
27
|
-
<PanelBody title={__('설정', '{{textDomain}}')}>
|
|
28
|
-
<TextControl
|
|
29
|
-
label={__('콘텐츠', '{{textDomain}}')}
|
|
30
|
-
value={attributes.content || ''}
|
|
31
|
-
onChange={(value) => updateAttribute('content', value)}
|
|
32
|
-
help={__('블록의 메인 콘텐츠입니다.', '{{textDomain}}')}
|
|
33
|
-
/>
|
|
34
|
-
|
|
35
|
-
<SelectControl
|
|
36
|
-
label={__('정렬', '{{textDomain}}')}
|
|
37
|
-
value={attributes.alignment || 'left'}
|
|
38
|
-
options={[
|
|
39
|
-
{ label: __('왼쪽', '{{textDomain}}'), value: 'left' },
|
|
40
|
-
{ label: __('가운데', '{{textDomain}}'), value: 'center' },
|
|
41
|
-
{ label: __('오른쪽', '{{textDomain}}'), value: 'right' },
|
|
42
|
-
{ label: __('양쪽 맞춤', '{{textDomain}}'), value: 'justify' },
|
|
43
|
-
]}
|
|
44
|
-
onChange={(value) => updateAttribute('alignment', value as any)}
|
|
45
|
-
/>
|
|
46
|
-
|
|
47
|
-
<TextControl
|
|
48
|
-
label={__('CSS 클래스', '{{textDomain}}')}
|
|
49
|
-
value={attributes.className || ''}
|
|
50
|
-
onChange={(value) => updateAttribute('className', value)}
|
|
51
|
-
help={__('추가 CSS 클래스를 입력하세요.', '{{textDomain}}')}
|
|
52
|
-
/>
|
|
53
|
-
|
|
54
|
-
<ToggleControl
|
|
55
|
-
label={__('표시하기', '{{textDomain}}')}
|
|
56
|
-
checked={attributes.isVisible !== false}
|
|
57
|
-
onChange={(value) => updateAttribute('isVisible', value)}
|
|
58
|
-
/>
|
|
59
|
-
</PanelBody>
|
|
60
|
-
|
|
61
|
-
{!isValid && (
|
|
62
|
-
<PanelBody title={__('유효성 검증 오류', '{{textDomain}}')} initialOpen>
|
|
63
|
-
{errors.map((error, index) => (
|
|
64
|
-
<div key={index} style={{ color: '#cc1818', fontSize: '12px' }}>
|
|
65
|
-
• {error}
|
|
66
|
-
</div>
|
|
67
|
-
))}
|
|
68
|
-
</PanelBody>
|
|
69
|
-
)}
|
|
70
|
-
</InspectorControls>
|
|
71
|
-
|
|
72
|
-
<div {...blockProps}>
|
|
73
|
-
<div className="wp-block-{{slug}}__content">
|
|
74
|
-
{attributes.content || (
|
|
75
|
-
<span style={{ color: '#757575' }}>
|
|
76
|
-
{__('콘텐츠를 입력하세요...', '{{textDomain}}')}
|
|
77
|
-
</span>
|
|
78
|
-
)}
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
</>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export default Edit;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState, useCallback } from '@wordpress/element';
|
|
2
|
-
import { __ } from '@wordpress/i18n';
|
|
3
|
-
import { {{pascalCase}}Attributes } from './types';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 유효성 검증 훅
|
|
7
|
-
*/
|
|
8
|
-
export function useValidation<T>(
|
|
9
|
-
attributes: T,
|
|
10
|
-
validator: (value: T) => { success: boolean; errors?: any[] }
|
|
11
|
-
) {
|
|
12
|
-
const [errors, setErrors] = useState<string[]>([]);
|
|
13
|
-
const [isValid, setIsValid] = useState(true);
|
|
14
|
-
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
const result = validator(attributes);
|
|
17
|
-
if (result.success) {
|
|
18
|
-
setErrors([]);
|
|
19
|
-
setIsValid(true);
|
|
20
|
-
} else {
|
|
21
|
-
setErrors(result.errors?.map(e => e.path || 'Unknown error') || []);
|
|
22
|
-
setIsValid(false);
|
|
23
|
-
}
|
|
24
|
-
}, [attributes, validator]);
|
|
25
|
-
|
|
26
|
-
return { errors, isValid };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* 디바운스 훅
|
|
31
|
-
*/
|
|
32
|
-
export function useDebounce<T>(value: T, delay: number): T {
|
|
33
|
-
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
const handler = setTimeout(() => {
|
|
37
|
-
setDebouncedValue(value);
|
|
38
|
-
}, delay);
|
|
39
|
-
|
|
40
|
-
return () => {
|
|
41
|
-
clearTimeout(handler);
|
|
42
|
-
};
|
|
43
|
-
}, [value, delay]);
|
|
44
|
-
|
|
45
|
-
return debouncedValue;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 로컬 스토리지 훅
|
|
50
|
-
*/
|
|
51
|
-
export function useLocalStorage<T>(
|
|
52
|
-
key: string,
|
|
53
|
-
initialValue: T
|
|
54
|
-
): [T, (value: T) => void] {
|
|
55
|
-
const [storedValue, setStoredValue] = useState<T>(() => {
|
|
56
|
-
try {
|
|
57
|
-
const item = window.localStorage.getItem(key);
|
|
58
|
-
return item ? JSON.parse(item) : initialValue;
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.error(`Error loading ${key} from localStorage:`, error);
|
|
61
|
-
return initialValue;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const setValue = useCallback((value: T) => {
|
|
66
|
-
try {
|
|
67
|
-
setStoredValue(value);
|
|
68
|
-
window.localStorage.setItem(key, JSON.stringify(value));
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error(`Error saving ${key} to localStorage:`, error);
|
|
71
|
-
}
|
|
72
|
-
}, [key]);
|
|
73
|
-
|
|
74
|
-
return [storedValue, setValue];
|
|
75
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress {{title}} Block
|
|
3
|
-
*
|
|
4
|
-
* Typia 기반 타입 안전 블록
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { registerBlockType } from '@wordpress/blocks';
|
|
8
|
-
import { __ } from '@wordpress/i18n';
|
|
9
|
-
|
|
10
|
-
// Import components
|
|
11
|
-
import Edit from './edit';
|
|
12
|
-
import Save from './save';
|
|
13
|
-
import metadata from './block.json';
|
|
14
|
-
import './style.scss';
|
|
15
|
-
|
|
16
|
-
// Import types
|
|
17
|
-
import { {{pascalCase}}Attributes } from './types';
|
|
18
|
-
import { validators } from './validators';
|
|
19
|
-
|
|
20
|
-
// Register the block
|
|
21
|
-
registerBlockType<{{pascalCase}}Attributes>(metadata.name, {
|
|
22
|
-
title: metadata.title,
|
|
23
|
-
description: metadata.description,
|
|
24
|
-
category: metadata.category as any,
|
|
25
|
-
icon: metadata.icon,
|
|
26
|
-
supports: {
|
|
27
|
-
html: false,
|
|
28
|
-
multiple: true,
|
|
29
|
-
align: ['wide', 'full'],
|
|
30
|
-
},
|
|
31
|
-
attributes: metadata.attributes,
|
|
32
|
-
example: {
|
|
33
|
-
attributes: validators.random(),
|
|
34
|
-
},
|
|
35
|
-
edit: Edit,
|
|
36
|
-
save: Save,
|
|
37
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Save/Frontend component for {{title}} Block
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { useBlockProps } from '@wordpress/block-editor';
|
|
6
|
-
import { {{pascalCase}}Attributes } from './types';
|
|
7
|
-
|
|
8
|
-
interface SaveProps {
|
|
9
|
-
attributes: {{pascalCase}}Attributes;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default function Save({ attributes }: SaveProps) {
|
|
13
|
-
const blockProps = useBlockProps.save();
|
|
14
|
-
|
|
15
|
-
// 블록이 숨겨져 있으면 아무것도 렌더링하지 않음
|
|
16
|
-
if (attributes.isVisible === false) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div {...blockProps}>
|
|
22
|
-
<div className="wp-block-{{slug}}__content">
|
|
23
|
-
{attributes.content}
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* {{title}} Block Styles
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
.wp-block-{{namespace}}-{{slug}} {
|
|
6
|
-
padding: 20px;
|
|
7
|
-
border: 1px solid #ddd;
|
|
8
|
-
border-radius: 4px;
|
|
9
|
-
background-color: #fff;
|
|
10
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
11
|
-
|
|
12
|
-
&__content {
|
|
13
|
-
font-size: 16px;
|
|
14
|
-
line-height: 1.6;
|
|
15
|
-
color: #333;
|
|
16
|
-
|
|
17
|
-
// 정렬 스타일
|
|
18
|
-
&[data-align="center"] {
|
|
19
|
-
text-align: center;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&[data-align="right"] {
|
|
23
|
-
text-align: right;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
&[data-align="justify"] {
|
|
27
|
-
text-align: justify;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// 호버 효과
|
|
32
|
-
&:hover {
|
|
33
|
-
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
34
|
-
transition: box-shadow 0.2s ease;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 에디터에서의 스타일
|
|
38
|
-
.wp-block-editor & {
|
|
39
|
-
outline: 1px dashed #ddd;
|
|
40
|
-
outline-offset: -1px;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { tags } from "typia";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 블록 속성 인터페이스
|
|
5
|
-
* Typia 태그를 사용하여 유효성 검증 규칙 정의
|
|
6
|
-
*/
|
|
7
|
-
export interface {{pascalCase}}Attributes {
|
|
8
|
-
/**
|
|
9
|
-
* 메인 콘텐츠
|
|
10
|
-
*/
|
|
11
|
-
content: string &
|
|
12
|
-
tags.MinLength<1> &
|
|
13
|
-
tags.MaxLength<1000> &
|
|
14
|
-
tags.Default<"">;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 정렬 방식
|
|
18
|
-
*/
|
|
19
|
-
alignment?: ('left' | 'center' | 'right' | 'justify') &
|
|
20
|
-
tags.Default<"left">;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 표시 여부
|
|
24
|
-
*/
|
|
25
|
-
isVisible?: boolean &
|
|
26
|
-
tags.Default<true>;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* 커스텀 CSS 클래스
|
|
30
|
-
*/
|
|
31
|
-
className?: string &
|
|
32
|
-
tags.MaxLength<100> &
|
|
33
|
-
tags.Default<"">;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 고유 ID (자동 생성)
|
|
37
|
-
*/
|
|
38
|
-
id?: string &
|
|
39
|
-
tags.Format<"uuid">;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* 블록 버전 (마이그레이션용)
|
|
43
|
-
*/
|
|
44
|
-
version?: number &
|
|
45
|
-
tags.Type<"uint32"> &
|
|
46
|
-
tags.Default<1>;
|
|
47
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import typia from "typia";
|
|
2
|
-
import { {{pascalCase}}Attributes } from "./types";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Typia 유효성 검증기
|
|
6
|
-
*/
|
|
7
|
-
export const validators = {
|
|
8
|
-
validate: typia.createValidate<{{pascalCase}}Attributes>(),
|
|
9
|
-
assert: typia.createAssert<{{pascalCase}}Attributes>(),
|
|
10
|
-
is: typia.createIs<{{pascalCase}}Attributes>(),
|
|
11
|
-
random: typia.createRandom<{{pascalCase}}Attributes>(),
|
|
12
|
-
clone: typia.misc.createClone<{{pascalCase}}Attributes>(),
|
|
13
|
-
prune: typia.misc.createPrune<{{pascalCase}}Attributes>(),
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 속성 업데이터 생성
|
|
18
|
-
*/
|
|
19
|
-
export function createAttributeUpdater(
|
|
20
|
-
attributes: {{pascalCase}}Attributes,
|
|
21
|
-
setAttributes: (attrs: Partial<{{pascalCase}}Attributes>) => void,
|
|
22
|
-
validator = validators.validate
|
|
23
|
-
) {
|
|
24
|
-
return <K extends keyof {{pascalCase}}Attributes>(
|
|
25
|
-
key: K,
|
|
26
|
-
value: {{pascalCase}}Attributes[K]
|
|
27
|
-
) => {
|
|
28
|
-
const newAttrs = { ...attributes, [key]: value };
|
|
29
|
-
|
|
30
|
-
const validation = validator(newAttrs);
|
|
31
|
-
if (validation.success) {
|
|
32
|
-
setAttributes({ [key]: value } as Partial<{{pascalCase}}Attributes>);
|
|
33
|
-
return true;
|
|
34
|
-
} else {
|
|
35
|
-
console.error(`Validation failed for ${String(key)}:`, validation.errors);
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"jsx": "react-jsx",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"allowSyntheticDefaultImports": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"moduleResolution": "node",
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"isolatedModules": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
"baseUrl": "."
|
|
17
|
-
},
|
|
18
|
-
"include": ["src/**/*"],
|
|
19
|
-
"exclude": ["node_modules", "build"]
|
|
20
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const defaultConfig = require("@wordpress/scripts/config/webpack.config");
|
|
4
|
-
|
|
5
|
-
class TypiaManifestAssetPlugin {
|
|
6
|
-
apply(compiler) {
|
|
7
|
-
compiler.hooks.thisCompilation.tap("TypiaManifestAssetPlugin", (compilation) => {
|
|
8
|
-
compilation.hooks.processAssets.tap(
|
|
9
|
-
{
|
|
10
|
-
name: "TypiaManifestAssetPlugin",
|
|
11
|
-
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
|
|
12
|
-
},
|
|
13
|
-
() => {
|
|
14
|
-
for (const entry of getManifestEntries()) {
|
|
15
|
-
if (compilation.getAsset(entry.outputPath)) {
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
compilation.emitAsset(
|
|
20
|
-
entry.outputPath,
|
|
21
|
-
new compiler.webpack.sources.RawSource(fs.readFileSync(entry.inputPath)),
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getManifestEntries() {
|
|
31
|
-
const entries = [];
|
|
32
|
-
const rootManifestPath = path.resolve(process.cwd(), "typia.manifest.json");
|
|
33
|
-
|
|
34
|
-
if (fs.existsSync(rootManifestPath)) {
|
|
35
|
-
entries.push({
|
|
36
|
-
inputPath: rootManifestPath,
|
|
37
|
-
outputPath: "typia.manifest.json",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const srcDir = path.resolve(process.cwd(), "src");
|
|
42
|
-
if (!fs.existsSync(srcDir)) {
|
|
43
|
-
return entries;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
for (const inputPath of findManifestFiles(srcDir)) {
|
|
47
|
-
entries.push({
|
|
48
|
-
inputPath,
|
|
49
|
-
outputPath: path.relative(srcDir, inputPath),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return entries;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function findManifestFiles(directory) {
|
|
57
|
-
const manifestFiles = [];
|
|
58
|
-
|
|
59
|
-
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
60
|
-
const entryPath = path.join(directory, entry.name);
|
|
61
|
-
|
|
62
|
-
if (entry.isDirectory()) {
|
|
63
|
-
manifestFiles.push(...findManifestFiles(entryPath));
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (entry.isFile() && entry.name === "typia.manifest.json") {
|
|
67
|
-
manifestFiles.push(entryPath);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return manifestFiles;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
module.exports = async () => {
|
|
75
|
-
const { default: UnpluginTypia } = await import("@typia/unplugin/webpack");
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
...defaultConfig,
|
|
79
|
-
plugins: [
|
|
80
|
-
UnpluginTypia(),
|
|
81
|
-
...(defaultConfig.plugins || []),
|
|
82
|
-
new TypiaManifestAssetPlugin(),
|
|
83
|
-
],
|
|
84
|
-
};
|
|
85
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{slugSnakeCase}}",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"packageManager": "bun@1.3.10",
|
|
5
|
-
"description": "{{description}}",
|
|
6
|
-
"author": "{{author}}",
|
|
7
|
-
"license": "GPL-2.0-or-later",
|
|
8
|
-
"main": "build/index.js",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"sync-types": "tsx scripts/sync-types-to-block-json.ts",
|
|
11
|
-
"prebuild": "bun run sync-types",
|
|
12
|
-
"build": "wp-scripts build",
|
|
13
|
-
"start": "bun run sync-types && wp-scripts start",
|
|
14
|
-
"dev": "bun run start",
|
|
15
|
-
"lint:js": "wp-scripts lint-js",
|
|
16
|
-
"lint:css": "wp-scripts lint-style",
|
|
17
|
-
"lint": "bun run lint:js && bun run lint:css",
|
|
18
|
-
"format": "wp-scripts format",
|
|
19
|
-
"typecheck": "tsc --noEmit"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"ajv": "^8.18.0",
|
|
23
|
-
"@types/wordpress__block-editor": "^11.5.17",
|
|
24
|
-
"@types/wordpress__blocks": "^12.5.18",
|
|
25
|
-
"@types/wordpress__components": "^23.8.0",
|
|
26
|
-
"@wordpress/browserslist-config": "^6.42.0",
|
|
27
|
-
"@wordpress/scripts": "^30.22.0",
|
|
28
|
-
"@typia/unplugin": "^12.0.1",
|
|
29
|
-
"tsx": "^4.20.5",
|
|
30
|
-
"typescript": "^5.9.2",
|
|
31
|
-
"typia": "^12.0.1"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"@wordpress/block-editor": "^15.2.0",
|
|
35
|
-
"@wordpress/blocks": "^15.2.0",
|
|
36
|
-
"@wordpress/components": "^30.2.0",
|
|
37
|
-
"@wordpress/element": "^6.29.0",
|
|
38
|
-
"@wordpress/i18n": "^6.2.0"
|
|
39
|
-
}
|
|
40
|
-
}
|