@wp-typia/project-tools 0.23.0 → 0.24.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/dist/runtime/ai-feature-artifacts.js +4 -1
- package/dist/runtime/block-generator-service-spec.js +2 -1
- package/dist/runtime/built-in-block-non-ts-basic-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-basic-artifacts.js +84 -0
- package/dist/runtime/built-in-block-non-ts-compound-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-compound-artifacts.js +36 -0
- package/dist/runtime/built-in-block-non-ts-compound-templates.d.ts +23 -0
- package/dist/runtime/built-in-block-non-ts-compound-templates.js +453 -0
- package/dist/runtime/built-in-block-non-ts-family-artifacts.d.ts +8 -26
- package/dist/runtime/built-in-block-non-ts-family-artifacts.js +8 -1034
- package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.js +83 -0
- package/dist/runtime/built-in-block-non-ts-persistence-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-persistence-artifacts.js +33 -0
- package/dist/runtime/built-in-block-non-ts-persistence-templates.d.ts +23 -0
- package/dist/runtime/built-in-block-non-ts-persistence-templates.js +395 -0
- package/dist/runtime/cli-add-block-json.js +5 -1
- package/dist/runtime/cli-add-collision.js +8 -0
- package/dist/runtime/cli-add-help.js +14 -10
- package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
- package/dist/runtime/cli-add-kind-ids.js +1 -0
- package/dist/runtime/cli-add-types.d.ts +45 -6
- package/dist/runtime/cli-add-types.js +2 -0
- package/dist/runtime/cli-add-validation.d.ts +7 -0
- package/dist/runtime/cli-add-validation.js +9 -0
- package/dist/runtime/cli-add-workspace-ability-anchors.d.ts +24 -0
- package/dist/runtime/cli-add-workspace-ability-anchors.js +294 -0
- package/dist/runtime/cli-add-workspace-ability-registry.d.ts +10 -0
- package/dist/runtime/cli-add-workspace-ability-registry.js +51 -0
- package/dist/runtime/cli-add-workspace-ability-scaffold.d.ts +1 -1
- package/dist/runtime/cli-add-workspace-ability-scaffold.js +5 -308
- package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +6 -2
- package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.d.ts +34 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.js +483 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-default.d.ts +30 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-default.js +310 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-rest.d.ts +25 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-rest.js +124 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-settings.d.ts +34 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-settings.js +370 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-shared.d.ts +49 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates-shared.js +259 -0
- package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +18 -27
- package/dist/runtime/cli-add-workspace-admin-view-templates.js +30 -1326
- package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +4 -4
- package/dist/runtime/cli-add-workspace-ai-anchors.js +8 -233
- package/dist/runtime/cli-add-workspace-ai-scaffold.js +4 -2
- package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +1 -4
- package/dist/runtime/cli-add-workspace-ai-source-emitters.js +1 -129
- package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.d.ts +5 -0
- package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.js +236 -0
- package/dist/runtime/cli-add-workspace-ai-sync-script-source.d.ts +4 -0
- package/dist/runtime/cli-add-workspace-ai-sync-script-source.js +145 -0
- package/dist/runtime/cli-add-workspace-assets.d.ts +6 -63
- package/dist/runtime/cli-add-workspace-assets.js +6 -950
- package/dist/runtime/cli-add-workspace-binding-source-anchors.d.ts +23 -0
- package/dist/runtime/cli-add-workspace-binding-source-anchors.js +112 -0
- package/dist/runtime/cli-add-workspace-binding-source-source-emitters.d.ts +33 -0
- package/dist/runtime/cli-add-workspace-binding-source-source-emitters.js +436 -0
- package/dist/runtime/cli-add-workspace-binding-source-types.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-binding-source-types.js +1 -0
- package/dist/runtime/cli-add-workspace-binding-source.d.ts +40 -0
- package/dist/runtime/cli-add-workspace-binding-source.js +275 -0
- package/dist/runtime/cli-add-workspace-block-style.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-block-style.js +148 -0
- package/dist/runtime/cli-add-workspace-block-transform.d.ts +32 -0
- package/dist/runtime/cli-add-workspace-block-transform.js +197 -0
- package/dist/runtime/cli-add-workspace-contract.js +1 -1
- package/dist/runtime/cli-add-workspace-core-variation.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-core-variation.js +322 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-anchors.d.ts +37 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-anchors.js +206 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.d.ts +47 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.js +219 -0
- package/dist/runtime/cli-add-workspace-editor-plugin.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-editor-plugin.js +78 -0
- package/dist/runtime/cli-add-workspace-hooked-block.d.ts +23 -0
- package/dist/runtime/cli-add-workspace-hooked-block.js +57 -0
- package/dist/runtime/cli-add-workspace-integration-env-files.d.ts +33 -0
- package/dist/runtime/cli-add-workspace-integration-env-files.js +65 -0
- package/dist/runtime/cli-add-workspace-integration-env-package-json.d.ts +38 -0
- package/dist/runtime/cli-add-workspace-integration-env-package-json.js +122 -0
- package/dist/runtime/cli-add-workspace-integration-env-source-emitters.d.ts +44 -0
- package/dist/runtime/cli-add-workspace-integration-env-source-emitters.js +262 -0
- package/dist/runtime/cli-add-workspace-integration-env.d.ts +3 -1
- package/dist/runtime/cli-add-workspace-integration-env.js +10 -313
- package/dist/runtime/cli-add-workspace-pattern-anchors.d.ts +10 -0
- package/dist/runtime/cli-add-workspace-pattern-anchors.js +95 -0
- package/dist/runtime/cli-add-workspace-pattern-options.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-pattern-options.js +113 -0
- package/dist/runtime/cli-add-workspace-pattern-source-emitters.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-pattern-source-emitters.js +57 -0
- package/dist/runtime/cli-add-workspace-pattern.d.ts +42 -0
- package/dist/runtime/cli-add-workspace-pattern.js +99 -0
- package/dist/runtime/cli-add-workspace-post-meta.js +1 -1
- package/dist/runtime/cli-add-workspace-registration-hooks.d.ts +50 -0
- package/dist/runtime/cli-add-workspace-registration-hooks.js +162 -0
- package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +9 -4
- package/dist/runtime/cli-add-workspace-rest-anchors.js +9 -428
- package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.d.ts +17 -0
- package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.js +108 -0
- package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.d.ts +9 -0
- package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.js +142 -0
- package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.d.ts +51 -0
- package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.js +415 -0
- package/dist/runtime/cli-add-workspace-rest-generated.d.ts +9 -0
- package/dist/runtime/cli-add-workspace-rest-generated.js +160 -0
- package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.d.ts +80 -0
- package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.js +238 -0
- package/dist/runtime/cli-add-workspace-rest-manual.d.ts +8 -0
- package/dist/runtime/cli-add-workspace-rest-manual.js +266 -0
- package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +18 -0
- package/dist/runtime/cli-add-workspace-rest-php-templates.js +359 -0
- package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.d.ts +33 -0
- package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.js +145 -0
- package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.d.ts +9 -0
- package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.js +162 -0
- package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.d.ts +7 -0
- package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.js +193 -0
- package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +5 -91
- package/dist/runtime/cli-add-workspace-rest-source-emitters.js +5 -642
- package/dist/runtime/cli-add-workspace-rest-source-utils.d.ts +17 -0
- package/dist/runtime/cli-add-workspace-rest-source-utils.js +50 -0
- package/dist/runtime/cli-add-workspace-rest-sync-script-shared.d.ts +56 -0
- package/dist/runtime/cli-add-workspace-rest-sync-script-shared.js +122 -0
- package/dist/runtime/cli-add-workspace-rest-types.d.ts +108 -0
- package/dist/runtime/cli-add-workspace-rest-types.js +1 -0
- package/dist/runtime/cli-add-workspace-rest.d.ts +3 -20
- package/dist/runtime/cli-add-workspace-rest.js +33 -788
- package/dist/runtime/cli-add-workspace-variation.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-variation.js +162 -0
- package/dist/runtime/cli-add-workspace.d.ts +42 -107
- package/dist/runtime/cli-add-workspace.js +42 -674
- package/dist/runtime/cli-add.d.ts +3 -3
- package/dist/runtime/cli-add.js +2 -2
- package/dist/runtime/cli-core.d.ts +3 -2
- package/dist/runtime/cli-core.js +2 -2
- package/dist/runtime/cli-diagnostics.d.ts +3 -1
- package/dist/runtime/cli-diagnostics.js +17 -5
- package/dist/runtime/cli-doctor-workspace-bindings.js +63 -1
- package/dist/runtime/cli-doctor-workspace-block-addons.d.ts +12 -0
- package/dist/runtime/cli-doctor-workspace-block-addons.js +162 -0
- package/dist/runtime/cli-doctor-workspace-block-iframe.d.ts +9 -0
- package/dist/runtime/cli-doctor-workspace-block-iframe.js +228 -0
- package/dist/runtime/cli-doctor-workspace-block-metadata.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-block-metadata.js +111 -0
- package/dist/runtime/cli-doctor-workspace-blocks.js +6 -424
- package/dist/runtime/cli-doctor-workspace-features-abilities.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-features-abilities.js +112 -0
- package/dist/runtime/cli-doctor-workspace-features-admin-views.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-features-admin-views.js +128 -0
- package/dist/runtime/cli-doctor-workspace-features-ai.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-features-ai.js +57 -0
- package/dist/runtime/cli-doctor-workspace-features-editor-plugins.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-features-editor-plugins.js +80 -0
- package/dist/runtime/cli-doctor-workspace-features-post-meta.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-features-post-meta.js +77 -0
- package/dist/runtime/cli-doctor-workspace-features-rest.d.ts +11 -0
- package/dist/runtime/cli-doctor-workspace-features-rest.js +120 -0
- package/dist/runtime/cli-doctor-workspace-features.js +14 -487
- package/dist/runtime/cli-doctor.d.ts +54 -3
- package/dist/runtime/cli-doctor.js +92 -10
- package/dist/runtime/cli-help.js +12 -7
- package/dist/runtime/cli-init-package-json.js +4 -2
- package/dist/runtime/cli-prompt.d.ts +16 -2
- package/dist/runtime/cli-prompt.js +29 -12
- package/dist/runtime/cli-scaffold.d.ts +2 -1
- package/dist/runtime/cli-scaffold.js +19 -10
- package/dist/runtime/external-template-guards.js +4 -6
- package/dist/runtime/index.d.ts +6 -3
- package/dist/runtime/index.js +4 -2
- package/dist/runtime/json-utils.d.ts +62 -4
- package/dist/runtime/json-utils.js +78 -4
- package/dist/runtime/local-dev-presets.js +6 -2
- package/dist/runtime/migration-ui-capability.js +4 -1
- package/dist/runtime/migration-utils.js +4 -1
- package/dist/runtime/package-managers.js +6 -1
- package/dist/runtime/package-versions.d.ts +1 -0
- package/dist/runtime/package-versions.js +16 -3
- package/dist/runtime/pattern-catalog.d.ts +122 -0
- package/dist/runtime/pattern-catalog.js +471 -0
- package/dist/runtime/post-meta-binding-fields.d.ts +46 -0
- package/dist/runtime/post-meta-binding-fields.js +135 -0
- package/dist/runtime/scaffold-bootstrap.js +7 -2
- package/dist/runtime/scaffold-package-manager-files.js +5 -1
- package/dist/runtime/scaffold-repository-reference.js +4 -2
- package/dist/runtime/scaffold-template-variables.js +2 -1
- package/dist/runtime/scaffold.d.ts +18 -1
- package/dist/runtime/scaffold.js +55 -2
- package/dist/runtime/temp-roots.js +4 -1
- package/dist/runtime/template-layers.js +4 -1
- package/dist/runtime/template-registry.js +9 -3
- package/dist/runtime/template-source-contracts.d.ts +2 -0
- package/dist/runtime/template-source-normalization.js +2 -1
- package/dist/runtime/template-source-remote.js +18 -5
- package/dist/runtime/template-source-seeds.js +10 -3
- package/dist/runtime/typia-llm-json-schema.d.ts +24 -0
- package/dist/runtime/typia-llm-json-schema.js +33 -0
- package/dist/runtime/typia-llm-openapi-constraints.d.ts +20 -0
- package/dist/runtime/typia-llm-openapi-constraints.js +254 -0
- package/dist/runtime/typia-llm-projection.d.ts +25 -0
- package/dist/runtime/typia-llm-projection.js +58 -0
- package/dist/runtime/typia-llm-render.d.ts +21 -0
- package/dist/runtime/typia-llm-render.js +252 -0
- package/dist/runtime/typia-llm-sync.d.ts +10 -0
- package/dist/runtime/typia-llm-sync.js +63 -0
- package/dist/runtime/typia-llm-types.d.ts +197 -0
- package/dist/runtime/typia-llm-types.js +1 -0
- package/dist/runtime/typia-llm.d.ts +9 -255
- package/dist/runtime/typia-llm.js +5 -634
- package/dist/runtime/workspace-inventory-mutations.js +15 -1
- package/dist/runtime/workspace-inventory-parser-entries.d.ts +17 -0
- package/dist/runtime/workspace-inventory-parser-entries.js +157 -0
- package/dist/runtime/workspace-inventory-parser-validation.d.ts +104 -0
- package/dist/runtime/workspace-inventory-parser-validation.js +34 -0
- package/dist/runtime/workspace-inventory-parser.d.ts +3 -45
- package/dist/runtime/workspace-inventory-parser.js +3 -581
- package/dist/runtime/workspace-inventory-section-descriptors.d.ts +19 -0
- package/dist/runtime/workspace-inventory-section-descriptors.js +443 -0
- package/dist/runtime/workspace-inventory-templates.d.ts +3 -3
- package/dist/runtime/workspace-inventory-templates.js +10 -1
- package/dist/runtime/workspace-inventory-types.d.ts +10 -1
- package/dist/runtime/workspace-project.js +4 -6
- package/package.json +8 -3
- package/templates/_shared/compound/core/scripts/block-config.ts.mustache +22 -0
- package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +103 -2
- package/templates/_shared/compound/core/src/inner-blocks-templates.ts.mustache +13 -0
- package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +22 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BuiltInCodeArtifact } from "./built-in-block-code-artifacts.js";
|
|
2
|
+
import type { ScaffoldTemplateVariables } from "./scaffold.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the interactivity family non-TypeScript scaffold artifacts.
|
|
5
|
+
*
|
|
6
|
+
* @param variables Scaffold template variables used to render the artifact set.
|
|
7
|
+
* @returns The SCSS artifacts owned by the interactivity template family.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildInteractivityArtifacts(variables: ScaffoldTemplateVariables): BuiltInCodeArtifact[];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { renderArtifact } from "./built-in-block-non-ts-render-utils.js";
|
|
2
|
+
const INTERACTIVITY_STYLE_TEMPLATE = `.{{cssClassName}} {
|
|
3
|
+
position: relative;
|
|
4
|
+
padding: 1rem;
|
|
5
|
+
border: 1px solid #dcdcde;
|
|
6
|
+
border-radius: 0.75rem;
|
|
7
|
+
background: #fff;
|
|
8
|
+
|
|
9
|
+
&__content {
|
|
10
|
+
display: grid;
|
|
11
|
+
gap: 0.75rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&__counter {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
gap: 0.35rem;
|
|
17
|
+
align-items: center;
|
|
18
|
+
font-size: 0.9rem;
|
|
19
|
+
font-weight: 600;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&__progress {
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: 0.5rem;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
background: #f0f0f1;
|
|
27
|
+
border-radius: 999px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&__progress-bar {
|
|
31
|
+
height: 100%;
|
|
32
|
+
background: #3858e9;
|
|
33
|
+
transition: width 0.2s ease;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&__animation {
|
|
37
|
+
min-height: 1.5rem;
|
|
38
|
+
font-size: 0.85rem;
|
|
39
|
+
color: #3858e9;
|
|
40
|
+
opacity: 0;
|
|
41
|
+
transition: opacity 0.2s ease;
|
|
42
|
+
|
|
43
|
+
&.is-active {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&__completion {
|
|
49
|
+
font-weight: 700;
|
|
50
|
+
color: #06752d;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&__reset {
|
|
54
|
+
align-self: start;
|
|
55
|
+
padding: 0.4rem 0.7rem;
|
|
56
|
+
border: 1px solid #dcdcde;
|
|
57
|
+
border-radius: 999px;
|
|
58
|
+
background: transparent;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
const INTERACTIVITY_EDITOR_STYLE_TEMPLATE = `/**
|
|
64
|
+
* {{title}} Block Editor Styles
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
.{{cssClassName}} {
|
|
68
|
+
outline: 1px dashed #ddd;
|
|
69
|
+
outline-offset: -1px;
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
/**
|
|
73
|
+
* Builds the interactivity family non-TypeScript scaffold artifacts.
|
|
74
|
+
*
|
|
75
|
+
* @param variables Scaffold template variables used to render the artifact set.
|
|
76
|
+
* @returns The SCSS artifacts owned by the interactivity template family.
|
|
77
|
+
*/
|
|
78
|
+
export function buildInteractivityArtifacts(variables) {
|
|
79
|
+
return [
|
|
80
|
+
renderArtifact("src/editor.scss", INTERACTIVITY_EDITOR_STYLE_TEMPLATE, variables),
|
|
81
|
+
renderArtifact("src/style.scss", INTERACTIVITY_STYLE_TEMPLATE, variables),
|
|
82
|
+
];
|
|
83
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BuiltInCodeArtifact } from "./built-in-block-code-artifacts.js";
|
|
2
|
+
import type { ScaffoldTemplateVariables } from "./scaffold.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the persistence family non-TypeScript scaffold artifacts.
|
|
5
|
+
*
|
|
6
|
+
* @param variables Scaffold template variables used to render the artifact set.
|
|
7
|
+
* @returns The persistence SCSS and PHP artifacts for the selected render targets.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildPersistenceArtifacts(variables: ScaffoldTemplateVariables): BuiltInCodeArtifact[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { buildAlternateRenderEntryArtifact, renderArtifact, } from "./built-in-block-non-ts-render-utils.js";
|
|
2
|
+
import { PERSISTENCE_RENDER_TARGETS_TEMPLATE, PERSISTENCE_RENDER_TEMPLATE, PERSISTENCE_STYLE_TEMPLATE, } from "./built-in-block-non-ts-persistence-templates.js";
|
|
3
|
+
import { getScaffoldAlternateRenderTargets } from "./scaffold-template-variable-groups.js";
|
|
4
|
+
/**
|
|
5
|
+
* Builds the persistence family non-TypeScript scaffold artifacts.
|
|
6
|
+
*
|
|
7
|
+
* @param variables Scaffold template variables used to render the artifact set.
|
|
8
|
+
* @returns The persistence SCSS and PHP artifacts for the selected render targets.
|
|
9
|
+
*/
|
|
10
|
+
export function buildPersistenceArtifacts(variables) {
|
|
11
|
+
const alternateRenderTargets = getScaffoldAlternateRenderTargets(variables);
|
|
12
|
+
if (!alternateRenderTargets.enabled) {
|
|
13
|
+
return [
|
|
14
|
+
renderArtifact("src/style.scss", PERSISTENCE_STYLE_TEMPLATE, variables),
|
|
15
|
+
renderArtifact("src/render.php", PERSISTENCE_RENDER_TEMPLATE, variables),
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
const artifacts = [
|
|
19
|
+
renderArtifact("src/style.scss", PERSISTENCE_STYLE_TEMPLATE, variables),
|
|
20
|
+
renderArtifact("src/render-targets.php", PERSISTENCE_RENDER_TARGETS_TEMPLATE, variables),
|
|
21
|
+
buildAlternateRenderEntryArtifact("src/render.php", "web", variables),
|
|
22
|
+
];
|
|
23
|
+
if (alternateRenderTargets.hasEmail) {
|
|
24
|
+
artifacts.push(buildAlternateRenderEntryArtifact("src/render-email.php", "email", variables));
|
|
25
|
+
}
|
|
26
|
+
if (alternateRenderTargets.hasMjml) {
|
|
27
|
+
artifacts.push(buildAlternateRenderEntryArtifact("src/render-mjml.php", "mjml", variables));
|
|
28
|
+
}
|
|
29
|
+
if (alternateRenderTargets.hasPlainText) {
|
|
30
|
+
artifacts.push(buildAlternateRenderEntryArtifact("src/render-text.php", "plain-text", variables));
|
|
31
|
+
}
|
|
32
|
+
return artifacts;
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCSS template for persistence block editor and frontend styles.
|
|
3
|
+
*
|
|
4
|
+
* @remarks Consumed by `buildPersistenceArtifacts()` with
|
|
5
|
+
* `{{cssClassName}}` and `{{frontendCssClassName}}` scaffold placeholders.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PERSISTENCE_STYLE_TEMPLATE = ".{{cssClassName}} {\n\tborder: 1px solid #dcdcde;\n\tborder-radius: 12px;\n\tpadding: 16px;\n\tbackground: #fff;\n\n\t&__meta {\n\t\tcolor: #50575e;\n\t\tfont-size: 13px;\n\t\tmargin: 8px 0 0;\n\t}\n}\n\n.{{frontendCssClassName}} {\n\tdisplay: grid;\n\tgap: 12px;\n\tborder: 1px solid #dcdcde;\n\tborder-radius: 12px;\n\tpadding: 16px;\n\tbackground: #f6f7f7;\n\n\t&__count {\n\t\tdisplay: inline-flex;\n\t\tmin-width: 3rem;\n\t\tjustify-content: center;\n\t\tfont-weight: 700;\n\t}\n\n\t&__notice,\n\t&__error {\n\t\tmargin: 0;\n\t\tfont-size: 13px;\n\t}\n\n\t&__notice {\n\t\tcolor: #50575e;\n\t}\n\n\t&__error {\n\t\tcolor: #b32d2e;\n\t}\n\n\tbutton {\n\t\twidth: fit-content;\n\t}\n}\n";
|
|
8
|
+
/**
|
|
9
|
+
* Main PHP `render.php` template for the persistence block.
|
|
10
|
+
*
|
|
11
|
+
* @remarks Consumed by `buildPersistenceArtifacts()` with scaffold
|
|
12
|
+
* placeholders for block identity, namespace, text domain, storage mode,
|
|
13
|
+
* persistence policy, and frontend CSS class names.
|
|
14
|
+
*/
|
|
15
|
+
export declare const PERSISTENCE_RENDER_TEMPLATE = "<?php\n/**\n * Dynamic render entry for the {{title}} block.\n *\n * @package {{pascalCase}}\n */\n\nif ( ! defined( 'ABSPATH' ) ) {\n\texit;\n}\n\n$validator_path = __DIR__ . '/typia-validator.php';\nif ( ! file_exists( $validator_path ) ) {\n\treturn '';\n}\n\n$validator = require $validator_path;\nif ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {\n\treturn '';\n}\n\n$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );\n$validation = $validator->validate( $normalized );\n$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';\n\nif ( empty( $validation['valid'] ) || '' === $resource_key ) {\n\treturn '';\n}\n\n$alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';\n$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';\n$content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';\n$post_id = is_object( $block ) && isset( $block->context['postId'] )\n\t? (int) $block->context['postId']\n\t: (int) get_queried_object_id();\n$storage_mode = '{{dataStorageMode}}';\n$persistence_policy = '{{persistencePolicy}}';\n\n{{phpPrefix}}_record_rendered_block_instance(\n\t(int) $post_id,\n\t'{{namespace}}/{{slugKebabCase}}',\n\t$resource_key\n);\n\n$notice_message = 'authenticated' === $persistence_policy\n\t? __( 'Sign in to persist this counter.', '{{textDomain}}' )\n\t: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );\n$context = array(\n\t'bootstrapReady' => false,\n\t'buttonLabel' => $button_label,\n\t'canWrite' => false,\n\t'client' => array(\n\t\t'writeExpiry' => 0,\n\t\t'writeNonce' => '',\n\t\t'writeToken' => '',\n\t),\n\t'count' => 0,\n\t'error' => '',\n\t'isBootstrapping' => false,\n\t'isLoading' => false,\n\t'isSaving' => false,\n\t'isVisible' => ! empty( $normalized['isVisible'] ),\n\t'persistencePolicy' => $persistence_policy,\n\t'postId' => (int) $post_id,\n\t'resourceKey' => $resource_key,\n\t'storage' => $storage_mode,\n);\n\n$wrapper_attributes = get_block_wrapper_attributes(\n\tarray(\n\t\t'data-wp-context' => wp_json_encode( $context ),\n\t\t'data-wp-interactive' => '{{slugKebabCase}}',\n\t\t'data-wp-init' => 'callbacks.init',\n\t\t'data-wp-run--mounted' => 'callbacks.mounted',\n\t)\n);\n?>\n\n<div <?php echo $wrapper_attributes; ?>>\n\t<div class=\"{{frontendCssClassName}}\">\n\t\t<p class=\"{{frontendCssClassName}}__content\" style=\"<?php echo esc_attr( 'text-align:' . $alignment ); ?>\">\n\t\t\t<?php echo esc_html( $content ); ?>\n\t\t</p>\n\t\t<p\n\t\t\tclass=\"{{frontendCssClassName}}__notice\"\n\t\t\tdata-wp-bind--hidden=\"!context.bootstrapReady || context.canWrite\"\n\t\t\thidden\n\t\t>\n\t\t\t<?php echo esc_html( $notice_message ); ?>\n\t\t</p>\n\t\t<p\n\t\t\tclass=\"{{frontendCssClassName}}__error\"\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t\taria-atomic=\"true\"\n\t\t\tdata-wp-bind--hidden=\"!context.error\"\n\t\t\tdata-wp-text=\"context.error\"\n\t\t\thidden\n\t\t></p>\n\t\t<?php if ( ! empty( $normalized['showCount'] ) ) : ?>\n\t\t\t<span\n\t\t\t\tclass=\"{{frontendCssClassName}}__count\"\n\t\t\t\trole=\"status\"\n\t\t\t\taria-live=\"polite\"\n\t\t\t\taria-atomic=\"true\"\n\t\t\t\tdata-wp-text=\"context.count\"\n\t\t\t>\n\t\t\t\t0\n\t\t\t</span>\n\t\t<?php endif; ?>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled\n\t\t\tdata-wp-bind--disabled=\"!context.canWrite\"\n\t\t\tdata-wp-on--click=\"actions.increment\"\n\t\t>\n\t\t\t<?php echo esc_html( $button_label ); ?>\n\t\t</button>\n\t</div>\n</div>\n";
|
|
16
|
+
/**
|
|
17
|
+
* PHP helper template for persistence alternate render targets.
|
|
18
|
+
*
|
|
19
|
+
* @remarks Consumed by `buildPersistenceArtifacts()` for email, MJML,
|
|
20
|
+
* plain-text, and web render entries with block identity, namespace, text
|
|
21
|
+
* domain, storage, policy, frontend class, and title placeholders.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PERSISTENCE_RENDER_TARGETS_TEMPLATE = "<?php\n/**\n * Alternate render target helpers for the {{title}} block.\n *\n * @package {{pascalCase}}\n */\n\nif ( ! defined( 'ABSPATH' ) ) {\n\texit;\n}\n\nif ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' ) ) {\n\tfunction {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block ) {\n\t\t$validator_path = __DIR__ . '/typia-validator.php';\n\t\tif ( ! file_exists( $validator_path ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t$validator = require $validator_path;\n\t\tif ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );\n\t\t$validation = $validator->validate( $normalized );\n\t\t$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';\n\n\t\tif ( empty( $validation['valid'] ) || '' === $resource_key ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t$alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';\n\t\t$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';\n\t\t$rendered_content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';\n\t\t$post_id = is_object( $block ) && isset( $block->context['postId'] )\n\t\t\t? (int) $block->context['postId']\n\t\t\t: (int) get_queried_object_id();\n\t\t$storage_mode = '{{dataStorageMode}}';\n\t\t$persistence_policy = '{{persistencePolicy}}';\n\n\t\t{{phpPrefix}}_record_rendered_block_instance(\n\t\t\t(int) $post_id,\n\t\t\t'{{namespace}}/{{slugKebabCase}}',\n\t\t\t$resource_key\n\t\t);\n\n\t\t$notice_message = 'authenticated' === $persistence_policy\n\t\t\t? __( 'Sign in to persist this counter.', '{{textDomain}}' )\n\t\t\t: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );\n\t\t$web_context = array(\n\t\t\t'bootstrapReady' => false,\n\t\t\t'buttonLabel' => $button_label,\n\t\t\t'canWrite' => false,\n\t\t\t'client' => array(\n\t\t\t\t'writeExpiry' => 0,\n\t\t\t\t'writeNonce' => '',\n\t\t\t\t'writeToken' => '',\n\t\t\t),\n\t\t\t'count' => 0,\n\t\t\t'error' => '',\n\t\t\t'isBootstrapping' => false,\n\t\t\t'isLoading' => false,\n\t\t\t'isSaving' => false,\n\t\t\t'isVisible' => ! empty( $normalized['isVisible'] ),\n\t\t\t'persistencePolicy' => $persistence_policy,\n\t\t\t'postId' => (int) $post_id,\n\t\t\t'resourceKey' => $resource_key,\n\t\t\t'storage' => $storage_mode,\n\t\t);\n\n\t\treturn array(\n\t\t\t'alignment' => $alignment,\n\t\t\t'buttonLabel' => $button_label,\n\t\t\t'content' => $rendered_content,\n\t\t\t'frontendClassName' => '{{frontendCssClassName}}',\n\t\t\t'isVisible' => ! empty( $normalized['isVisible'] ),\n\t\t\t'normalized' => $normalized,\n\t\t\t'noticeMessage' => $notice_message,\n\t\t\t'postId' => (int) $post_id,\n\t\t\t'resourceKey' => $resource_key,\n\t\t\t'showCount' => ! empty( $normalized['showCount'] ),\n\t\t\t'title' => {{titleJson}},\n\t\t\t'webContext' => $web_context,\n\t\t);\n\t}\n}\n\nif ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {\n\tfunction {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {\n\t\t$context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );\n\t\tif ( null === $context || empty( $context['isVisible'] ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\t$target_context = apply_filters(\n\t\t\t'{{phpPrefix}}_{{slugSnakeCase}}_render_target_context',\n\t\t\t$context,\n\t\t\t$target,\n\t\t\t$attributes,\n\t\t\t$block\n\t\t);\n\n\t\t$markup = '';\n\t\tswitch ( $target ) {\n\t\t\tcase 'email':\n\t\t\t\t$parts = array(\n\t\t\t\t\t'<div class=\"' . esc_attr( $target_context['frontendClassName'] ) . '-email\">',\n\t\t\t\t\t'<p style=\"text-align:' . esc_attr( $target_context['alignment'] ) . ';\">' . esc_html( $target_context['content'] ) . '</p>',\n\t\t\t\t);\n\t\t\t\tif ( ! empty( $target_context['showCount'] ) ) {\n\t\t\t\t\t$parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';\n\t\t\t\t}\n\t\t\t\t$parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';\n\t\t\t\t$parts[] = '</div>';\n\t\t\t\t$markup = implode( '', $parts );\n\t\t\t\tbreak;\n\t\t\tcase 'mjml':\n\t\t\t\t$markup = '<mjml><mj-body><mj-section><mj-column><mj-text align=\"' . esc_attr( $target_context['alignment'] ) . '\">' . esc_html( $target_context['content'] ) . '</mj-text>';\n\t\t\t\tif ( ! empty( $target_context['showCount'] ) ) {\n\t\t\t\t\t$markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';\n\t\t\t\t}\n\t\t\t\t$markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';\n\t\t\t\tbreak;\n\t\t\tcase 'plain-text':\n\t\t\t\t$markup = implode(\n\t\t\t\t\t\"\\n\",\n\t\t\t\t\tarray_filter(\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t$target_context['title'],\n\t\t\t\t\t\t\t$target_context['content'],\n\t\t\t\t\t\t\t! empty( $target_context['showCount'] )\n\t\t\t\t\t\t\t\t? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )\n\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t$target_context['noticeMessage'],\n\t\t\t\t\t\t),\n\t\t\t\t\t\tstatic fn( $value ) => is_string( $value ) && '' !== $value\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'web':\n\t\t\tdefault:\n\t\t\t\t$wrapper_attributes = get_block_wrapper_attributes(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'data-wp-context' => wp_json_encode( $target_context['webContext'] ),\n\t\t\t\t\t\t'data-wp-interactive' => '{{slugKebabCase}}',\n\t\t\t\t\t\t'data-wp-init' => 'callbacks.init',\n\t\t\t\t\t\t'data-wp-run--mounted' => 'callbacks.mounted',\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t\tob_start();\n\t\t\t\t?>\n<div <?php echo $wrapper_attributes; ?>>\n\t<div class=\"{{frontendCssClassName}}\">\n\t\t<p class=\"{{frontendCssClassName}}__content\" style=\"<?php echo esc_attr( 'text-align:' . $target_context['alignment'] ); ?>\">\n\t\t\t<?php echo esc_html( $target_context['content'] ); ?>\n\t\t</p>\n\t\t<p\n\t\t\tclass=\"{{frontendCssClassName}}__notice\"\n\t\t\tdata-wp-bind--hidden=\"!context.bootstrapReady || context.canWrite\"\n\t\t\thidden\n\t\t>\n\t\t\t<?php echo esc_html( $target_context['noticeMessage'] ); ?>\n\t\t</p>\n\t\t<p\n\t\t\tclass=\"{{frontendCssClassName}}__error\"\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t\taria-atomic=\"true\"\n\t\t\tdata-wp-bind--hidden=\"!context.error\"\n\t\t\tdata-wp-text=\"context.error\"\n\t\t\thidden\n\t\t></p>\n\t\t<?php if ( ! empty( $target_context['showCount'] ) ) : ?>\n\t\t\t<span\n\t\t\t\tclass=\"{{frontendCssClassName}}__count\"\n\t\t\t\trole=\"status\"\n\t\t\t\taria-live=\"polite\"\n\t\t\t\taria-atomic=\"true\"\n\t\t\t\tdata-wp-text=\"context.count\"\n\t\t\t>\n\t\t\t\t0\n\t\t\t</span>\n\t\t<?php endif; ?>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled\n\t\t\tdata-wp-bind--disabled=\"!context.canWrite\"\n\t\t\tdata-wp-on--click=\"actions.increment\"\n\t\t>\n\t\t\t<?php echo esc_html( $target_context['buttonLabel'] ); ?>\n\t\t</button>\n\t</div>\n</div>\n\t\t\t\t<?php\n\t\t\t\t$markup = (string) ob_get_clean();\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn apply_filters(\n\t\t\t'{{phpPrefix}}_{{slugSnakeCase}}_render_target_markup',\n\t\t\t$markup,\n\t\t\t$target,\n\t\t\t$target_context\n\t\t);\n\t}\n}\n";
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCSS template for persistence block editor and frontend styles.
|
|
3
|
+
*
|
|
4
|
+
* @remarks Consumed by `buildPersistenceArtifacts()` with
|
|
5
|
+
* `{{cssClassName}}` and `{{frontendCssClassName}}` scaffold placeholders.
|
|
6
|
+
*/
|
|
7
|
+
export const PERSISTENCE_STYLE_TEMPLATE = `.{{cssClassName}} {
|
|
8
|
+
border: 1px solid #dcdcde;
|
|
9
|
+
border-radius: 12px;
|
|
10
|
+
padding: 16px;
|
|
11
|
+
background: #fff;
|
|
12
|
+
|
|
13
|
+
&__meta {
|
|
14
|
+
color: #50575e;
|
|
15
|
+
font-size: 13px;
|
|
16
|
+
margin: 8px 0 0;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.{{frontendCssClassName}} {
|
|
21
|
+
display: grid;
|
|
22
|
+
gap: 12px;
|
|
23
|
+
border: 1px solid #dcdcde;
|
|
24
|
+
border-radius: 12px;
|
|
25
|
+
padding: 16px;
|
|
26
|
+
background: #f6f7f7;
|
|
27
|
+
|
|
28
|
+
&__count {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
min-width: 3rem;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
font-weight: 700;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&__notice,
|
|
36
|
+
&__error {
|
|
37
|
+
margin: 0;
|
|
38
|
+
font-size: 13px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&__notice {
|
|
42
|
+
color: #50575e;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&__error {
|
|
46
|
+
color: #b32d2e;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
button {
|
|
50
|
+
width: fit-content;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
/**
|
|
55
|
+
* Main PHP `render.php` template for the persistence block.
|
|
56
|
+
*
|
|
57
|
+
* @remarks Consumed by `buildPersistenceArtifacts()` with scaffold
|
|
58
|
+
* placeholders for block identity, namespace, text domain, storage mode,
|
|
59
|
+
* persistence policy, and frontend CSS class names.
|
|
60
|
+
*/
|
|
61
|
+
export const PERSISTENCE_RENDER_TEMPLATE = `<?php
|
|
62
|
+
/**
|
|
63
|
+
* Dynamic render entry for the {{title}} block.
|
|
64
|
+
*
|
|
65
|
+
* @package {{pascalCase}}
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
69
|
+
exit;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
$validator_path = __DIR__ . '/typia-validator.php';
|
|
73
|
+
if ( ! file_exists( $validator_path ) ) {
|
|
74
|
+
return '';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
$validator = require $validator_path;
|
|
78
|
+
if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
83
|
+
$validation = $validator->validate( $normalized );
|
|
84
|
+
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
85
|
+
|
|
86
|
+
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
$alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';
|
|
91
|
+
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
92
|
+
$content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';
|
|
93
|
+
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
94
|
+
? (int) $block->context['postId']
|
|
95
|
+
: (int) get_queried_object_id();
|
|
96
|
+
$storage_mode = '{{dataStorageMode}}';
|
|
97
|
+
$persistence_policy = '{{persistencePolicy}}';
|
|
98
|
+
|
|
99
|
+
{{phpPrefix}}_record_rendered_block_instance(
|
|
100
|
+
(int) $post_id,
|
|
101
|
+
'{{namespace}}/{{slugKebabCase}}',
|
|
102
|
+
$resource_key
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
$notice_message = 'authenticated' === $persistence_policy
|
|
106
|
+
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
107
|
+
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
108
|
+
$context = array(
|
|
109
|
+
'bootstrapReady' => false,
|
|
110
|
+
'buttonLabel' => $button_label,
|
|
111
|
+
'canWrite' => false,
|
|
112
|
+
'client' => array(
|
|
113
|
+
'writeExpiry' => 0,
|
|
114
|
+
'writeNonce' => '',
|
|
115
|
+
'writeToken' => '',
|
|
116
|
+
),
|
|
117
|
+
'count' => 0,
|
|
118
|
+
'error' => '',
|
|
119
|
+
'isBootstrapping' => false,
|
|
120
|
+
'isLoading' => false,
|
|
121
|
+
'isSaving' => false,
|
|
122
|
+
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
123
|
+
'persistencePolicy' => $persistence_policy,
|
|
124
|
+
'postId' => (int) $post_id,
|
|
125
|
+
'resourceKey' => $resource_key,
|
|
126
|
+
'storage' => $storage_mode,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
$wrapper_attributes = get_block_wrapper_attributes(
|
|
130
|
+
array(
|
|
131
|
+
'data-wp-context' => wp_json_encode( $context ),
|
|
132
|
+
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
133
|
+
'data-wp-init' => 'callbacks.init',
|
|
134
|
+
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
?>
|
|
138
|
+
|
|
139
|
+
<div <?php echo $wrapper_attributes; ?>>
|
|
140
|
+
<div class="{{frontendCssClassName}}">
|
|
141
|
+
<p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $alignment ); ?>">
|
|
142
|
+
<?php echo esc_html( $content ); ?>
|
|
143
|
+
</p>
|
|
144
|
+
<p
|
|
145
|
+
class="{{frontendCssClassName}}__notice"
|
|
146
|
+
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
147
|
+
hidden
|
|
148
|
+
>
|
|
149
|
+
<?php echo esc_html( $notice_message ); ?>
|
|
150
|
+
</p>
|
|
151
|
+
<p
|
|
152
|
+
class="{{frontendCssClassName}}__error"
|
|
153
|
+
role="status"
|
|
154
|
+
aria-live="polite"
|
|
155
|
+
aria-atomic="true"
|
|
156
|
+
data-wp-bind--hidden="!context.error"
|
|
157
|
+
data-wp-text="context.error"
|
|
158
|
+
hidden
|
|
159
|
+
></p>
|
|
160
|
+
<?php if ( ! empty( $normalized['showCount'] ) ) : ?>
|
|
161
|
+
<span
|
|
162
|
+
class="{{frontendCssClassName}}__count"
|
|
163
|
+
role="status"
|
|
164
|
+
aria-live="polite"
|
|
165
|
+
aria-atomic="true"
|
|
166
|
+
data-wp-text="context.count"
|
|
167
|
+
>
|
|
168
|
+
0
|
|
169
|
+
</span>
|
|
170
|
+
<?php endif; ?>
|
|
171
|
+
<button
|
|
172
|
+
type="button"
|
|
173
|
+
disabled
|
|
174
|
+
data-wp-bind--disabled="!context.canWrite"
|
|
175
|
+
data-wp-on--click="actions.increment"
|
|
176
|
+
>
|
|
177
|
+
<?php echo esc_html( $button_label ); ?>
|
|
178
|
+
</button>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
`;
|
|
182
|
+
/**
|
|
183
|
+
* PHP helper template for persistence alternate render targets.
|
|
184
|
+
*
|
|
185
|
+
* @remarks Consumed by `buildPersistenceArtifacts()` for email, MJML,
|
|
186
|
+
* plain-text, and web render entries with block identity, namespace, text
|
|
187
|
+
* domain, storage, policy, frontend class, and title placeholders.
|
|
188
|
+
*/
|
|
189
|
+
export const PERSISTENCE_RENDER_TARGETS_TEMPLATE = `<?php
|
|
190
|
+
/**
|
|
191
|
+
* Alternate render target helpers for the {{title}} block.
|
|
192
|
+
*
|
|
193
|
+
* @package {{pascalCase}}
|
|
194
|
+
*/
|
|
195
|
+
|
|
196
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
197
|
+
exit;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' ) ) {
|
|
201
|
+
function {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block ) {
|
|
202
|
+
$validator_path = __DIR__ . '/typia-validator.php';
|
|
203
|
+
if ( ! file_exists( $validator_path ) ) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
$validator = require $validator_path;
|
|
208
|
+
if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
213
|
+
$validation = $validator->validate( $normalized );
|
|
214
|
+
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
215
|
+
|
|
216
|
+
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
$alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';
|
|
221
|
+
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
222
|
+
$rendered_content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';
|
|
223
|
+
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
224
|
+
? (int) $block->context['postId']
|
|
225
|
+
: (int) get_queried_object_id();
|
|
226
|
+
$storage_mode = '{{dataStorageMode}}';
|
|
227
|
+
$persistence_policy = '{{persistencePolicy}}';
|
|
228
|
+
|
|
229
|
+
{{phpPrefix}}_record_rendered_block_instance(
|
|
230
|
+
(int) $post_id,
|
|
231
|
+
'{{namespace}}/{{slugKebabCase}}',
|
|
232
|
+
$resource_key
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
$notice_message = 'authenticated' === $persistence_policy
|
|
236
|
+
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
237
|
+
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
238
|
+
$web_context = array(
|
|
239
|
+
'bootstrapReady' => false,
|
|
240
|
+
'buttonLabel' => $button_label,
|
|
241
|
+
'canWrite' => false,
|
|
242
|
+
'client' => array(
|
|
243
|
+
'writeExpiry' => 0,
|
|
244
|
+
'writeNonce' => '',
|
|
245
|
+
'writeToken' => '',
|
|
246
|
+
),
|
|
247
|
+
'count' => 0,
|
|
248
|
+
'error' => '',
|
|
249
|
+
'isBootstrapping' => false,
|
|
250
|
+
'isLoading' => false,
|
|
251
|
+
'isSaving' => false,
|
|
252
|
+
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
253
|
+
'persistencePolicy' => $persistence_policy,
|
|
254
|
+
'postId' => (int) $post_id,
|
|
255
|
+
'resourceKey' => $resource_key,
|
|
256
|
+
'storage' => $storage_mode,
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
return array(
|
|
260
|
+
'alignment' => $alignment,
|
|
261
|
+
'buttonLabel' => $button_label,
|
|
262
|
+
'content' => $rendered_content,
|
|
263
|
+
'frontendClassName' => '{{frontendCssClassName}}',
|
|
264
|
+
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
265
|
+
'normalized' => $normalized,
|
|
266
|
+
'noticeMessage' => $notice_message,
|
|
267
|
+
'postId' => (int) $post_id,
|
|
268
|
+
'resourceKey' => $resource_key,
|
|
269
|
+
'showCount' => ! empty( $normalized['showCount'] ),
|
|
270
|
+
'title' => {{titleJson}},
|
|
271
|
+
'webContext' => $web_context,
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
277
|
+
function {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {
|
|
278
|
+
$context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );
|
|
279
|
+
if ( null === $context || empty( $context['isVisible'] ) ) {
|
|
280
|
+
return '';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
$target_context = apply_filters(
|
|
284
|
+
'{{phpPrefix}}_{{slugSnakeCase}}_render_target_context',
|
|
285
|
+
$context,
|
|
286
|
+
$target,
|
|
287
|
+
$attributes,
|
|
288
|
+
$block
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
$markup = '';
|
|
292
|
+
switch ( $target ) {
|
|
293
|
+
case 'email':
|
|
294
|
+
$parts = array(
|
|
295
|
+
'<div class="' . esc_attr( $target_context['frontendClassName'] ) . '-email">',
|
|
296
|
+
'<p style="text-align:' . esc_attr( $target_context['alignment'] ) . ';">' . esc_html( $target_context['content'] ) . '</p>',
|
|
297
|
+
);
|
|
298
|
+
if ( ! empty( $target_context['showCount'] ) ) {
|
|
299
|
+
$parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';
|
|
300
|
+
}
|
|
301
|
+
$parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';
|
|
302
|
+
$parts[] = '</div>';
|
|
303
|
+
$markup = implode( '', $parts );
|
|
304
|
+
break;
|
|
305
|
+
case 'mjml':
|
|
306
|
+
$markup = '<mjml><mj-body><mj-section><mj-column><mj-text align="' . esc_attr( $target_context['alignment'] ) . '">' . esc_html( $target_context['content'] ) . '</mj-text>';
|
|
307
|
+
if ( ! empty( $target_context['showCount'] ) ) {
|
|
308
|
+
$markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';
|
|
309
|
+
}
|
|
310
|
+
$markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';
|
|
311
|
+
break;
|
|
312
|
+
case 'plain-text':
|
|
313
|
+
$markup = implode(
|
|
314
|
+
"\\n",
|
|
315
|
+
array_filter(
|
|
316
|
+
array(
|
|
317
|
+
$target_context['title'],
|
|
318
|
+
$target_context['content'],
|
|
319
|
+
! empty( $target_context['showCount'] )
|
|
320
|
+
? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )
|
|
321
|
+
: null,
|
|
322
|
+
$target_context['noticeMessage'],
|
|
323
|
+
),
|
|
324
|
+
static fn( $value ) => is_string( $value ) && '' !== $value
|
|
325
|
+
)
|
|
326
|
+
);
|
|
327
|
+
break;
|
|
328
|
+
case 'web':
|
|
329
|
+
default:
|
|
330
|
+
$wrapper_attributes = get_block_wrapper_attributes(
|
|
331
|
+
array(
|
|
332
|
+
'data-wp-context' => wp_json_encode( $target_context['webContext'] ),
|
|
333
|
+
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
334
|
+
'data-wp-init' => 'callbacks.init',
|
|
335
|
+
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
336
|
+
)
|
|
337
|
+
);
|
|
338
|
+
ob_start();
|
|
339
|
+
?>
|
|
340
|
+
<div <?php echo $wrapper_attributes; ?>>
|
|
341
|
+
<div class="{{frontendCssClassName}}">
|
|
342
|
+
<p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $target_context['alignment'] ); ?>">
|
|
343
|
+
<?php echo esc_html( $target_context['content'] ); ?>
|
|
344
|
+
</p>
|
|
345
|
+
<p
|
|
346
|
+
class="{{frontendCssClassName}}__notice"
|
|
347
|
+
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
348
|
+
hidden
|
|
349
|
+
>
|
|
350
|
+
<?php echo esc_html( $target_context['noticeMessage'] ); ?>
|
|
351
|
+
</p>
|
|
352
|
+
<p
|
|
353
|
+
class="{{frontendCssClassName}}__error"
|
|
354
|
+
role="status"
|
|
355
|
+
aria-live="polite"
|
|
356
|
+
aria-atomic="true"
|
|
357
|
+
data-wp-bind--hidden="!context.error"
|
|
358
|
+
data-wp-text="context.error"
|
|
359
|
+
hidden
|
|
360
|
+
></p>
|
|
361
|
+
<?php if ( ! empty( $target_context['showCount'] ) ) : ?>
|
|
362
|
+
<span
|
|
363
|
+
class="{{frontendCssClassName}}__count"
|
|
364
|
+
role="status"
|
|
365
|
+
aria-live="polite"
|
|
366
|
+
aria-atomic="true"
|
|
367
|
+
data-wp-text="context.count"
|
|
368
|
+
>
|
|
369
|
+
0
|
|
370
|
+
</span>
|
|
371
|
+
<?php endif; ?>
|
|
372
|
+
<button
|
|
373
|
+
type="button"
|
|
374
|
+
disabled
|
|
375
|
+
data-wp-bind--disabled="!context.canWrite"
|
|
376
|
+
data-wp-on--click="actions.increment"
|
|
377
|
+
>
|
|
378
|
+
<?php echo esc_html( $target_context['buttonLabel'] ); ?>
|
|
379
|
+
</button>
|
|
380
|
+
</div>
|
|
381
|
+
</div>
|
|
382
|
+
<?php
|
|
383
|
+
$markup = (string) ob_get_clean();
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return apply_filters(
|
|
388
|
+
'{{phpPrefix}}_{{slugSnakeCase}}_render_target_markup',
|
|
389
|
+
$markup,
|
|
390
|
+
$target,
|
|
391
|
+
$target_context
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
`;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { parseScaffoldBlockMetadata } from "@wp-typia/block-runtime/blocks";
|
|
3
3
|
import { readOptionalUtf8File } from "./fs-async.js";
|
|
4
|
+
import { safeJsonParse } from "./json-utils.js";
|
|
4
5
|
/**
|
|
5
6
|
* Resolve an existing workspace block inventory entry by slug.
|
|
6
7
|
*
|
|
@@ -32,7 +33,10 @@ export async function readWorkspaceBlockJson(projectDir, blockSlug) {
|
|
|
32
33
|
}
|
|
33
34
|
let blockJson;
|
|
34
35
|
try {
|
|
35
|
-
blockJson = parseScaffoldBlockMetadata(
|
|
36
|
+
blockJson = parseScaffoldBlockMetadata(safeJsonParse(source, {
|
|
37
|
+
context: "workspace block metadata",
|
|
38
|
+
filePath: blockJsonPath,
|
|
39
|
+
}));
|
|
36
40
|
}
|
|
37
41
|
catch (error) {
|
|
38
42
|
throw new Error(error instanceof Error
|
|
@@ -90,6 +90,14 @@ const PATTERN_COLLISION_DESCRIPTOR = {
|
|
|
90
90
|
label: "A pattern",
|
|
91
91
|
relativePath: ({ slug }) => path.join("src", "patterns", `${slug}.php`),
|
|
92
92
|
},
|
|
93
|
+
{
|
|
94
|
+
label: "A full pattern",
|
|
95
|
+
relativePath: ({ slug }) => path.join("src", "patterns", "full", `${slug}.php`),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: "A section pattern",
|
|
99
|
+
relativePath: ({ slug }) => path.join("src", "patterns", "sections", `${slug}.php`),
|
|
100
|
+
},
|
|
93
101
|
],
|
|
94
102
|
inventoryCollision: {
|
|
95
103
|
entries: (inventory) => inventory.patterns,
|