@reformer/builder 3.0.0-beta.7 → 3.0.0-beta.8
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/bin/reformer-builder.mjs +1 -1
- package/dist/assets/css/index-CHjtwIsF.css +1 -0
- package/dist/assets/i18n/en-uNov8AYL.js +1 -0
- package/dist/assets/i18n/ru-BNkTKaU6.js +1 -0
- package/dist/assets/js/index-C4LjLCAZ.js +57 -0
- package/dist/assets/monaco/html-DT-eqvPn.js +1 -0
- package/dist/assets/monaco/javascript-CIJHG94Q.js +1 -0
- package/dist/assets/monaco/{jsonMode-C3DAkvde.js → jsonMode-rEmNPnut.js} +3 -3
- package/dist/assets/monaco/{monaco-runtime-DNdOZY7f.js → monaco-runtime-Dqtu7Dpv.js} +137 -137
- package/dist/assets/monaco/typescript-Bp6doald.js +1 -0
- package/dist/assets/monaco/xml-D8D5UF1F.js +1 -0
- package/dist/assets/monaco/yaml-DsiyZy1w.js +1 -0
- package/dist/assets/plugins/{ai-jKAVkXuU.js → ai-CFoGZBd-.js} +36 -36
- package/dist/assets/plugins/{ai-byok-DgeZQTZb.js → ai-byok-a7JlkizL.js} +1 -1
- package/dist/assets/plugins/ai-knowledge-docs-BcbN7Ar1.js +1 -0
- package/dist/assets/plugins/ai-knowledge-index-CncxmxEf.js +1 -0
- package/dist/assets/plugins/codegen-DPh2ynzq.js +520 -0
- package/dist/assets/plugins/{editor-markdown-MarkdownPreview-DyHZvj8H.js → editor-markdown-MarkdownPreview-CjVpNIV5.js} +3 -3
- package/dist/assets/plugins/editor-markdown-McTrLzET.js +2 -0
- package/dist/assets/plugins/editor-monaco-7BM478IS.js +14 -0
- package/dist/assets/plugins/editor-schema-DOoRcy16.js +4 -0
- package/dist/assets/plugins/files-WhQya3nC.js +2 -0
- package/dist/assets/plugins/plain-4ISpXJVh.js +78 -0
- package/dist/assets/plugins/plugin-manager-Ek0Ph0Jj.js +1 -0
- package/dist/assets/plugins/preview-BSh_puVw.js +1 -0
- package/dist/assets/plugins/preview-runtime-B8NzDg53.js +3 -0
- package/dist/assets/plugins/templates-BE9B0S3J.js +2 -0
- package/dist/assets/vendor/{ajv-CCplthOF.js → ajv-N5zGp_lm.js} +1 -1
- package/dist/assets/vendor/calendar-base-BW48REpD-BYc4qqRC.js +1 -0
- package/dist/assets/vendor/carousel-BDyy29mt.js +1 -0
- package/dist/assets/vendor/chart-Cbp9J5YJ.js +52 -0
- package/dist/assets/vendor/collapsible-base-DZxAKbAF-DtQ4867U.js +1 -0
- package/dist/assets/vendor/drawer-BdLrIIeu.js +3 -0
- package/dist/assets/vendor/highlight.js/{common-g0-hl6Ud.js → common-B96EybDa.js} +1 -1
- package/dist/assets/vendor/index-BTAoX623.js +6 -0
- package/dist/assets/vendor/index-D8ACoUqy.js +51 -0
- package/dist/assets/vendor/input-otp-BoPlZ6dt.js +20 -0
- package/dist/assets/vendor/lucide-react/arrow-left-BlVPt6Ag.js +1 -0
- package/dist/assets/vendor/lucide-react/arrow-right-I5ntlq0-.js +1 -0
- package/dist/assets/vendor/lucide-react/calendar-L-57WZlQ.js +1 -0
- package/dist/assets/vendor/lucide-react/eye-DVTIIHcH.js +1 -0
- package/dist/assets/vendor/lucide-react/file-code-corner-DUfMS_yi.js +1 -0
- package/dist/assets/vendor/lucide-react/folder-tree-COyCkaDl.js +1 -0
- package/dist/assets/vendor/lucide-react/minus-zJRYKuAo.js +1 -0
- package/dist/assets/vendor/lucide-react/plus-B0WG2JcM.js +1 -0
- package/dist/assets/vendor/lucide-react/rotate-ccw-BSYk0mux.js +1 -0
- package/dist/assets/vendor/lucide-react/wrench-mybFdWHD.js +1 -0
- package/dist/assets/vendor/message-base-B5jT1FuY-BvDKjuSs.js +1 -0
- package/dist/assets/vendor/message-scroller-B2tlOtxT.js +1 -0
- package/dist/assets/vendor/reformer-builder-stack-reformer/node-token-VfZdCqcs.js +1 -0
- package/dist/assets/vendor/reformer-builder-stack-reformer/paths-DeGLVPUt.js +1 -0
- package/dist/assets/{js/rules-CM1OzesO.js → vendor/reformer-builder-stack-reformer/rules-CQSVDlmo.js} +1 -1
- package/dist/assets/vendor/reformer-builder-stack-reformer/selectors-CjNSFsK9.js +1 -0
- package/dist/assets/vendor/reformer-builder-toolkit/marker-DiOaKX-e.js +4 -0
- package/dist/assets/vendor/reformer-cdk/define-steps-CyGUrx9p-vcI1WbRz.js +1 -0
- package/dist/assets/vendor/reformer-cdk/file-upload-D8FOieMN.js +1 -0
- package/dist/assets/vendor/reformer-cdk/form-array-DlFEb40E.js +1 -0
- package/dist/assets/vendor/reformer-cdk/form-wizard-DDLs_-Ya.js +1 -0
- package/dist/assets/vendor/reformer-cdk/index-CeCSv2Go.js +1 -0
- package/dist/assets/vendor/reformer-cdk/{list-BrqYwhrQ.js → list-DkqJWU70.js} +1 -1
- package/dist/assets/vendor/reformer-form-registry/{index-s1IAa6Lm.js → index-DflpiFcm.js} +1 -1
- package/dist/assets/vendor/reformer-form-registry/loader-BK2c_fCA-BtIEWzon.js +2 -0
- package/dist/assets/vendor/reformer-form-registry/react-BiEQRau3.js +1 -0
- package/dist/assets/vendor/reformer-renderer-json/{validate-C5Gll2Yt.js → validate-DXzHWMfT.js} +1 -1
- package/dist/assets/vendor/reformer-ui-kit/alert-base-WOl_V-qI-2ZIfaT1o.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/calendar-Bm2DDJDU.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/calendar-base.props-CqesU7CZ-tpDaVQbq.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/combobox-Dm4bFCVg.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/combobox-tree.props-BEQhnapq-DQmsBcYk.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/component-catalog-BEv0Zf-R.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/date-picker-CkVXt6Uh.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/date-picker-base.props-WBloFrDq-QhVYMCMG.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/input-otp-base.props-D1xRJiuO-DBKxHsz1.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/meta-YyKXxsBK.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/sidebar-CMzt3bAb.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/skeleton-base-C-lIzi0D-BjmjAmE9.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/toggle-group-multi.props-7kNpujN6-jLENMOcN.js +1 -0
- package/dist/assets/vendor/reformer-ui-kit/tree-node-schema-xHyN0QCr-CLbM_Aw_.js +1 -0
- package/dist/assets/vendor/render-DutGx1TC.js +46 -0
- package/dist/assets/vendor/sheet-base-Bdh947IC-CH2UsjIt.js +1 -0
- package/dist/assets/vendor/typescript/{typescript-Dp5hP5cS.js → typescript-BejA4q8A.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +6 -2
- package/runtime-config.schema.json +23 -1
- package/dist/assets/css/index-DgRudQqc.css +0 -1
- package/dist/assets/i18n/en-DHElWsPO.js +0 -1
- package/dist/assets/i18n/ru-DXsuKRv9.js +0 -1
- package/dist/assets/js/index-BSeq6-8S.js +0 -67
- package/dist/assets/js/index-CQvmAVe0.js +0 -115
- package/dist/assets/js/selectors-BiPlGN2c.js +0 -1
- package/dist/assets/monaco/html-R9lQ-L9C.js +0 -1
- package/dist/assets/monaco/javascript-COUjr2au.js +0 -1
- package/dist/assets/monaco/typescript-CVSiBX9O.js +0 -1
- package/dist/assets/monaco/xml-ee1lph4p.js +0 -1
- package/dist/assets/monaco/yaml-DXPc9WLc.js +0 -1
- package/dist/assets/plugins/ai-knowledge-docs-DCjqodcj.js +0 -1
- package/dist/assets/plugins/ai-knowledge-index-bUfNPqlZ.js +0 -1
- package/dist/assets/plugins/codegen-B0riFOHC.js +0 -416
- package/dist/assets/plugins/editor-markdown-oiBrRpM4.js +0 -2
- package/dist/assets/plugins/editor-schema-CVPAk-MV.js +0 -4
- package/dist/assets/plugins/plugin-manager-BmjjSqYy.js +0 -1
- package/dist/assets/plugins/templates-DNeIl0cD.js +0 -2
- package/dist/assets/vendor/collapsible-base-DZxAKbAF-h07cIL_F.js +0 -1
- package/dist/assets/vendor/index-jGqhTST4.js +0 -6
- package/dist/assets/vendor/lucide-react/eye-COs0olKf.js +0 -1
- package/dist/assets/vendor/lucide-react/file-code-corner-BMVX-Qf1.js +0 -1
- package/dist/assets/vendor/lucide-react/rotate-ccw-D0mVnqJN.js +0 -1
- package/dist/assets/vendor/lucide-react/wrench-BX6KiYsu.js +0 -1
- package/dist/assets/vendor/message-base-B5jT1FuY-GU8TkaN4.js +0 -1
- package/dist/assets/vendor/reformer-cdk/async-boundary-DPu-1Ifi.js +0 -1
- package/dist/assets/vendor/reformer-cdk/define-steps-CyGUrx9p-B_03D9I7.js +0 -1
- package/dist/assets/vendor/reformer-cdk/file-upload-C_DEa-OT.js +0 -1
- package/dist/assets/vendor/reformer-cdk/form-array-DRkRfAUh.js +0 -1
- package/dist/assets/vendor/reformer-cdk/form-wizard-DFqFjH7E.js +0 -1
- package/dist/assets/vendor/reformer-cdk/index-BXFomK5m.js +0 -1
- package/dist/assets/vendor/reformer-form-registry/loader-BK2c_fCA-D59m3JOQ.js +0 -2
- package/dist/assets/vendor/reformer-form-registry/react-B8lbN6s4.js +0 -1
- package/dist/assets/vendor/reformer-ui-kit/alert-base-WOl_V-qI-CYoSap05.js +0 -1
- package/dist/assets/vendor/reformer-ui-kit/component-catalog-BKjWf5Yx.js +0 -1
- /package/dist/assets/{js → vendor/reformer-builder-toolkit}/naming-9aaM0Wbc.js +0 -0
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
import{at as E,ar as z,as as D,aq as B,ay as ie,bm as ae,r as y,j as l,aP as se,aQ as de,aI as I,bn as le,bo as ce,a$ as me,b1 as ue,b2 as pe,bp as P,bq as fe,a7 as ge,br as he,b8 as ve,am as ye,ba as be}from"../js/index-BSeq6-8S.js";import{r as K,s as xe,S as we,p as Ne,w as Se,a as Te,b as W,c as ke,e as je,d as Ee}from"../js/index-CQvmAVe0.js";import{o as J,u as V}from"../vendor/reformer-ui-kit/alert-base-WOl_V-qI-CYoSap05.js";import{F as Re}from"../vendor/lucide-react/file-code-corner-BMVX-Qf1.js";import"../js/rules-CM1OzesO.js";import"../js/naming-9aaM0Wbc.js";const x="// @reformer-generated",Oe=new Set(["ts","tsx","js","jsx","mjs","cjs","mts","cts","css","scss"]);function Fe(e){const t=e.lastIndexOf(".");return t===-1?!1:Oe.has(e.slice(t+1).toLowerCase())}function G(e){let t=2166136261;for(let r=0;r<e.length;r+=1)t^=e.charCodeAt(r),t=Math.imul(t,16777619)>>>0;let n=2646966556;for(let r=e.length-1;r>=0;r-=1)n^=e.charCodeAt(r),n=Math.imul(n,16777619)>>>0;return(t.toString(16).padStart(8,"0")+n.toString(16).padStart(8,"0")).slice(0,12)}function L(e){return e.startsWith(x)?e.slice(e.indexOf(`
|
|
2
|
-
`)+1):e}function U(e){const t=L(e);return`${x} ${G(t)}
|
|
3
|
-
${t}`}function Ie(e){return e==null||!e.startsWith(x)?"handwritten":e.slice(0,e.indexOf(`
|
|
4
|
-
`)).slice(x.length).trim()===G(L(e))?"generated":"edited"}function q(e){return Ie(e)==="generated"}const Ce="./form-schema.schema.json";function Pe(e){const{$schema:t,version:n,...r}=e.schema,a={$schema:t??Ce,version:n??"1.0",...r};return`${JSON.stringify(a,null,2)}
|
|
5
|
-
`}const Me=`// api.ts — заготовка бэкенда (submit). Реализуйте реальные запросы. Пишется один раз.
|
|
6
|
-
|
|
7
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
8
|
-
|
|
9
|
-
export type ApiResult<T> = { success: true; data: T } | { success: false; error: string };
|
|
10
|
-
|
|
11
|
-
const API_DELAY = 600;
|
|
12
|
-
|
|
13
|
-
function wait(ms: number): Promise<void> {
|
|
14
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** POST — отправка формы. TODO: заменить на реальный запрос. */
|
|
18
|
-
export async function submitForm(values: <%= it.names.TypeName %>): Promise<ApiResult<{ id: string }>> {
|
|
19
|
-
await wait(API_DELAY);
|
|
20
|
-
// eslint-disable-next-line no-console
|
|
21
|
-
console.info('[<%= it.names.dir %>] submit', values);
|
|
22
|
-
return { success: true, data: { id: String(Date.now()) } };
|
|
23
|
-
}
|
|
24
|
-
`,$e=`// data-sources.ts — значения $dataSource. МОК: опции из синтеза, замените реальными.
|
|
25
|
-
// Пишется один раз и при регенерации не затирается.
|
|
26
|
-
|
|
27
|
-
<% if (it.dataSources.options.length > 0) { -%>
|
|
28
|
-
import type { SelectOption } from './types';
|
|
29
|
-
|
|
30
|
-
<% } -%>
|
|
31
|
-
<%~ it.blocks([
|
|
32
|
-
it.dataSources.options
|
|
33
|
-
.map((d) => \`export const \${d.name}: SelectOption[] = \${it.json(d.value)};\`)
|
|
34
|
-
.join('\\n\\n'),
|
|
35
|
-
it.dataSources.scalars.map((d) => \`export const \${d.name} = \${d.literal};\`).join('\\n'),
|
|
36
|
-
it.dataSources.labels
|
|
37
|
-
.map((name) => \`export const \${name} = (_item: unknown, index: number): string =>\\n '#' + (index + 1); // TODO: подпись элемента\`)
|
|
38
|
-
.join('\\n'),
|
|
39
|
-
]) %>
|
|
40
|
-
`,_e=`// model.ts — начальные значения (из мока) и фабрика модели. Регенерируется.
|
|
41
|
-
|
|
42
|
-
import { createModel, type FormModel } from '@reformer/core';
|
|
43
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
44
|
-
|
|
45
|
-
export function createInitialValues(): <%= it.names.TypeName %> {
|
|
46
|
-
return <%= it.json(it.mock.model, 2) %> as <%= it.names.TypeName %>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function <%= it.names.modelFactory %>(
|
|
50
|
-
initial?: Partial<<%= it.names.TypeName %>>
|
|
51
|
-
): FormModel<<%= it.names.TypeName %>> {
|
|
52
|
-
return createModel<<%= it.names.TypeName %>>({ ...createInitialValues(), ...initial });
|
|
53
|
-
}
|
|
54
|
-
`,Ae=`// index.tsx — сборка формы одним проходом: createJsonForm → JsonFormRenderer (проп form).
|
|
55
|
-
// Здесь же запись реестра форм. Регенерируется билдером; правки будут перезаписаны.
|
|
56
|
-
|
|
57
|
-
import { useState } from 'react';
|
|
58
|
-
import type { FormEntry } from '@reformer/form-registry';
|
|
59
|
-
import {
|
|
60
|
-
JsonFormRenderer,
|
|
61
|
-
JsonRendererProvider,
|
|
62
|
-
createJsonForm,
|
|
63
|
-
useJsonForm,
|
|
64
|
-
type JsonFormSchema,
|
|
65
|
-
} from '@reformer/renderer-json';
|
|
66
|
-
import rawSchema from './renderer.schema.json';
|
|
67
|
-
import { createRegistry } from './registry';
|
|
68
|
-
import { <%= it.names.modelFactory %> } from './model';
|
|
69
|
-
import { formBehavior } from './form.behavior';
|
|
70
|
-
import { createJsonRenderBehavior } from './renderer.behavior';
|
|
71
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
72
|
-
|
|
73
|
-
type SubmitResult = { message: string; ok: boolean };
|
|
74
|
-
|
|
75
|
-
// В чистом JSON операторы типизируются как \`string\` — приведение к схеме модели формы.
|
|
76
|
-
const typedSchema = rawSchema as unknown as JsonFormSchema<<%= it.names.TypeName %>>;
|
|
77
|
-
|
|
78
|
-
export default function <%= it.names.pageComponent %>() {
|
|
79
|
-
const [result, setResult] = useState<SubmitResult | null>(null);
|
|
80
|
-
|
|
81
|
-
// Сборка ОДНИМ вызовом: model + form + registry + behavior + render-behavior из одной схемы.
|
|
82
|
-
// useJsonForm (ленивый useState) зовёт фабрику ровно один раз, поэтому ссылка на поведение
|
|
83
|
-
// стабильна, а колбэк хоста (onResult) безопасно замыкается прямо здесь.
|
|
84
|
-
const jsonForm = useJsonForm(() =>
|
|
85
|
-
createJsonForm<<%= it.names.TypeName %>>({
|
|
86
|
-
schema: typedSchema,
|
|
87
|
-
registry: createRegistry(),
|
|
88
|
-
model: <%= it.names.modelFactory %>(),
|
|
89
|
-
behavior: formBehavior,
|
|
90
|
-
renderBehavior: (form, model) =>
|
|
91
|
-
createJsonRenderBehavior(form, model, {
|
|
92
|
-
onResult: (message, ok) => setResult({ message, ok }),
|
|
93
|
-
}),
|
|
94
|
-
})
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
<div className="mx-auto max-w-3xl p-6">
|
|
99
|
-
<header className="mb-6">
|
|
100
|
-
<h1 className="text-2xl font-bold"><%= it.names.title %></h1>
|
|
101
|
-
</header>
|
|
102
|
-
|
|
103
|
-
{result && (
|
|
104
|
-
<div
|
|
105
|
-
role="status"
|
|
106
|
-
data-testid="submit-result"
|
|
107
|
-
className={
|
|
108
|
-
'mb-4 rounded-md border p-3 text-sm ' +
|
|
109
|
-
(result.ok
|
|
110
|
-
? 'border-green-300 bg-green-50 text-green-800'
|
|
111
|
-
: 'border-red-300 bg-red-50 text-red-800')
|
|
112
|
-
}
|
|
113
|
-
>
|
|
114
|
-
{result.message}
|
|
115
|
-
</div>
|
|
116
|
-
)}
|
|
117
|
-
|
|
118
|
-
<JsonRendererProvider settings={{ registry: jsonForm.registry }}>
|
|
119
|
-
<JsonFormRenderer<<%= it.names.TypeName %>> form={jsonForm} validateSchema={import.meta.env.DEV} />
|
|
120
|
-
</JsonRendererProvider>
|
|
121
|
-
</div>
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Запись формы «<%= it.names.title %>» в реестре форм.
|
|
127
|
-
*
|
|
128
|
-
* Регистрация в приложении — одна строка:
|
|
129
|
-
* \`\`\`ts
|
|
130
|
-
* import { getFormRegistry } from '@reformer/form-registry';
|
|
131
|
-
* import { <%= it.names.entryConst %> } from './pages/demo/<%= it.names.dir %>';
|
|
132
|
-
*
|
|
133
|
-
* getFormRegistry().register(<%= it.names.entryConst %>);
|
|
134
|
-
* \`\`\`
|
|
135
|
-
*
|
|
136
|
-
* После этого форма монтируется где угодно: \`<FormOutlet id="<%= it.names.exampleId %>" />\`, либо через
|
|
137
|
-
* слот или маршрут, если заполнить \`placement\`.
|
|
138
|
-
*/
|
|
139
|
-
export const <%= it.names.entryConst %>: FormEntry<<%= it.names.TypeName %>> = {
|
|
140
|
-
id: '<%= it.names.exampleId %>',
|
|
141
|
-
version: '1.0.0',
|
|
142
|
-
// Кто зарегистрировал: по этому полю различаются одинаковые id из разных микрофронтов.
|
|
143
|
-
owner: 'app', // TODO: имя вашего приложения-хоста
|
|
144
|
-
|
|
145
|
-
// Данные — единственная часть, которую можно доставить по сети.
|
|
146
|
-
schema: { kind: 'inline', value: typedSchema },
|
|
147
|
-
|
|
148
|
-
// Код — только из бандла.
|
|
149
|
-
registry: { kind: 'inline', value: createRegistry() },
|
|
150
|
-
model: { kind: 'inline', value: <%= it.names.modelFactory %> },
|
|
151
|
-
behavior: { kind: 'inline', value: formBehavior },
|
|
152
|
-
// Адаптер, а не прямая ссылка: у \`createJsonRenderBehavior\` третий параметр — настройки места
|
|
153
|
-
// (\`{ onResult }\`), а реестр третьим отдаёт правила валидации и только четвёртым — настройки
|
|
154
|
-
// хоста. Без переходника это не компилируется, а \`onResult\` не доезжает никогда.
|
|
155
|
-
renderBehavior: {
|
|
156
|
-
kind: 'inline',
|
|
157
|
-
value: (form, model, _validation, options) =>
|
|
158
|
-
createJsonRenderBehavior(
|
|
159
|
-
form,
|
|
160
|
-
model,
|
|
161
|
-
options as { onResult?: (m: string, ok: boolean) => void }
|
|
162
|
-
),
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
// Где показывать. Пусто — форма доступна только по id; заполните, чтобы показывать её
|
|
166
|
-
// в слоте хоста или на маршруте.
|
|
167
|
-
placement: { slots: [], routes: ['<%= it.names.routePath %>'] },
|
|
168
|
-
|
|
169
|
-
meta: {
|
|
170
|
-
name: '<%= it.names.title %>',
|
|
171
|
-
tags: ['renderer-json', 'form-registry'],
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
`,ze="# <%= it.names.title %>\n\nСгенерированная форма (renderer-json). Рендерится и работает сразу на синтетических данных —\n«доведение» сводится к реализации методов в ваших файлах.\n\n## Встраивание\n\nСкопируйте папку в `src/pages/demo/<%= it.names.dir %>/` и зарегистрируйте форму:\n\n```tsx\n<%~ include('codegen.snippet', it) -%>\n```\n\n## Файлы\n\nНабор — канон раскладки renderer-json (`@reformer/mcp` docs/llms/06-form-directory-layout.md §1),\nплоский: без `lib/` и `components/steps/`, запись реестра форм — в `index.tsx`.\n\n- **Регенерируемые** (перезаписываются при повторной генерации): <%= it.files.filter((f) => f.cls === 'derived').map((f) => '`' + f.path + '`').join(', ') %>.\n- **Ваши** (пишутся один раз, не затираются): <%= it.files.filter((f) => f.cls === 'user').map((f) => '`' + f.path + '`').join(', ') %>.\n\nСхема лежит в `renderer.schema.json` — допустимый вариант канона («схема как данные»), выбранный\nради того, чтобы форма открывалась обратно в билдере. Цена — пути `$model(...)` не проверяются на\nкомпиляции: опечатка внутри них останется до рантайма, и никто её не поймает. Нужна проверка —\nпереложите схему в `renderer.schema.ts` литералом `defineJsonSchema<<%= it.names.TypeName %>>({ ... })`;\nправить её в билдере после этого будет нельзя.\n\nКомпоненты импортируются из `<%= it.kit.importSpecifier %>` — того кита, который был\nактивен при генерации (`<%= it.kit.label %>`).\n\n## Методы для реализации\n\n- `api.ts` → `submitForm(values)` — отправка на реальный бэкенд (сейчас `console.info` и успех).\n<% if (it.selectors.sections.length > 0) { -%>\n- `renderer.behavior.ts` → раскомментируйте `hideWhen` для секций: <%= it.selectors.sections.map((s) => '`' + s.selector + '`').join(', ') %>.\n<% } -%>\n<% if (it.dataSources.labels.length > 0) { -%>\n- `data-sources.ts` → подписи элементов массивов: <%= it.dataSources.labels.map((x) => '`' + x + '`').join(', ') %>.\n<% } -%>\n<% if (it.dataSources.options.length > 0) { -%>\n- `data-sources.ts` → замените синтетические опции реальными словарями или загрузчиками.\n<% } -%>\n- `validation.ts` → допишите правила (сейчас — только `required`).\n- `form.behavior.ts` → вычисляемые поля и условное включение (по желанию).\n",De=`// types.ts — тип формы (выведен из схемы и мока). Регенерируется.
|
|
175
|
-
|
|
176
|
-
export type SelectOption = { value: string; label: string };
|
|
177
|
-
|
|
178
|
-
export type <%= it.names.TypeName %> = <%= it.types.text %>;
|
|
179
|
-
`,Be=`<% if (it.rules.validationCode !== null) { -%>
|
|
180
|
-
<%~ it.rules.validationCode -%>
|
|
181
|
-
<% } else { -%>
|
|
182
|
-
// validation.ts — валидация модели. МОК: required выведены из схемы, допишите правила.
|
|
183
|
-
// Пишется один раз и при регенерации не затирается.
|
|
184
|
-
|
|
185
|
-
import { type FormModel } from '@reformer/core';
|
|
186
|
-
<% if (it.required.length > 0) { -%>
|
|
187
|
-
import { validate, defineValidationSchema, validateModel } from '@reformer/core/validation';
|
|
188
|
-
import { required } from '@reformer/core/validators';
|
|
189
|
-
<% } else { -%>
|
|
190
|
-
import { defineValidationSchema, validateModel } from '@reformer/core/validation';
|
|
191
|
-
<% } -%>
|
|
192
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
193
|
-
|
|
194
|
-
type Root = <%= it.names.TypeName %>;
|
|
195
|
-
|
|
196
|
-
<% if (it.required.length > 0) { -%>
|
|
197
|
-
export const formValidation = defineValidationSchema<Root>(({ model }) => {
|
|
198
|
-
<% for (const path of it.required) { -%>
|
|
199
|
-
validate(model.$.<%= path %>, [required({ message: 'Обязательное поле' })]);
|
|
200
|
-
<% } -%>
|
|
201
|
-
});
|
|
202
|
-
<% } else { -%>
|
|
203
|
-
export const formValidation = defineValidationSchema<Root>(() => {
|
|
204
|
-
// TODO: правила валидации
|
|
205
|
-
});
|
|
206
|
-
<% } -%>
|
|
207
|
-
|
|
208
|
-
/** Пошаговый контракт визарда. Полная проверка — validateModel(model, formValidation). */
|
|
209
|
-
export function makeValidationConfig(model: FormModel<Root>) {
|
|
210
|
-
return {
|
|
211
|
-
validateStep: (_step: number): Promise<boolean> => validateModel(model, formValidation),
|
|
212
|
-
validateAll: (): Promise<boolean> => validateModel(model, formValidation),
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
<% } -%>
|
|
216
|
-
`,Ke=`<% if (it.rules.behaviorCode !== null) { -%>
|
|
217
|
-
<%~ it.rules.behaviorCode -%>
|
|
218
|
-
<% } else { -%>
|
|
219
|
-
// form.behavior.ts — реактивное поведение модели (вычисляемые поля, enableWhen, copyFrom).
|
|
220
|
-
// МОК: заготовка, реализуйте по необходимости. Пишется один раз.
|
|
221
|
-
|
|
222
|
-
import { defineFormBehavior } from '@reformer/core/behaviors';
|
|
223
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
224
|
-
|
|
225
|
-
export const formBehavior = defineFormBehavior<<%= it.names.TypeName %>>(() => {});
|
|
226
|
-
|
|
227
|
-
// --- ПРИМЕР ↓ замените объявление выше на такое и оставьте нужные строки ---------------
|
|
228
|
-
// import { defineFormBehavior, compute, computeFrom, copyFrom, enableWhen } from '@reformer/core/behaviors';
|
|
229
|
-
//
|
|
230
|
-
// export const formBehavior = defineFormBehavior<<%= it.names.TypeName %>>(({ model }) => {
|
|
231
|
-
// // model.field — ЗНАЧЕНИЕ поля, model.$.field — его сигнал. Операторы принимают сигналы.
|
|
232
|
-
// compute(model.$.total, () => (model.price ?? 0) * (model.qty ?? 0));
|
|
233
|
-
// computeFrom([model.$.price, model.$.qty], model.$.total, (price, qty) => price * qty);
|
|
234
|
-
// enableWhen(model.$.city, () => model.country !== null);
|
|
235
|
-
// copyFrom(model.$.shippingAddress, model.$.billingAddress, { when: () => model.sameAddress });
|
|
236
|
-
// });
|
|
237
|
-
// --- конец примера ---------------------------------------------------------------------
|
|
238
|
-
<% } -%>
|
|
239
|
-
`,We=`// renderer.wizard.tsx — шим под $component(Wizard) и тело шага. Регенерируется.
|
|
240
|
-
|
|
241
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
242
|
-
import type { ReactNode } from 'react';
|
|
243
|
-
import { <%= it.wizard.symbol %>, type FormWizardStep } from '<%= it.wizard.importFrom %>';
|
|
244
|
-
import type { FormProxy } from '@reformer/core';
|
|
245
|
-
import { RenderNodeComponent, type RenderNode } from '@reformer/renderer-react';
|
|
246
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
247
|
-
|
|
248
|
-
/** Узел шага после конвертации: \`title\`/\`icon\` лежат в его \`componentProps\`. */
|
|
249
|
-
interface StepNode {
|
|
250
|
-
componentProps?: { title?: string; icon?: string; [key: string]: unknown };
|
|
251
|
-
[key: string]: unknown;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export interface WizardProps {
|
|
255
|
-
/** Приходит от рендерера (см. \`__selfManagedChildren\`). */
|
|
256
|
-
form?: FormProxy<<%= it.names.TypeName %>>;
|
|
257
|
-
/** Узлы шагов из \`componentProps.steps\`. */
|
|
258
|
-
steps?: StepNode[];
|
|
259
|
-
className?: string;
|
|
260
|
-
/** Вешается снаружи — renderer.behavior.ts через onComponentEvent(node, 'onSubmit'). */
|
|
261
|
-
onSubmit?: (values: <%= it.names.TypeName %>) => void | Promise<void>;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Визард: узлы шагов из схемы — в шаги кита. Отрисовку тела шага даём пропом
|
|
266
|
-
* \`renderStepBody\`: кит намеренно не зависит от \`@reformer/renderer-react\`.
|
|
267
|
-
*/
|
|
268
|
-
export function Wizard({ form, steps = [], className, onSubmit }: WizardProps): ReactNode {
|
|
269
|
-
const wizardSteps: FormWizardStep<<%= it.names.TypeName %>, RenderNode<<%= it.names.TypeName %>>>[] = steps.map(
|
|
270
|
-
(node, i) => ({
|
|
271
|
-
number: i + 1,
|
|
272
|
-
title: node.componentProps?.title ?? \`Шаг \${i + 1}\`,
|
|
273
|
-
icon: node.componentProps?.icon,
|
|
274
|
-
body: node as any,
|
|
275
|
-
})
|
|
276
|
-
);
|
|
277
|
-
|
|
278
|
-
return (
|
|
279
|
-
<<%= it.wizard.symbol %><<%= it.names.TypeName %>, RenderNode<<%= it.names.TypeName %>>>
|
|
280
|
-
form={form as FormProxy<<%= it.names.TypeName %>>}
|
|
281
|
-
className={className}
|
|
282
|
-
steps={wizardSteps}
|
|
283
|
-
config={{}}
|
|
284
|
-
renderStepBody={(body, wizardForm) => <RenderNodeComponent node={body} form={wizardForm} />}
|
|
285
|
-
onSubmit={onSubmit ? () => onSubmit(form?.getValue() as <%= it.names.TypeName %>) : undefined}
|
|
286
|
-
/>
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Контракт с рендерером: получить \`form\` пропом и сырые \`steps\`, без обхода детей.
|
|
291
|
-
(Wizard as any).__selfManagedChildren = true;
|
|
292
|
-
|
|
293
|
-
export interface StepProps {
|
|
294
|
-
className?: string;
|
|
295
|
-
children?: ReactNode;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Тело шага — компонент под \`$component(Step)\`. Маркер: \`title\`/\`icon\` из его
|
|
300
|
-
* \`componentProps\` снимает \`Wizard\` выше, сюда доезжает только вёрстка.
|
|
301
|
-
*/
|
|
302
|
-
export function <%= it.wizard.stepName %>({ className, children }: StepProps): ReactNode {
|
|
303
|
-
return <div className={className}>{children}</div>;
|
|
304
|
-
}
|
|
305
|
-
`,Je=`// registry.ts — привязка $component/$dataSource к реализациям. Регенерируется.
|
|
306
|
-
|
|
307
|
-
<% if (it.registry.hasPlaceholder) { -%>
|
|
308
|
-
import type { ReactNode } from 'react';
|
|
309
|
-
<% } -%>
|
|
310
|
-
import { <%= it.registry.kitSymbols.join(', ') %> } from '<%= it.kit.importSpecifier %>';
|
|
311
|
-
import { defineRegistry, FIELD_WRAPPER } from '@reformer/renderer-json';
|
|
312
|
-
<% if (it.wizard !== null) { -%>
|
|
313
|
-
import { <% if (it.wizard.hasStep) { %><%= it.wizard.stepName %>, <% } %>Wizard } from './renderer.wizard';
|
|
314
|
-
<% } -%>
|
|
315
|
-
<% if (it.registry.dataSourceNames.length > 0) { -%>
|
|
316
|
-
import { <%= it.registry.dataSourceNames.join(', ') %> } from './data-sources';
|
|
317
|
-
<% } -%>
|
|
318
|
-
<% if (it.registry.hasPlaceholder) { -%>
|
|
319
|
-
|
|
320
|
-
/** Заглушка для компонента без прямого соответствия в ките (замените реальным). */
|
|
321
|
-
const Placeholder = ({ children }: { children?: ReactNode }): ReactNode => children ?? null;
|
|
322
|
-
<% } -%>
|
|
323
|
-
|
|
324
|
-
export function createRegistry() {
|
|
325
|
-
return defineRegistry((reg) => {
|
|
326
|
-
reg.component(FIELD_WRAPPER, <%= it.registry.fieldWrapper %>);
|
|
327
|
-
<% if (it.wizard !== null) { -%>
|
|
328
|
-
// Визард и тело шага — из шима renderer.wizard.tsx.
|
|
329
|
-
<% for (const name of it.wizard.hostNames) { -%>
|
|
330
|
-
reg.component('<%= name %>', Wizard);
|
|
331
|
-
<% } -%>
|
|
332
|
-
<% if (it.wizard.hasStep) { -%>
|
|
333
|
-
reg.component('<%= it.wizard.stepName %>', <%= it.wizard.stepName %>);
|
|
334
|
-
<% } -%>
|
|
335
|
-
<% } -%>
|
|
336
|
-
<% for (const c of it.registry.components) { -%>
|
|
337
|
-
<% if (c.placeholder) { -%>
|
|
338
|
-
reg.component('<%= c.name %>', Placeholder); // TODO: <%= c.reason %>
|
|
339
|
-
<% } else { -%>
|
|
340
|
-
reg.component('<%= c.name %>', <%= c.symbol %>);
|
|
341
|
-
<% } -%>
|
|
342
|
-
<% } -%>
|
|
343
|
-
<% if (it.registry.dataSourceNames.length > 0) { %>
|
|
344
|
-
<% for (const name of it.registry.dataSourceNames) { -%>
|
|
345
|
-
reg.dataSource('<%= name %>', <%= name %>);
|
|
346
|
-
<% } -%>
|
|
347
|
-
<% } -%>
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
`,Ve=`// renderer.behavior.ts — рантайм-обвязка (submit, условная видимость, события узлов).
|
|
351
|
-
|
|
352
|
-
import { <%= it.renderBehavior.imports.join(', ') %>, type RenderBehaviorFn } from '@reformer/renderer-react';
|
|
353
|
-
import { validateModel } from '@reformer/core/validation';
|
|
354
|
-
import type { FormModel, FormProxy } from '@reformer/core';
|
|
355
|
-
import { formValidation } from './validation';
|
|
356
|
-
import { submitForm } from './api';
|
|
357
|
-
import type { <%= it.names.TypeName %> } from './types';
|
|
358
|
-
|
|
359
|
-
export type RenderBehaviorOptions = { onResult?: (message: string, ok: boolean) => void };
|
|
360
|
-
|
|
361
|
-
export function createJsonRenderBehavior(
|
|
362
|
-
form: FormProxy<<%= it.names.TypeName %>>,
|
|
363
|
-
model: FormModel<<%= it.names.TypeName %>>,
|
|
364
|
-
options: RenderBehaviorOptions = {}
|
|
365
|
-
): RenderBehaviorFn<<%= it.names.TypeName %>> {
|
|
366
|
-
const { onResult } = options;
|
|
367
|
-
return (schema) => {
|
|
368
|
-
void form; // используется в условиях hideWhen (form.<поле>.value.value)
|
|
369
|
-
<% if (it.renderBehavior.voidHideWhen) { -%>
|
|
370
|
-
void hideWhen;
|
|
371
|
-
<% } -%>
|
|
372
|
-
|
|
373
|
-
const <%= it.renderBehavior.target %> = schema.node('<%= it.selectors.submitSelector %>');
|
|
374
|
-
<% if (it.renderBehavior.isWizard) { -%>
|
|
375
|
-
|
|
376
|
-
// Визард — self-managed компонент: форму ему передаём явно.
|
|
377
|
-
onInit(<%= it.renderBehavior.target %>, () => <%= it.renderBehavior.target %>.patchProps({ form }));
|
|
378
|
-
<% } -%>
|
|
379
|
-
|
|
380
|
-
onComponentEvent(<%= it.renderBehavior.target %>, '<%= it.selectors.submitEvent %>', async () => {
|
|
381
|
-
// \`touch: true\` обязателен: киты показывают ошибку только у ТРОНУТОГО поля
|
|
382
|
-
// (\`invalid && (touched || dirty)\`). Без него неудачная отправка выглядела бы так,
|
|
383
|
-
// будто кнопка не работает: форма не отправлена, а почему — нигде не сказано.
|
|
384
|
-
if (!(await validateModel(model, formValidation, { touch: true }))) {
|
|
385
|
-
onResult?.('Проверьте заполнение формы', false);
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
const res = await submitForm(model.get());
|
|
389
|
-
onResult?.(res.success ? 'Форма отправлена' : res.error, res.success);
|
|
390
|
-
});
|
|
391
|
-
<% if (it.renderBehavior.rules.length > 0) { %>
|
|
392
|
-
// Правила render-слоя (из правил формы — правьте здесь или в панели правил):
|
|
393
|
-
<% for (const rule of it.renderBehavior.rules) { -%>
|
|
394
|
-
<%~ it.indent(rule.lines, 4) %>
|
|
395
|
-
<% } -%>
|
|
396
|
-
<% } -%>
|
|
397
|
-
<% if (it.renderBehavior.scaffold.length > 0) { %>
|
|
398
|
-
// Условная видимость секций — раскомментируйте и впишите условие:
|
|
399
|
-
<% for (const s of it.renderBehavior.scaffold) { -%>
|
|
400
|
-
// hideWhen(schema.node('<%= s.selector %>'), () => /* TODO: условие для «<%= s.label %>» */ false);
|
|
401
|
-
<% } -%>
|
|
402
|
-
<% } -%>
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
`;function Ge(e){return K(we,xe,{names:e}).replace(/\n$/,"")}const b="---";function v(e){return{ok:!1,message:e}}function T(e,t){if(e!==void 0)return typeof e!="string"||e.trim()===""?new Error(`«${t}» должно быть непустой строкой`):e.trim()}function Le(e){const t=e.replace(/^\uFEFF/,"");if(!t.startsWith(`${b}
|
|
406
|
-
`)&&!t.startsWith(`${b}\r
|
|
407
|
-
`))return v("файл должен начинаться со строки `---` и заголовка за ней");const n=t.indexOf(`
|
|
408
|
-
`)+1,r=t.indexOf(`
|
|
409
|
-
${b}`,n);if(r<0)return v("заголовок не закрыт строкой `---`");const a=t.slice(n,r),o=t.indexOf(`
|
|
410
|
-
`,r+1),i=o<0?"":t.slice(o+1);let d;try{d=JSON.parse(a)}catch(u){return v(`заголовок не разбирается как JSON: ${u.message}`)}if(typeof d!="object"||d===null||Array.isArray(d))return v("заголовок должен быть объектом JSON");const c=d,s=T(c.id,"id");if(s instanceof Error)return v(s.message);if(s===void 0)return v("в заголовке нет «id»");const p=T(c.path,"path");if(p instanceof Error)return v(p.message);if(p===void 0)return v("в заголовке нет «path»");const f=c.cls;if(f!=="derived"&&f!=="user")return v("«cls» должно быть «derived» или «user»");const g=c.order;if(g!==void 0&&(typeof g!="number"||!Number.isFinite(g)))return v("«order» должно быть числом");const m=c.regenerable;if(m!==void 0&&typeof m!="boolean")return v("«regenerable» должно быть true или false");for(const u of["title","overrides","applies"]){const h=T(c[u],u);if(h instanceof Error)return v(h.message)}return{ok:!0,body:i,meta:{id:s,path:p,cls:f,...g===void 0?{}:{order:g},...m===void 0?{}:{regenerable:m},...typeof c.title=="string"?{title:c.title.trim()}:{},...typeof c.overrides=="string"?{overrides:c.overrides.trim()}:{},...typeof c.applies=="string"?{applies:c.applies.trim()}:{}}}}function Ue(e,t){const r=[["id",e.id],...e.overrides===void 0?[]:[["overrides",e.overrides]],["path",e.path],["cls",e.cls],...e.order===void 0?[]:[["order",e.order]],...e.regenerable===void 0?[]:[["regenerable",e.regenerable]],...e.title===void 0?[]:[["title",e.title]],...e.applies===void 0?[]:[["applies",e.applies]]].map(([a,o])=>` ${JSON.stringify(a)}: ${JSON.stringify(o)}`).join(`,
|
|
411
|
-
`);return`${b}
|
|
412
|
-
{
|
|
413
|
-
${r}
|
|
414
|
-
}
|
|
415
|
-
${b}
|
|
416
|
-
${t}`}class w extends Error{constructor(){super("источник не принимает запись"),this.name="SourceReadOnlyError"}}async function qe(e,t,n,r){return X(e,e.resolve(t,n),r)}async function X(e,t,n){const r=e.sourceOf(t);if(r===null||!r.write)throw new w;const a=[],o=[],i=[],d=[];for(const s of n){const p=e.resolve(t,...s.path.split("/"));try{if(s.cls==="user"&&await e.exists(p)){if(!s.regenerable){o.push({path:s.path,reason:"authored"});continue}const f=await e.readText(p);if(!q(f)){o.push({path:s.path,reason:"edited"});continue}}await e.writeText(p,s.content),a.push(s.path),d.push(p)}catch(f){i.push({path:s.path,message:f instanceof Error?f.message:String(f)})}}const c=e.save===void 0||d.length===0?null:await e.save(d);return{dir:t,written:a,skipped:o,failed:i,saved:c}}function Xe(e){return e===""||e.startsWith("/")||e.includes("\\")?!1:!e.split("/").some(t=>t===".."||t==="."||t==="")}function He(e,t){const n=[],r=[],a=new Map;for(const o of e){const i=o.emit!==void 0,d=o.template!==void 0;if(i===d){n.push({targetId:o.id,path:o.path,reason:i?"both-bodies":"no-body",message:i?"цель объявила и emit, и template":"цель не объявила ни emit, ни template"});continue}if(!Xe(o.path)){n.push({targetId:o.id,path:o.path,reason:"escaping-path",message:"путь выходит за каталог модуля"});continue}let c=!0;try{c=o.applies===void 0?!0:o.applies(t)}catch(p){n.push({targetId:o.id,path:o.path,reason:"threw",message:H(p)});continue}if(!c)continue;const s=a.get(o.path);if(s!==void 0){n.push({targetId:o.id,path:o.path,reason:"duplicate-path",message:`файл уже печатает цель «${s}»`});continue}a.set(o.path,o.id),r.push(o)}return{selected:r,problems:n}}function H(e){return e instanceof Error?e.message:String(e)}function Ye(e,t,n){if(e.template!==void 0){const r=e.view?.(t),a=r===void 0?n:ke(n,r);return K(e.id,e.template,a)}if(e.emit!==void 0)return e.emit(t);throw new Error(`цель «${e.id}» без тела дошла до печати`)}async function Y(e,t,n){const r=Ne(t),{selected:a,problems:o}=He(e,r),i=a.map(m=>({path:m.path,cls:m.cls})),d=Se(r,i),c=Te(W(r),i),s=[],p=[];for(const m of a)try{s.push({path:m.path,content:Ye(m,d,c),cls:m.cls,regenerable:m.regenerable===!0,targetId:m.id,origin:m.origin??"builtin"})}catch(u){p.push({targetId:m.id,path:m.path,reason:"threw",message:H(u)})}const f=n===void 0?null:await n(s),g=s.map((m,u)=>{const h=f?.[u]??m.content,S=(m.cls==="derived"||m.regenerable)&&Fe(m.path)?U(h):h;return{...m,content:S}});return{dir:d.names.dir,files:g,problems:[...o,...p],context:d,view:c}}function Q(e){const t=e.ref.name,n=t.indexOf(".");return n<=0?t:t.slice(0,n)}function Z(e){const t=e.model();if(E(t))return t;try{const n=JSON.parse(e.getText());return E(n)?n:null}catch{return null}}async function ee(e){const{host:t,targets:n,documentId:r,store:a}=e,o=t.documentOf(r);if(o===null){a.patch({phase:"idle",errorKey:"error.no-document"});return}const i=Z(o);if(i===null){a.patch({phase:"idle",errorKey:"error.not-a-schema"});return}const d=t.kit();if(d===null){a.patch({phase:"idle",errorKey:"error.no-kit"});return}const c=(e.formName??"").trim()||Q(o);a.patch({phase:"running",errorKey:null,delivery:null});const s=await Y(n,{schema:i,formName:c,kit:{kit:d,catalog:t.catalog()},rules:t.rulesOf?.(r)??void 0},t.format),p=[...e.problems??[],...s.problems],f=s.files.map(m=>({path:m.path,cls:m.cls,targetId:m.targetId,origin:m.origin})),g=Ge(s.context.names);try{const m=await qe(t,t.parentOf(r),s.dir,s.files);a.patch({phase:"idle",formName:c,files:f,snippet:g,problems:p,view:s.view,delivery:m,errorKey:null})}catch(m){if(a.patch({phase:"idle",formName:c,files:f,snippet:g,problems:p,view:s.view,delivery:null,errorKey:m instanceof w?"error.read-only":"error.failed"}),!(m instanceof w))throw m}}const R="codegen.generateInto",k="resource/context/codegen",O="renderer.schema.json",Qe=[".schema.json",".form.json"];function Ze(e){return e===O||Qe.some(t=>e.endsWith(t))}function et(e){return[...e.filter(n=>n.kind==="file"&&Ze(n.name))].sort((n,r)=>n.name===r.name?0:n.name===O?-1:r.name===O?1:n.name.localeCompare(r.name))}async function tt(e,t){if(e.list===void 0)return null;const n=await e.list(t).catch(()=>null);if(n===null)return null;for(const r of et(n)){const a=e.documentOf(r.id);if(a!==null){const i=Z(a);if(i!==null)return{ref:r,schema:i};continue}const o=await e.readText(r.id).catch(()=>null);if(o!==null)try{const i=JSON.parse(o);if(E(i))return{ref:r,schema:i}}catch{}}return null}function nt(e){const t=e.indexOf(".");return t<=0?e:e.slice(0,t)}function j(e,t){if(typeof e!="object"||e===null)return;const n=e[t];return typeof n=="string"&&n!==""?n:void 0}function rt(e){return{dir:j(e,"dir"),targetId:j(e,"targetId"),formName:j(e,"formName")}}async function ot(e,t){const{host:n}=e,r=t.dir;if(r===void 0)return{kind:"no-directory"};if(n.list===void 0)return{kind:"no-listing"};const a=await tt(n,r);if(a===null)return{kind:"no-schema"};const o=n.kit();if(o===null)return{kind:"no-kit"};const i=(t.formName??"").trim()||nt(a.ref.name),d=await Y(e.targets(),{schema:a.schema,formName:i,kit:{kit:o,catalog:n.catalog()},rules:n.rulesOf?.(a.ref.id)??void 0},n.format),c=t.targetId===void 0?d.files:d.files.filter(s=>s.targetId===t.targetId);if(c.length===0&&t.targetId!==void 0)return{kind:"not-applicable",targetId:t.targetId};try{return{kind:"delivered",delivery:await X(n,r,c),formName:i}}catch(s){return s instanceof w?{kind:"read-only"}:{kind:"failed",message:s instanceof Error?s.message:String(s)}}}function it(e,t){if(e!==null)switch(t.kind){case"no-directory":e.warning("codegen.notify.no-directory");return;case"no-listing":e.error("codegen.notify.no-listing");return;case"no-schema":e.warning("codegen.notify.no-schema");return;case"no-kit":e.error("codegen.notify.no-kit");return;case"not-applicable":e.info("codegen.notify.not-applicable");return;case"read-only":e.error("codegen.notify.read-only");return;case"failed":e.error("codegen.notify.failed",{params:{message:t.message}});return;case"delivered":{const{written:n,skipped:r,failed:a}=t.delivery;if(a.length>0){e.error("codegen.notify.partial",{params:{written:n.length,failed:a.length}});return}if(n.length===0){e.info("codegen.notify.nothing-written",{params:{skipped:r.length}});return}e.success("codegen.notify.written",{params:{written:n.length,skipped:r.length}});return}}}function at(e,t){return[{id:R,titleKey:"command.generateInto",async run(n){const r=await ot(e,rt(n));if(it(t,r),r.kind==="delivered"&&r.delivery.written.length===1){const a=r.delivery.written[0];e.host.openResource?.(e.host.resolve(r.delivery.dir,...a.split("/")))}return r.kind==="delivered"}}]}const st=z(e=>e.ref===null||e.ref.kind==="directory");function M(e){return e!==null&&e.kind==="directory"?e.name:void 0}function dt(e){return[{id:"codegen.context.submenu",value:{kind:"submenu",menu:D,submenu:k,titleKey:"menu.generate",group:"4_generate",enabledWhen:st}},{id:"codegen.context.all",value:{kind:"item",menu:k,command:R,group:"1_all",titleKey:"menu.generate.all",argsOf:B(t=>({dir:t.dir,formName:M(t.ref)}))}},{id:"codegen.context.targets",value:{kind:"dynamic",menu:k,group:"2_targets",items:(t,n)=>{const r=ie(n);if(r===null)return[];const a=M(r.ref);return e().map(o=>({id:o.id,command:R,args:{dir:r.dir,targetId:o.id,formName:a},titleKey:o.titleKey,title:o.titleKey===void 0?o.path:void 0}))}}}]}const te=[".ui_builder","codegen"],lt=".eta",ct=Object.freeze({targets:[],problems:[]});function N(e,t){return{targetId:e,path:e,reason:"template-invalid",message:t}}function mt(e){const t=new Function("it",`return (${e});`);return n=>t(W(n))===!0}function ut(e,t){const n=Le(t);if(!n.ok)return N(e,n.message);const{meta:r,body:a}=n;let o;if(r.applies!==void 0)try{o=mt(r.applies)}catch(i){return N(e,`«applies» не компилируется: ${i.message}`)}return{id:r.id,path:r.path,cls:r.cls,template:a,origin:"user",...r.order===void 0?{}:{order:r.order},...r.title===void 0?{}:{title:r.title},...r.overrides===void 0?{}:{overrides:r.overrides},...r.regenerable===void 0?{}:{regenerable:r.regenerable},...o===void 0?{}:{applies:o}}}function pt(e){return"reason"in e}async function ft(e){const t=e.projectRoot?.()??null;if(t===null||e.list===void 0)return ct;const n=e.resolve(t,...te),a=(await e.list(n).catch(()=>[])).filter(s=>s.kind!=="directory"&&s.name.endsWith(lt)).sort((s,p)=>s.name.localeCompare(p.name)),o=[],i=[];for(const s of a){const p=await e.readText(s.id).catch(()=>null);if(p===null){i.push(N(s.name,"файл не читается"));continue}const f=ut(s.name,p);pt(f)?i.push(f):o.push(f)}const d=new Set,c=[];for(const s of o){if(d.has(s.id)){i.push(N(s.path,`цель с id «${s.id}» уже объявлена другим файлом`));continue}d.add(s.id),c.push(s)}return{targets:c,problems:i}}function gt(e){const t=new Set(e.flatMap(n=>n.overrides===void 0?[]:[n.overrides]));return t.size===0?e:e.filter(n=>!t.has(n.id))}function $(e){const n=e.slice(e.lastIndexOf(".")+1).replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return n===""?"target":n}async function ht(e,t,n){let r=`${n}.eta`;for(let a=2;await e.exists(e.resolve(t,r));a+=1)r=`${n}-${a}.eta`;return r}async function vt(e,t){const{host:n}=e,r=e.targets().find(d=>d.id===t);if(r===void 0||r.template===void 0)return{kind:"not-a-template",targetId:t};const a=n.projectRoot?.()??null;if(a===null)return{kind:"no-project"};const o=n.resolve(a,...te),i=n.sourceOf(o);if(i===null||!i.write)return{kind:"read-only"};try{const d=await ht(n,o,$(r.id)),c=n.resolve(o,d),s=r.order,p=Ue({id:`user.${$(r.id)}`,overrides:r.id,path:r.path,cls:r.cls,...s===void 0?{}:{order:s},...r.regenerable===void 0?{}:{regenerable:r.regenerable}},r.template);return await n.writeText(c,p),await n.save?.([c]),{kind:"written",id:c,name:d}}catch(d){return{kind:"failed",message:d instanceof Error?d.message:String(d)}}}function yt(e){return typeof e=="object"&&e!==null&&"root"in e?e:null}async function bt(e,t){const n=e.documentOf(t),r=yt(n?.model());if(n===null||r===null)return{kind:"no-schema"};const a=ae(n.ref.path),o=e.resolveFromRoot;if(a===null||o===void 0)return{kind:"no-target"};if(e.sourceOf(t)?.write!==!0)return{kind:"no-target"};const i=o(t,a),d=await e.readText(i);return d!==null&&!q(d)?{kind:"edited",path:a,id:i}:(await e.writeText(i,U(je(r))),await e.save?.([i]),{kind:"written",path:a,id:i})}const xt={"panel.title":"Export form","command.generate":"Export form to code","form.name":"Form name","form.name.hint":"Directory, type and route names are derived from it.","kit.active":"Kit: {label} ({package})","action.generate":"Generate","action.running":"Generating…","files.title":"Module files","files.derived":"overwritten","files.user":"yours","empty.no-document":"No open document","empty.no-document.detail":"Open a form schema to generate its code.","empty.not-run":"Nothing generated yet","empty.not-run.detail":"The module layout appears after the first run.","result.written":"Files written: {count}","result.skipped":"Skipped (your edits kept): {count}","result.failed":"Not written: {count}","result.saved":"Pushed to the source","result.unsaved":"Kept in the working copy — save the project","skip.authored":"yours, never regenerated","skip.edited":"hand-edited — the marker does not match","problem.threw":"target failed: {message}","problem.duplicate-path":"{message}","problem.escaping-path":"path escapes the module directory","problem.no-body":"target prints nothing: neither emit nor template","problem.both-bodies":"target declares both emit and template — keep one","problem.template-invalid":"{message}","command.refresh-targets":"Reload codegen templates","command.eject-template":"Eject template into project","file.origin.user":"from project","panel.view-data":"Template data (it)","problems.title":"Target failures","snippet.title":"Registration in the app","snippet.copy":"Copy","snippet.copied":"Copied","error.no-document":"The document was closed while generating.","error.not-a-schema":"This document is not a form schema.","error.no-kit":"No kit selected: there is no way to know where to import components from.","error.read-only":"The source refuses writes — there is nowhere to put the module.","error.failed":"Writing the module failed.","command.create-fixture":"Create preview fixture","command.generateInto":"Generate the form module into a directory","menu.generate":"Generate","menu.generate.all":"The whole module","target.schema":"Form schema","target.types":"Types","target.model":"Model","target.registry":"Component registry","target.index":"Entry point","target.wizard":"Wizard shim","target.data-sources":"Data sources","target.render-behavior":"UI behavior","target.form-behavior":"Form behavior","target.validation":"Validation schema","target.api":"Backend","target.readme":"README"},wt={"panel.title":"Экспорт формы","command.generate":"Экспортировать форму в код","form.name":"Имя формы","form.name.hint":"Из него выводятся имя каталога, тип и маршрут.","kit.active":"Кит: {label} ({package})","action.generate":"Сгенерировать","action.running":"Генерируем…","files.title":"Файлы модуля","files.derived":"перезаписывается","files.user":"ваш","empty.no-document":"Нет открытого документа","empty.no-document.detail":"Откройте схему формы, чтобы сгенерировать её код.","empty.not-run":"Прогона ещё не было","empty.not-run.detail":"Состав модуля станет виден после генерации.","result.written":"Записано файлов: {count}","result.skipped":"Пропущено (ваши правки не тронуты): {count}","result.failed":"Не записано: {count}","result.saved":"Отправлено в источник","result.unsaved":"Осталось в рабочей копии — сохраните проект","skip.authored":"ваш файл, регенерации не подлежит","skip.edited":"правлен руками — маркер не сходится","problem.threw":"цель отказала: {message}","problem.duplicate-path":"{message}","problem.escaping-path":"путь выходит за каталог модуля","problem.no-body":"цель не печатает ничего: нет ни emit, ни template","problem.both-bodies":"цель объявила и emit, и template — оставьте одно","problem.template-invalid":"{message}","command.refresh-targets":"Перечитать шаблоны генерации","command.eject-template":"Выгрузить шаблон в проект","file.origin.user":"из проекта","panel.view-data":"Данные шаблона (it)","problems.title":"Отказы целей","snippet.title":"Регистрация в приложении","snippet.copy":"Скопировать","snippet.copied":"Скопировано","error.no-document":"Документ закрыли, пока шла генерация.","error.not-a-schema":"Этот документ не разбирается в схему формы.","error.no-kit":"Кит не выбран: неизвестно, откуда импортировать компоненты.","error.read-only":"Источник не принимает запись — сгенерированное сохранить некуда.","error.failed":"Записать модуль не удалось.","command.create-fixture":"Создать фикстуру предпросмотра","command.generateInto":"Сгенерировать код формы в каталог","menu.generate":"Сгенерировать","menu.generate.all":"Весь модуль","target.schema":"Схема формы","target.types":"Типы","target.model":"Модель","target.registry":"Реестр компонентов","target.index":"Точка входа","target.wizard":"Шим визарда","target.data-sources":"Справочники","target.render-behavior":"Поведение UI","target.form-behavior":"Поведение формы","target.validation":"Схема валидации","target.api":"Бэкенд","target.readme":"README"},Nt=Object.freeze({ru:wt,en:xt}),St=Object.freeze({phase:"idle",formName:"",files:[],snippet:"",problems:[],delivery:null,errorKey:null,view:null});function Tt(){let e=St;const t=new Set;return{get:()=>e,patch(n){e={...e,...n};for(const r of[...t])r()},subscribe(n){return t.add(n),{dispose:()=>{t.delete(n)}}}}}function kt(){const e=new Map;let t=null;return{storeFor(n){const r=e.get(n);if(r!==void 0)return r;const a=Tt();return e.set(n,a),a},active:()=>t,setActive(n){t=n},dispose(){e.clear(),t=null}}}const _=Object.freeze([{id:"codegen.schema",titleKey:"target.schema",path:"renderer.schema.json",cls:"derived",order:10,emit:Pe},{id:"codegen.types",titleKey:"target.types",path:"types.ts",cls:"derived",order:20,template:De},{id:"codegen.model",titleKey:"target.model",path:"model.ts",cls:"derived",order:30,template:_e},{id:"codegen.registry",titleKey:"target.registry",path:"registry.ts",cls:"derived",order:40,template:Je},{id:"codegen.index",titleKey:"target.index",path:"index.tsx",cls:"derived",order:50,template:Ae},{id:"codegen.wizard",titleKey:"target.wizard",path:"renderer.wizard.tsx",cls:"derived",order:60,applies:e=>Ee(e)!==null,template:We},{id:"codegen.data-sources",titleKey:"target.data-sources",path:"data-sources.ts",cls:"user",order:70,template:$e},{id:"codegen.render-behavior",titleKey:"target.render-behavior",path:"renderer.behavior.ts",cls:"user",regenerable:!0,order:80,template:Ve},{id:"codegen.form-behavior",titleKey:"target.form-behavior",path:"form.behavior.ts",cls:"user",regenerable:!0,order:90,template:Ke},{id:"codegen.validation",titleKey:"target.validation",path:"validation.ts",cls:"user",regenerable:!0,order:100,template:Be},{id:"codegen.api",titleKey:"target.api",path:"api.ts",cls:"user",order:110,template:Me},{id:"codegen.readme",titleKey:"target.readme",path:"README.md",cls:"derived",order:120,template:ze}]);function jt({host:e,sessions:t,targets:n,onEject:r,problems:a}){const o=e.useTranslate(),i=e.useActiveDocument();return y.useEffect(()=>{t.setActive(i)},[t,i]),i===null?l.jsx(ne,{title:o("empty.no-document"),detail:o("empty.no-document.detail")}):l.jsx(Rt,{host:e,sessions:t,targets:n,onEject:r,problems:a,documentId:i},i)}function Et(e){return y.useSyncExternalStore(t=>{const n=e.subscribe(t);return()=>{n.dispose()}},()=>e.get())}function Rt({host:e,sessions:t,targets:n,documentId:r,onEject:a,problems:o}){const i=e.useTranslate(),d=t.storeFor(r),c=Et(d),s=e.documentOf(r),p=e.kit(),[f,g]=y.useState(()=>c.formName||(s===null?"":Q(s))),m=y.useCallback(()=>{ee({host:e,targets:n(),documentId:r,store:d,formName:f,problems:o?.()})},[e,n,r,d,f,o]),u=c.phase==="running";return l.jsxs("div",{className:"flex h-full min-h-0 flex-col gap-3 p-3",children:[l.jsxs("div",{className:"flex flex-col gap-1.5",children:[l.jsx(se,{htmlFor:"codegen-form-name",children:i("form.name")}),l.jsx(de,{id:"codegen-form-name","data-testid":"input-formName",value:f,onChange:h=>g(h.target.value)}),l.jsx("span",{className:"text-muted-foreground text-[11px]",children:i("form.name.hint")})]}),p===null?null:l.jsx("span",{className:"text-muted-foreground text-[11px]",children:i("kit.active",{label:p.label,package:p.package})}),l.jsx(I,{size:"sm",disabled:u,onClick:m,"data-testid":"button-generate",children:i(u?"action.running":"action.generate")}),c.errorKey===null?null:l.jsx(J,{variant:"destructive",children:l.jsx(V,{children:i(c.errorKey)})}),l.jsx(le,{}),l.jsx(ce,{className:"min-h-0 flex-1",children:l.jsx(Ft,{state:c,t:i,onEject:a})})]})}function Ot({view:e,t}){const[n,r]=y.useState(!1);return l.jsxs("section",{className:"flex flex-col gap-1",children:[l.jsxs(I,{size:"sm",variant:"ghost",className:"justify-start px-0",onClick:()=>{r(a=>!a)},children:[n?"▾":"▸"," ",t("panel.view-data")]}),n?l.jsx("pre",{className:"bg-muted max-h-64 overflow-auto rounded-md p-2 font-mono text-[11px]",children:JSON.stringify(e,null,2)}):null]})}function Ft({state:e,t,onEject:n}){if(e.files.length===0)return l.jsx(ne,{title:t("empty.not-run"),detail:t("empty.not-run.detail")});const r=e.delivery,a=new Set(r?.written??[]),o=new Map((r?.skipped??[]).map(i=>[i.path,i.reason]));return l.jsxs("div",{className:"flex flex-col gap-3",children:[l.jsxs("section",{className:"flex flex-col gap-1",children:[l.jsx("h3",{className:"text-foreground text-[12px] font-semibold",children:t("files.title")}),e.files.map(i=>{const d=o.get(i.path);return l.jsxs(me,{size:"sm",variant:"muted",children:[l.jsxs(ue,{children:[l.jsx(pe,{className:"font-mono text-[12px]",children:i.path}),d===void 0?null:l.jsx("span",{className:"text-muted-foreground text-[11px]",children:t(`skip.${d}`)})]}),i.origin!=="user"?null:l.jsx(P,{variant:"outline",children:t("file.origin.user")}),l.jsx(P,{variant:a.has(i.path)?"default":"secondary",children:t(`files.${i.cls}`)}),n===void 0?null:l.jsx(I,{size:"sm",variant:"ghost",title:t("command.eject-template"),onClick:()=>{n(i.targetId)},children:"⤓"})]},i.path)})]}),r===null?null:l.jsxs("section",{className:"flex flex-col gap-0.5 text-[11.5px]",children:[l.jsx("span",{children:t("result.written",{count:r.written.length})}),r.skipped.length===0?null:l.jsx("span",{children:t("result.skipped",{count:r.skipped.length})}),r.failed.length===0?null:l.jsx("span",{className:"text-destructive",children:t("result.failed",{count:r.failed.length})}),l.jsx("span",{className:"text-muted-foreground",children:r.saved===!0?t("result.saved"):t("result.unsaved")})]}),e.problems.length===0?null:l.jsxs("section",{className:"flex flex-col gap-1",children:[l.jsx("h3",{className:"text-foreground text-[12px] font-semibold",children:t("problems.title")}),e.problems.map(i=>l.jsx(J,{variant:"destructive",children:l.jsxs(V,{className:"font-mono text-[11px] whitespace-pre-wrap",children:[i.path," — ",t(`problem.${i.reason}`,{message:i.message})]})},`${i.targetId}:${i.path}`))]}),e.view===null?null:l.jsx(Ot,{view:e.view,t}),e.snippet===""?null:l.jsxs("section",{className:"flex flex-col gap-1",children:[l.jsx("h3",{className:"text-foreground text-[12px] font-semibold",children:t("snippet.title")}),l.jsx("pre",{className:"bg-muted overflow-x-auto rounded p-2 font-mono text-[11px]",children:e.snippet})]})]})}function ne({title:e,detail:t}){return l.jsx("div",{className:"flex h-full items-center justify-center p-6",children:l.jsxs("div",{className:"border-border max-w-sm rounded-md border border-dashed p-4 text-center",children:[l.jsx("div",{className:"text-foreground text-[13px] font-medium",children:e}),l.jsx("div",{className:"text-muted-foreground mt-1 text-[12px]",children:t})]})})}const It="codegen.panel",re="codegen.generate",Ct="codegen.create-fixture",Pt="codegen.refresh-targets",oe="codegen.eject-template",Mt=1e3,$t="panel.right",_t=new Set(["form.schema","application/json"]),At=()=>y.createElement(Re,{className:"size-4"});function F(e){return e.activeResourceKind!==null&&_t.has(e.activeResourceKind)}function zt(e,t,n,r,a,o){return{id:It,slot:r,titleKey:"panel.title",icon:At,when:F,order:20,Body:()=>y.createElement(jt,{host:e,sessions:t,targets:n,onEject:a,problems:o})}}function A(e){if(typeof e!="object"||e===null)return null;const t=e.documentId;return typeof t=="string"?t:null}function Dt(e){return[{id:"codegen.context.generate",value:{kind:"item",menu:D,command:re,group:"4_generate",when:z(t=>t.ref!==null&&e.documentOf(t.ref.id)!==null),argsOf:B(t=>({documentId:t.ref?.id}))}}]}function Bt(e,t,n,r=()=>[]){return[{id:re,titleKey:"command.generate",enabled:F,run(a){const o=A(a)??t.active();if(o===null)return;const i=t.storeFor(o);ee({host:e,targets:n(),documentId:o,store:i,formName:i.get().formName,problems:r()})}},{id:Ct,titleKey:"command.create-fixture",enabled:F,run(a){const o=A(a)??t.active();o!==null&&bt(e,o).then(i=>{Vt(e,i)})}}]}function Kt(e,t,n,r){return[{id:Pt,titleKey:"command.refresh-targets",run(){n().then(a=>{r?.info("codegen.notify.targets-refreshed",{params:{count:a}})})}},{id:oe,titleKey:"command.eject-template",run(a){const o=Wt(a);o!==null&&vt({host:e,targets:t},o).then(async i=>{Jt(r,i),i.kind==="written"&&(await n(),e.openResource?.(i.id))})}}]}function Wt(e){if(typeof e!="object"||e===null)return null;const t=e.targetId;return typeof t=="string"?t:null}function Jt(e,t){if(e!==null)switch(t.kind){case"written":e.success("codegen.notify.eject-written",{params:{name:t.name}});return;case"no-project":e.warning("codegen.notify.eject-no-project");return;case"not-a-template":e.info("codegen.notify.eject-not-a-template");return;case"read-only":e.error("codegen.notify.eject-read-only");return;case"failed":e.error("codegen.notify.eject-failed",{params:{message:t.message}});return}}function Vt(e,t){if(t.kind==="written"){e.openResource?.(t.id);return}console.info("[codegen] фикстура не создана:",t.kind)}function Yt(e){const{host:t}=e,n=e.targetPoint??fe,r=e.slot??$t,a=kt();return ge({id:he,activate(o){for(const[u,h]of Object.entries(Nt))e.i18n?.contribute(u,h);const i=()=>gt(o.extensions.get(n).map(u=>u.value));let d=[],c=[];const s=()=>{for(const u of d)u.dispose();d=[]},p=async()=>{s();const u=await ft(t);c=u.problems;for(const h of u.targets){const C=_.find(S=>S.id===h.overrides)?.order;d.push(o.extensions.contribute(n,h,{id:`user:${h.id}`,order:h.order??C??Mt}))}return u.targets.length};o.subscriptions.push({dispose:s}),p(),o.subscriptions.push(t.onDidChangeKit(()=>{p()}));for(const u of _)o.subscriptions.push(o.extensions.contribute(n,u,{id:u.id,order:u.order}));for(const u of Bt(t,a,i,()=>c))o.subscriptions.push(o.commands.register(u));const f={host:t,targets:i},g=o.services.get(ve)??null;for(const u of Kt(t,i,p,g))o.subscriptions.push(o.commands.register(u));for(const u of at(f,g))o.subscriptions.push(o.commands.register(u));for(const u of[...Dt(t),...dt(i)])o.subscriptions.push(o.extensions.contribute(ye,u.value,{id:u.id}));const m=zt(t,a,i,r,u=>{o.commands.get(oe)?.run({targetId:u})},()=>c);o.subscriptions.push(o.extensions.contribute(be,m,{id:m.id}))},deactivate(){a.dispose()}})}export{_ as BUILTIN_TARGETS,k as CODEGEN_CONTEXT_SUBMENU,Nt as CODEGEN_MESSAGES,It as CODEGEN_PANEL_ID,he as CODEGEN_PLUGIN_ID,fe as CodegenTargetPoint,$t as DEFAULT_CODEGEN_SLOT,re as GENERATE_COMMAND_ID,R as GENERATE_INTO_COMMAND_ID,w as SourceReadOnlyError,Bt as codegenCommands,at as codegenContextCommands,dt as codegenContextMenuItems,Dt as codegenDocumentMenuItems,zt as codegenPanel,Yt as createCodegenPlugin,Q as defaultFormName,X as deliverInto,qe as deliverModule,tt as findSchemaIn,ot as generateInto,rt as generateIntoArgs,Y as generateModule,it as notifyOutcome,F as panelVisible,ee as runCodegen,et as schemaCandidates,Z as schemaOf};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/plugins/editor-markdown-MarkdownPreview-DyHZvj8H.js","assets/js/index-BSeq6-8S.js","assets/css/index-DgRudQqc.css","assets/vendor/lucide-react/eye-COs0olKf.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as l,ac as S,j as a,ad as C,ae as I,af as T,ag as N,ah as g,ai as P,a7 as R,aj as E,ak as A,al as W,am as V,an as K,ao as z,ap as w,aq as L,ar as U,as as q}from"../js/index-BSeq6-8S.js";import{E as G,C as H,a as X}from"../vendor/lucide-react/eye-COs0olKf.js";const Y=[".md",".mdx",".markdown",".mdown",".mkd"],y="text/markdown";function f(e,n){if(n===y)return!0;const t=e.toLowerCase();return Y.some(r=>t.endsWith(r))}function ke(e){return/^[a-z][a-z0-9+.-]*:/i.test(e)||e.startsWith("//")||e.startsWith("#")}function xe(e,n){const t=n.split(/[?#]/)[0];if(t===void 0||t===""||t.endsWith("/"))return null;const r=t.startsWith("/")?t.slice(1).split("/"):[...e.split("/"),...t.split("/")],i=[];for(const s of r)if(!(s===""||s===".")){if(s===".."){if(i.length===0)return null;i.pop();continue}i.push(s)}return i.length===0?null:i.join("/")}function Ee(e){const n=e.lastIndexOf("/");return n===-1?"":e.slice(0,n)}function ye(e){const n=e.indexOf("#");if(n===-1)return{path:e,hash:null};const t=decodeURIComponent(e.slice(n+1));return{path:e.slice(0,n),hash:t===""?null:t}}const $=Object.freeze({ts:"typescript",tsx:"typescript",mts:"typescript",cts:"typescript",typescript:"typescript",js:"javascript",jsx:"javascript",mjs:"javascript",cjs:"javascript",javascript:"javascript",node:"javascript",json:"json",json5:"json",jsonc:"json",css:"css",scss:"scss",sass:"scss",less:"less",html:"xml",htm:"xml",vue:"xml",svg:"xml",xml:"xml",md:"markdown",mdx:"markdown",markdown:"markdown",yml:"yaml",yaml:"yaml",sh:"bash",bash:"bash",zsh:"bash",shell:"bash",console:"bash",shellscript:"bash",py:"python",python:"python",sql:"sql",toml:"ini",ini:"ini",dockerfile:"dockerfile",docker:"dockerfile",go:"go",rs:"rust",rust:"rust",java:"java",kt:"kotlin",kotlin:"kotlin",php:"php",rb:"ruby",ruby:"ruby",cs:"csharp",csharp:"csharp",graphql:"graphql",gql:"graphql",diff:"diff",patch:"diff"});function F(e){if(e==null||e==="")return null;const t=(e.trim().split(/[\s,]+/)[0]??"").replace(/^language-/i,"").replace(/^\{|\}$/g,"");return t===""?null:$[t.toLowerCase()]??null}function Oe(e){if(e==null)return null;const n=e.split(/\s+/).find(t=>t.toLowerCase().startsWith("language-"));return F(n)}const B={"command.cycleView":"Next markdown view","command.openPreview":"Open the preview","command.showCode":"Show the source","command.showPreview":"Show the preview","command.showSplit":"Show side by side","command.toggleView":"Toggle source and preview","editor.label":"Markdown","editor.opening":"Opening the document…"},Z={"command.cycleView":"Следующий вид markdown","command.openPreview":"Открыть предпросмотр","command.showCode":"Показать исходник","command.showPreview":"Показать предпросмотр","command.showSplit":"Показать рядом","command.toggleView":"Переключить исходник и предпросмотр","editor.label":"Markdown","editor.opening":"Документ открывается…"},O=Object.freeze({ru:Z,en:B}),m=Object.freeze(["code","preview","split"]),_="editor-markdown.view",j="code";function J(e){return e==="code"||e==="preview"||e==="split"}function Q(e){return J(e)?e:j}function b(e,n=1){const t=m.indexOf(e),r=m.length;return m[(((t===-1?0:t)+n)%r+r)%r]??j}function ee(e){return e?m:m.filter(n=>n!=="split")}function h(e,n){return e==="split"&&!n?"preview":e}function ne(e){const n=new Map,t=new Set,r=()=>{for(const s of[...t])try{s()}catch(o){console.error("[markdown] подписчик режима отказал",o)}},i=()=>h(Q(e.settings?.get(e.settingKey)),e.hasTextEditor());return{get(s){const o=n.get(s);return o===void 0?i():h(o,e.hasTextEditor())},set(s,o,c=!0){const d=h(o,e.hasTextEditor());n.get(s)!==d&&(n.set(s,d),c&&Promise.resolve(e.settings?.set(e.settingKey,d)).catch(u=>{console.error("[markdown] предпочтение вида не сохранено",u)}),r())},forget(s){n.delete(s)&&r()},subscribe(s){return t.add(s),{dispose:()=>{t.delete(s)}}},dispose(){n.clear(),t.clear()}}}const te=l.lazy(async()=>({default:(await S(()=>import("./editor-markdown-MarkdownPreview-DyHZvj8H.js"),__vite__mapDeps([0,1,2,3]))).MarkdownPreview}));function se(e,n){const t=l.useCallback(i=>{const s=e.documentOf(n);if(s===null)return()=>{};const o=s.onDidChangeContent(()=>{i()});return()=>{o.dispose()}},[e,n]),r=l.useCallback(()=>e.documentOf(n)?.getText()??null,[e,n]);return l.useSyncExternalStore(t,r,r)}function oe(e,n){const t=l.useCallback(i=>{const s=e.subscribe(i);return()=>{s.dispose()}},[e]),r=l.useCallback(()=>e.get(n),[e,n]);return l.useSyncExternalStore(t,r,r)}const k={source:480,preview:480};function re({host:e,views:n,documentId:t}){const r=e.useTranslate(),i=e.documentOf(t),s=se(e,t),o=oe(n,t),c=l.useRef(null);if(i===null||s===null)return a.jsx(C,{className:"flex-1 border-0",children:a.jsx(I,{children:a.jsx(T,{className:"text-sm font-medium",children:r("editor.opening")})})});const d=e.TextEditor,u=a.jsx(l.Suspense,{fallback:a.jsx("div",{className:"bg-background h-full"}),children:a.jsx(te,{host:e,document:i,text:s,containerRef:c})});return o==="preview"||d===void 0?a.jsx("div",{className:"flex min-h-0 flex-1 flex-col",children:u}):o==="code"?a.jsx("div",{className:"flex min-h-0 flex-1 flex-col",children:a.jsx(d,{documentId:t})}):a.jsxs(N,{id:"markdown.split",orientation:"horizontal",className:"min-h-0 flex-1",children:[a.jsx(g,{id:"markdown.source",defaultSize:k.source,minSize:200,children:a.jsx("div",{className:"flex h-full min-h-0 flex-col",children:a.jsx(d,{documentId:t})})}),a.jsx(P,{withHandle:!0}),a.jsx(g,{id:"markdown.preview",defaultSize:k.preview,minSize:200,children:u})]})}const p="markdown.editor",ie="markdown.showCode",ce="markdown.showPreview",D="markdown.showSplit",v="markdown.toggleView",ae="markdown.cycleView",M="markdown.openPreview",le=50,de=()=>l.createElement(H,{className:"size-4"}),ue=()=>l.createElement(G,{className:"size-4"}),me=()=>l.createElement(X,{className:"size-4"});function x(e){if(typeof e!="object"||e===null)return null;const n=e.documentId;return typeof n=="string"?n:null}function fe(e){if(typeof e!="object"||e===null)return null;const n=e.ids;if(!Array.isArray(n))return null;const t=n[0];return typeof t=="string"?t:null}function pe(e,n){return{id:p,titleKey:"editor.label",canOpen(t){return f(t.name,t.mediaType)?le:!1},Body:({documentId:t})=>l.createElement(re,{host:e,views:n,documentId:t})}}function we(e){const{host:n,views:t}=e,r=o=>x(o)??n.activeDocument?.()??null,i=o=>{if(o===null)return!1;const c=n.documentOf(o);return c!==null&&f(c.ref.name,c.ref.mediaType)},s=o=>c=>{const d=r(c);return d===null?!1:(t.set(d,o),!0)};return[{id:ie,titleKey:"command.showCode",enabled:()=>i(n.activeDocument?.()??null),run:s("code")},{id:ce,titleKey:"command.showPreview",enabled:()=>i(n.activeDocument?.()??null),run:s("preview")},{id:D,titleKey:"command.showSplit",enabled:()=>n.TextEditor!==void 0&&i(n.activeDocument?.()??null),run:s("split")},{id:v,titleKey:"command.toggleView",enabled:()=>i(n.activeDocument?.()??null),run:o=>{const c=r(o);return c===null?!1:(t.set(c,t.get(c)==="code"?"preview":"code"),!0)}},{id:ae,titleKey:"command.cycleView",keybinding:"mod+shift+v",allowInEditable:!0,enabled:()=>i(n.activeDocument?.()??null),run:o=>{const c=r(o);if(c===null)return!1;const d=ee(n.TextEditor!==void 0);let u=b(t.get(c));for(;!d.includes(u);)u=b(u);return t.set(c,u),!0}},{id:M,titleKey:"command.openPreview",enabled:()=>n.openResource!==void 0,run:o=>{const c=fe(o)??x(o);return c===null||n.openResource===void 0?!1:(t.set(c,"preview",!1),n.openResource(c),!0)}}]}function he(e,n){const t=z(s=>s.editorId===p&&f(s.ref.name,s.ref.mediaType)),r=K(s=>({documentId:s.documentId})),i=s=>{const o=s?.documentId;return typeof o=="string"?e.get(o):null};return[{id:"markdown.title.toPreview",value:{kind:"item",menu:w,command:v,group:"1_view",titleKey:"command.showPreview",icon:ue,when:(s,o)=>t(s,o)&&i(o)==="code",argsOf:r,onDidChange:s=>e.subscribe(s)}},{id:"markdown.title.toCode",value:{kind:"item",menu:w,command:v,group:"1_view",titleKey:"command.showCode",icon:de,when:(s,o)=>t(s,o)&&i(o)!=="code",argsOf:r,onDidChange:s=>e.subscribe(s)}},{id:"markdown.title.split",value:{kind:"item",menu:w,command:D,group:"1_view",order:10,icon:me,when:(s,o)=>n()&&t(s,o),toggled:(s,o)=>i(o)==="split",argsOf:r,onDidChange:s=>e.subscribe(s)}},{id:"markdown.context.openPreview",value:{kind:"item",menu:q,command:M,group:"1_open",when:U(s=>s.ref!==null&&f(s.ref.name,s.ref.mediaType)),argsOf:L(s=>({ids:s.ref===null?[]:[s.ref.id]}))}}]}function ve(e){const{host:n}=e;return R({id:E,activate(t){for(const[o,c]of Object.entries(O))e.i18n?.contribute(o,c);const r=t.services.get(A)??null,i=()=>n.TextEditor!==void 0,s=ne({settings:r,settingKey:_,hasTextEditor:i});t.subscriptions.push({dispose:()=>{s.dispose()}});for(const o of we({host:n,views:s}))t.subscriptions.push(t.commands.register(o));t.subscriptions.push(t.extensions.contribute(W,pe(n,s),{id:p}));for(const o of he(s,i))t.subscriptions.push(t.extensions.contribute(V,o.value,{id:o.id}))}})}const _e=Object.freeze(Object.defineProperty({__proto__:null,MARKDOWN_EDITOR_ID:p,MARKDOWN_MEDIA_TYPE:y,MARKDOWN_MESSAGES:O,MARKDOWN_PLUGIN_ID:E,MARKDOWN_VIEW_SETTING:_,createMarkdownPlugin:ve,isMarkdown:f},Symbol.toStringTag,{value:"Module"}));export{_e as a,Ee as d,Oe as f,ke as i,xe as r,ye as s};
|