@appaflytech/zeyrek-ai-mcp 0.0.33 → 0.0.35
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/.env.example +0 -15
- package/dist/config.js +0 -11
- package/dist/index.js +0 -2
- package/dist/knowledge/boxSections.js +184 -0
- package/dist/knowledge/componentCatalog.js +634 -255
- package/dist/knowledge/componentEvents.js +38 -32
- package/dist/knowledge/layoutSummary.js +2 -140
- package/dist/knowledge/normalize.js +144 -117
- package/dist/knowledge/rules.js +42 -291
- package/dist/knowledge/styleResolve.js +53 -58
- package/dist/knowledge/themeResolve.js +4 -4
- package/dist/knowledge/themeSchema.js +2 -1
- package/dist/observability/trace.js +1 -1
- package/dist/platform/diagnostics.js +4 -10
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/http.js +7 -23
- package/dist/platform/responses.js +2 -6
- package/dist/platform/screenshot.js +1162 -0
- package/dist/platform/secrets.js +0 -9
- package/dist/platform/strictArguments.js +12 -68
- package/dist/platform/tokenVault.js +4 -187
- package/dist/resources/examples/layout-app-shell.json +707 -229
- package/dist/resources/examples/page-flex-sections.json +1 -1
- package/dist/resources/guides/component.md +6 -14
- package/dist/resources/guides/entity.md +5 -3
- package/dist/resources/guides/expressions.md +5 -14
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/layout.md +58 -55
- package/dist/resources/guides/microservice.md +2 -9
- package/dist/resources/guides/middleware.md +2 -34
- package/dist/resources/guides/page.md +179 -256
- package/dist/resources/guides/theme.md +3 -8
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +1 -7
- package/dist/resources/schema-fingerprint.json +4 -4
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -3
- package/dist/resources/schemas/MicroserviceDto.json +2 -2
- package/dist/server.js +1 -7
- package/dist/tools/applications.js +3 -60
- package/dist/tools/components.js +16 -103
- package/dist/tools/datasources.js +1 -1
- package/dist/tools/designSchemaPatch.js +19 -23
- package/dist/tools/externalComponents.js +4 -25
- package/dist/tools/flows.js +13 -80
- package/dist/tools/layouts.js +20 -48
- package/dist/tools/microservices.js +10 -32
- package/dist/tools/pages.js +115 -396
- package/dist/tools/platformInfo.js +2 -7
- package/dist/tools/rows.js +1 -7
- package/dist/tools/schemaOps.js +4 -35
- package/dist/tools/screenWrite.js +37 -25
- package/dist/tools/screens.js +4 -91
- package/dist/tools/variables.js +5 -11
- package/package.json +2 -2
- package/dist/knowledge/access.js +0 -802
- package/dist/knowledge/case.js +0 -41
- package/dist/knowledge/connectDataBind.js +0 -819
- package/dist/knowledge/connectDataDefinition.js +0 -341
- package/dist/knowledge/connectDataExecute.js +0 -93
- package/dist/knowledge/connectDataRules.js +0 -128
- package/dist/knowledge/decision.js +0 -121
- package/dist/knowledge/expressionPrelude.js +0 -59
- package/dist/knowledge/microserviceParameters.js +0 -58
- package/dist/knowledge/mining.js +0 -94
- package/dist/knowledge/mobileComponentCatalog.js +0 -864
- package/dist/knowledge/mobileComponentEvents.js +0 -239
- package/dist/knowledge/mobileStore.js +0 -227
- package/dist/knowledge/platform/lint.js +0 -385
- package/dist/knowledge/platform/mobile.js +0 -142
- package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
- package/dist/knowledge/platform/mobileRules.js +0 -231
- package/dist/knowledge/platform/mobileSpacing.js +0 -82
- package/dist/knowledge/platform/mobileTabs.js +0 -108
- package/dist/knowledge/platform/nativeBoxModel.js +0 -44
- package/dist/knowledge/platform/profile.js +0 -25
- package/dist/knowledge/platform/resolve.js +0 -122
- package/dist/knowledge/platform/web.js +0 -39
- package/dist/knowledge/process.js +0 -510
- package/dist/knowledge/rowFilter.js +0 -43
- package/dist/knowledge/styleResolveNative.js +0 -527
- package/dist/platform/argumentAliases.js +0 -128
- package/dist/platform/bodyFile.js +0 -103
- package/dist/platform/capture/actions.js +0 -333
- package/dist/platform/capture/browser.js +0 -1
- package/dist/platform/capture/capture.js +0 -659
- package/dist/platform/capture/console-log.js +0 -122
- package/dist/platform/capture/index.js +0 -11
- package/dist/platform/capture/readiness.js +0 -103
- package/dist/platform/capture/summary.js +0 -77
- package/dist/platform/capture/target.js +0 -5
- package/dist/platform/capture/targets/studio-mobile.js +0 -15
- package/dist/platform/capture/targets/studio-web.js +0 -5
- package/dist/platform/impersonation.js +0 -45
- package/dist/platform/jsonArray.js +0 -24
- package/dist/platform/schemaReadMemory.js +0 -60
- package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
- package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
- package/dist/resources/examples/bpm-satinalma.json +0 -376
- package/dist/resources/examples/connect-data-convert-verify.json +0 -107
- package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
- package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
- package/dist/resources/examples/connect-data-query-params.json +0 -50
- package/dist/resources/examples/connect-data-table-entity.json +0 -147
- package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
- package/dist/resources/examples/mobile-app-shell-drawer.json +0 -244
- package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
- package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
- package/dist/resources/examples/mobile-form-screen.json +0 -365
- package/dist/resources/examples/mobile-list-detail-form.json +0 -703
- package/dist/resources/guides/access.md +0 -796
- package/dist/resources/guides/bpm.md +0 -686
- package/dist/resources/guides/case.md +0 -153
- package/dist/resources/guides/decision.md +0 -185
- package/dist/resources/guides/mobile-layout.md +0 -193
- package/dist/resources/guides/mobile.md +0 -578
- package/dist/resources/read.js +0 -41
- package/dist/resources/schemas/AccessExplanationDto.json +0 -144
- package/dist/resources/schemas/AccessMatrixDto.json +0 -170
- package/dist/resources/schemas/AccessPermissionDto.json +0 -57
- package/dist/resources/schemas/AccessPolicyDto.json +0 -223
- package/dist/resources/schemas/AccessResourceDto.json +0 -86
- package/dist/resources/schemas/AppSessionDto.json +0 -53
- package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
- package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
- package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
- package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
- package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
- package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
- package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
- package/dist/resources/schemas/DecisionDto.json +0 -302
- package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
- package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
- package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
- package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
- package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
- package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
- package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
- package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
- package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
- package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
- package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
- package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
- package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
- package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
- package/dist/resources/schemas/StartMobileBuildCommand.json +0 -54
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
- package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +0 -259
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
- package/dist/tools/accessOperations.js +0 -135
- package/dist/tools/accessPolicies.js +0 -170
- package/dist/tools/accessRuntime.js +0 -203
- package/dist/tools/bpm.js +0 -343
- package/dist/tools/bpmGovernance.js +0 -266
- package/dist/tools/bpmOperations.js +0 -230
- package/dist/tools/bpmReporting.js +0 -154
- package/dist/tools/bpmRouting.js +0 -150
- package/dist/tools/bpmRuntime.js +0 -396
- package/dist/tools/case.js +0 -178
- package/dist/tools/caseRuntime.js +0 -89
- package/dist/tools/connectData.js +0 -449
- package/dist/tools/connectors.js +0 -193
- package/dist/tools/decisions.js +0 -206
- package/dist/tools/mobile.js +0 -221
- package/dist/tools/mobileStore.js +0 -268
- package/dist/tools/modules.js +0 -48
- package/dist/tools/organizationStructure.js +0 -137
- package/dist/tools/profileWrite.js +0 -92
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { logStep } from '../observability/trace.js';
|
|
2
2
|
import { PlatformApiError } from '../platform/errors.js';
|
|
3
3
|
import { ensureWorkflowErrorPath } from './errorPath.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { TYPED_STYLE_COMPONENTS } from './styleResolve.js';
|
|
5
|
+
import { FUNCTIONS_NAMESPACE } from './functionGuards.js';
|
|
6
6
|
const SORT_DEFAULT = { name: 'sortField', type: 'sortType', source: 'query-string' };
|
|
7
7
|
const LIMIT_DEFAULT = { name: 'limit', offset: 'offset', source: 'query-string' };
|
|
8
8
|
function asArray(value) {
|
|
@@ -270,11 +270,12 @@ export function normalizeWorkflowDefinition(definition) {
|
|
|
270
270
|
*/
|
|
271
271
|
/**
|
|
272
272
|
* Adım tipi sözlüğü backend'in, KOŞAN tipler barındırıcının: motor yedi tip register eder, web
|
|
273
|
-
* `Runtime.svelte` altı, mobil `
|
|
273
|
+
* `Runtime.svelte` altı, mobil `ScreenRuntime.tsx` beş tip ekler ve aynı sayfa kaydı ikisinde de
|
|
274
274
|
* koşar. Register edilmemiş bir tipe gelen akış sessizce ölür (`flow-engine.ts` `process()`
|
|
275
275
|
* callback bulamazsa next/completed/stopped hiç çağrılmaz), üstelik `run()` promise'i
|
|
276
276
|
* çözülmediği için `__ngAppsFlowActivity.running` sıfıra inmez. İki hâl tamamen türetilebilir
|
|
277
|
-
* olduğu için lint değil NORMALİZASYON
|
|
277
|
+
* olduğu için lint değil NORMALİZASYON — kalanı (`confirm`/`download` mobilde yok) yalnız
|
|
278
|
+
* uygulama tarafında kapanabilir, `FLOW-023` onları uyarır.
|
|
278
279
|
*/
|
|
279
280
|
function normalizeFlowHostGaps(steps, list) {
|
|
280
281
|
const fixes = [];
|
|
@@ -288,15 +289,12 @@ function normalizeFlowHostGaps(steps, list) {
|
|
|
288
289
|
.map(step => String(step.stepId ?? ''))
|
|
289
290
|
.filter(id => id.length > 0));
|
|
290
291
|
for (const step of list) {
|
|
291
|
-
// navigate ile redirect'in argümanı AYNI ({ path, pageId, query, targetBlank
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const original = String(step.type);
|
|
298
|
-
step.type = alias;
|
|
299
|
-
fixes.push(`'${label(step)}': type ${original} → ${alias} yazıldı — argüman şekli aynı ({ path, pageId, query, targetBlank, presentation }) ama ${original}'i web barındırıcısı register etmez, ${alias} ikisinde de koşar`);
|
|
292
|
+
// navigate ile redirect'in argümanı AYNI ({ path, pageId, query, targetBlank }) ama navigate'i
|
|
293
|
+
// yalnız mobil register eder; redirect ise iki barındırıcıda da koşar (mobilde aynı navigate
|
|
294
|
+
// uygulamasına eşlenir), yani redirect kesin üstün.
|
|
295
|
+
if (step.type === 'navigate') {
|
|
296
|
+
step.type = 'redirect';
|
|
297
|
+
fixes.push(`'${label(step)}': type navigate → redirect yazıldı — argüman şekli aynı ({ path, pageId, query, targetBlank }) ama navigate'i web barındırıcısı register etmez, redirect ikisinde de koşar`);
|
|
300
298
|
}
|
|
301
299
|
if (endStepIds.size === 0)
|
|
302
300
|
continue;
|
|
@@ -361,6 +359,7 @@ const REQUIRED_COLLECTIONS = ['events', 'validations', 'stateBindings', 'childre
|
|
|
361
359
|
*
|
|
362
360
|
* - `states`: DesignComponentManagementSchema.ToDomain:47 `States.IsSticky`'yi guard'sız okur;
|
|
363
361
|
* Appearance'ın satır 24'te varsayılanı var, States'in yok.
|
|
362
|
+
* - `blocks` doldurulmaz: konum ebeveynin düzenine bağlıdır, eksikse PAGE-037 ile reddedilir.
|
|
364
363
|
* - `events` / `validations` / `stateBindings`: yalnız **micro-op yolunda** zorunlu.
|
|
365
364
|
* `page_create` (POST /pages) bunlarsız 200 döner, `PATCH …/schema` NRE verir; canlı deneyde
|
|
366
365
|
* üçü birlikte verilince geçti, her biri tek başına verilince patladı (klinik H-005 eki).
|
|
@@ -459,7 +458,13 @@ const VALIDATION_TYPE_ALIASES = new Map([
|
|
|
459
458
|
...VALIDATION_CANONICAL_TYPES.map(type => [type.replace(/-/g, ''), type]),
|
|
460
459
|
['pattern', 'regex'],
|
|
461
460
|
['min', 'min-value'],
|
|
462
|
-
['max', 'max-value']
|
|
461
|
+
['max', 'max-value'],
|
|
462
|
+
// OR-2 (2026-10-03): kayıt defteri checkboxgroup/multi-select/tag-input kuralını minItems/maxItems
|
|
463
|
+
// adıyla ilan eder (component_get.validations); backend ValidationType'ta bu ad yok, runtime da tanımaz.
|
|
464
|
+
// Studio paneli bu üçüne 'custom' şablonundan min-length/max-length yazar (ng-apps-types
|
|
465
|
+
// validation/constants.ts) ve Form uzunluk kuralı dizide SEÇİLİ ELEMAN sayısını ölçer.
|
|
466
|
+
['minitems', 'min-length'],
|
|
467
|
+
['maxitems', 'max-length']
|
|
463
468
|
]);
|
|
464
469
|
const VALIDATION_VALUE_REQUIRED = new Set(['regex', 'max-length', 'min-length', 'max-value', 'min-value', 'value-options']);
|
|
465
470
|
function canonicalValidationType(value) {
|
|
@@ -653,48 +658,54 @@ export function styleKeyNote(fixed) {
|
|
|
653
658
|
+ 'değer kaydedilir ama hiç uygulanmaz ve tek işareti tarayıcı konsoludur (F-06). '
|
|
654
659
|
+ "Seçici anahtarlara ('&__body', ':hover', '--token') dokunulmadı."];
|
|
655
660
|
}
|
|
661
|
+
/** PAGE-009 ile aynı kural: JS tanımlayıcısı (tireler çıkarılınca) ve ayrılmış `Functions` değil. */
|
|
662
|
+
function isDerivableComponentName(name) {
|
|
663
|
+
const bare = name.replace(/-/g, '');
|
|
664
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(bare) && bare !== FUNCTIONS_NAMESPACE;
|
|
665
|
+
}
|
|
656
666
|
/**
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
* Yalnız `true` yazılır: katalog bir tipi kap saymıyorsa düğüme dokunulmaz.
|
|
667
|
+
* Y-15 — adı eksik, null ya da boş/boşluk olan düğüm runtime'ın ifade ön sözünü bozar: `getNodeNames`
|
|
668
|
+
* null adı `"null"` anahtarına çevirir, `runCode` `const null = Components["null"]` satırını üretir
|
|
669
|
+
* (`ng-apps-flow/src/flow-execution.functions.ts`) ve sayfadaki BÜTÜN ifadeler SyntaxError'la düşer;
|
|
670
|
+
* hata yalnız akış adımının runtimeErrors'ında görünür (ölçüldü 2026-10-03, `y15-adsiz`). Backend adı
|
|
671
|
+
* hiç denetlemez (`PageSchemaValidator.cs`); Studio her düğüme `name = elementId` yazar
|
|
672
|
+
* (`ScreenBuilderDroppable.svelte`). Kural deterministik olduğu için reddetmek yerine dolduruyoruz.
|
|
673
|
+
* Doldurulan ad da PAGE-009'dan geçmek zorunda: çağıran bunu denetimden ÖNCE koşar. Dolu ada dokunulmaz.
|
|
674
|
+
* `normalizeComponentDefaults` aynı boşluğu yalnız geçerli bir elementId için ikinci kez kapatır (güvenlik ağı).
|
|
666
675
|
*/
|
|
667
|
-
export function
|
|
668
|
-
const
|
|
669
|
-
if (droppable.size === 0)
|
|
670
|
-
return fixed;
|
|
676
|
+
export function fillComponentNames(nodes) {
|
|
677
|
+
const filled = [];
|
|
671
678
|
for (const node of asObjects(nodes)) {
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
node.states = { ...DEFAULT_STATES };
|
|
678
|
-
}
|
|
679
|
-
const states = node.states;
|
|
680
|
-
if (states.isDroppable !== true) {
|
|
681
|
-
states.isDroppable = true;
|
|
682
|
-
fixed.push(`'${String(node.elementId ?? node.name ?? type)}' (${type})`);
|
|
683
|
-
}
|
|
679
|
+
const name = node.name;
|
|
680
|
+
const blank = name === undefined || name === null || (typeof name === 'string' && name.trim().length === 0);
|
|
681
|
+
if (blank && typeof node.elementId === 'string' && node.elementId.length > 0) {
|
|
682
|
+
node.name = node.elementId;
|
|
683
|
+
filled.push(node.elementId);
|
|
684
684
|
}
|
|
685
|
-
|
|
685
|
+
filled.push(...fillComponentNames(node.children));
|
|
686
686
|
}
|
|
687
|
-
return
|
|
687
|
+
return filled;
|
|
688
688
|
}
|
|
689
|
-
export function
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
689
|
+
export function componentNameNote(filled) {
|
|
690
|
+
if (filled.length === 0)
|
|
691
|
+
return [];
|
|
692
|
+
const access = filled.length === 1 ? filled[0] : "her düğümün kendi elementId'si";
|
|
693
|
+
return [`${filled.map(id => `'${id}'`).join(', ')}: name eksikti, elementId'den yazıldı — ifadelerde ${access} ile erişilir (adsız düğüm runtime'da sayfadaki bütün ifadeleri düşürür, Y-15)`];
|
|
693
694
|
}
|
|
694
695
|
export function normalizeComponentDefaults(nodes) {
|
|
695
696
|
const fixed = [];
|
|
696
697
|
for (const node of asObjects(nodes)) {
|
|
697
698
|
const missing = [];
|
|
699
|
+
// name'siz düğümü platform kabul eder ama sayfada bir akış ya da `{{ }}` kod prop'u varsa
|
|
700
|
+
// FlowEngine runCode "Cannot read properties of undefined (reading 'catch')" ile düşer, akış
|
|
701
|
+
// `running:1`'de takılır ve hata adsız düğümü işaret etmez (image ölçüm turu, 2026-10-04).
|
|
702
|
+
// Yalnız PAGE-009'un geçerli saydığı elementId'den türetilir: page_create/page_update/layout
|
|
703
|
+
// yollarında PAGE-009 denetimi bu normalizasyondan ÖNCE koşar; bozuk bir elementId'den türeyen
|
|
704
|
+
// ad denetimi atlatıp "Missing initializer in const declaration" ile sayfayı öldürürdü.
|
|
705
|
+
if ((typeof node.name !== 'string' || node.name.trim() === '') && typeof node.elementId === 'string' && isDerivableComponentName(node.elementId)) {
|
|
706
|
+
node.name = node.elementId;
|
|
707
|
+
missing.push('name');
|
|
708
|
+
}
|
|
698
709
|
if (!node.states || typeof node.states !== 'object') {
|
|
699
710
|
node.states = { ...DEFAULT_STATES };
|
|
700
711
|
missing.push('states');
|
|
@@ -749,6 +760,65 @@ export function normalizeComponentDefaults(nodes) {
|
|
|
749
760
|
}
|
|
750
761
|
return fixed;
|
|
751
762
|
}
|
|
763
|
+
export const COMPONENT_BODY_RULE = "Asgari gövde: { elementId, name (= elementId), type, props, blocks: [{ breakpoint: 1024, size: { w, h }, position: { x, y } }] }. "
|
|
764
|
+
+ "Gateway blocks'u doldurmaz: blocks'u olmayan ya da null olan düğüm platformda kayıt sırasında 500 NullReferenceException verir. "
|
|
765
|
+
+ "Boyutu component_get çıktısındaki sizes'tan al; flex kapta position yalnız sırayı belirtir (sırayı index ile de verebilirsin, blocks yine gövdede olur), "
|
|
766
|
+
+ 'ızgara kapta x:0, y: kardeşlerin altı (en büyük y+h).';
|
|
767
|
+
/**
|
|
768
|
+
* Y-13 / PAGE-037 — `blocks` alanı hiç olmayan ya da `null` olan düğümleri (çocuklar dahil) toplar.
|
|
769
|
+
* `DesignComponentManagementSchema.Blocks`'un varsayılanı yoktur; `ToDomain` null listeyi
|
|
770
|
+
* `AddBlocks(null)` ile atlar, `_blocks` başlatılmaz ve `Blocks` getter'ı kayıtta patlar
|
|
771
|
+
* (`DesignComponent.cs:36-37,305`; yeni düğümde revizyon yakalama `ToObject:464`, var olan düğümde
|
|
772
|
+
* `DesignComponentRepository.UpsertRange` → `Override`). Ölçüldü 2026-10-04: son 7 günde eklenen
|
|
773
|
+
* düğümlerin ~%20'si blocks'suz geldi ve hepsi 500 aldı. Konum ebeveynin düzenine bağlı olduğu için
|
|
774
|
+
* doldurmuyoruz, reddediyoruz. `blocks: []` platformda kaydolur (ölçüldü 2026-10-04, `y13-blocks`) ve buraya girmez.
|
|
775
|
+
*/
|
|
776
|
+
export function missingBlocksNodes(nodes) {
|
|
777
|
+
const missing = [];
|
|
778
|
+
for (const node of asObjects(nodes)) {
|
|
779
|
+
if (node.blocks === undefined || node.blocks === null) {
|
|
780
|
+
missing.push(`'${String(node.elementId ?? node.name ?? node.type ?? '?')}': blocks eksik — şunu ver: [{breakpoint:1024, size:{w,h}, position:{x,y}}]`);
|
|
781
|
+
}
|
|
782
|
+
missing.push(...missingBlocksNodes(node.children));
|
|
783
|
+
}
|
|
784
|
+
return missing;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* PAGE-037 kimlik ayağı — platform elementId'siz add_component'i 'missing-id' ile reddeder
|
|
788
|
+
* (`PageSchemaMicroOpApplier.cs` add_component dalı) ama mesajı kimliğin hangi alan olduğunu
|
|
789
|
+
* söylemez. Ajanlar `name` verip elementId'yi atladı (Y-13 neden analizi N-B3, 5 düğüm).
|
|
790
|
+
*/
|
|
791
|
+
export function addComponentIdErrors(ops) {
|
|
792
|
+
const errors = [];
|
|
793
|
+
for (const op of asObjects(ops)) {
|
|
794
|
+
if (op.op !== 'add_component')
|
|
795
|
+
continue;
|
|
796
|
+
const component = op.component && typeof op.component === 'object' ? op.component : {};
|
|
797
|
+
const elementId = component.elementId;
|
|
798
|
+
if (typeof elementId === 'string' && elementId.trim() !== '')
|
|
799
|
+
continue;
|
|
800
|
+
const name = typeof component.name === 'string' && component.name.trim() !== '' ? component.name : undefined;
|
|
801
|
+
errors.push(`add_component: component.elementId yok (platform 'missing-id' ile reddeder) — kimlik elementId'dir; name ifade adıdır, ikisini aynı yaz${name ? ` (elementId: '${name}', name: '${name}')` : ''}`);
|
|
802
|
+
}
|
|
803
|
+
return errors;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* PAGE-037. Yalnız çağıranın verdiği ağaca bakar: page_create'in eklediği page_container
|
|
807
|
+
* blocks'la üretilir, okunan kayıttaki düğümler (layout_patch) platformdan blocks listesiyle gelir.
|
|
808
|
+
* Sayfa/layout yazma kapısı (`assertScreenWriteGuards`), `page_schema_validate` ve
|
|
809
|
+
* `component_update` çağırır; `page_schema_patch` aynı denetimi op başına toplar.
|
|
810
|
+
*/
|
|
811
|
+
export function assertComponentBlocks(nodes) {
|
|
812
|
+
const missing = missingBlocksNodes(nodes);
|
|
813
|
+
if (missing.length === 0)
|
|
814
|
+
return;
|
|
815
|
+
throw new PlatformApiError(`PAGE-037 — komponent gövdesinde blocks yok (istek gönderilmedi): ${missing.join(' · ')}. ${COMPONENT_BODY_RULE}`, 400);
|
|
816
|
+
}
|
|
817
|
+
export function assertAddComponentIds(ops) {
|
|
818
|
+
const errors = addComponentIdErrors(ops);
|
|
819
|
+
if (errors.length > 0)
|
|
820
|
+
throw new PlatformApiError(`PAGE-037 — ${errors.join(' · ')} (istek gönderilmedi). ${COMPONENT_BODY_RULE}`, 400);
|
|
821
|
+
}
|
|
752
822
|
/**
|
|
753
823
|
* add_component micro-op'unun taşıdığı komponent ağacı da aynı ToDomain yolundan geçer.
|
|
754
824
|
*/
|
|
@@ -845,6 +915,7 @@ export function normalizeSchemaOps(ops) {
|
|
|
845
915
|
const components = [];
|
|
846
916
|
const props = [];
|
|
847
917
|
const validations = [];
|
|
918
|
+
const names = [];
|
|
848
919
|
for (const op of asObjects(ops)) {
|
|
849
920
|
if (op.op === 'replace_prop') {
|
|
850
921
|
if (isStylePropName(String(op.prop ?? ''))) {
|
|
@@ -866,9 +937,10 @@ export function normalizeSchemaOps(ops) {
|
|
|
866
937
|
}
|
|
867
938
|
if (op.op !== 'add_component' || !op.component)
|
|
868
939
|
continue;
|
|
940
|
+
names.push(...fillComponentNames([op.component]));
|
|
869
941
|
components.push(...normalizeComponentDefaults([op.component]));
|
|
870
942
|
}
|
|
871
|
-
return { components, props, validations };
|
|
943
|
+
return { components, props, validations, names };
|
|
872
944
|
}
|
|
873
945
|
export function validationNote(fixed) {
|
|
874
946
|
return fixed.length === 0 ? [] : [`validation gövdeleri düzeltildi (${fixed.join(' · ')})`];
|
|
@@ -925,11 +997,11 @@ export function pageContainerNode() {
|
|
|
925
997
|
* çekilirlerse sayfa içeriğinin akışına girer ve katman olarak açılmazlar.
|
|
926
998
|
*/
|
|
927
999
|
const ROOT_LAYER_TYPES = new Set(['modal', 'drawer']);
|
|
928
|
-
export function ensurePageContainer(schema
|
|
1000
|
+
export function ensurePageContainer(schema) {
|
|
929
1001
|
const nodes = asObjects(schema);
|
|
930
1002
|
if (nodes.some(node => node.elementId === PAGE_CONTAINER_ELEMENT_ID))
|
|
931
1003
|
return { schema: nodes, fixes: [] };
|
|
932
|
-
const container =
|
|
1004
|
+
const container = pageContainerNode();
|
|
933
1005
|
const layers = nodes.filter(node => ROOT_LAYER_TYPES.has(String(node.type ?? '')));
|
|
934
1006
|
container.children = nodes.filter(node => !ROOT_LAYER_TYPES.has(String(node.type ?? '')));
|
|
935
1007
|
const moved = container.children.length;
|
|
@@ -972,7 +1044,7 @@ export function clampBlockSizes(nodes, maxSizes) {
|
|
|
972
1044
|
* başlatır (`ComponentHeightType.Fixed = 0`), yani "alan yok" = "sabit yükseklik". Studio'nun
|
|
973
1045
|
* kendi bırakma yolu bunu ASLA yapmaz: katalogdaki `isDefaultAutoHeight`e bakıp
|
|
974
1046
|
* `heightType: isDefaultAutoHeight ? 'auto' : 'fixed'` yazar
|
|
975
|
-
* (`ScreenBuilderDroppable.svelte:701`, `store-converter.ts`
|
|
1047
|
+
* (`ScreenBuilderDroppable.svelte:701`, `store-converter.ts:233`). Katalogda varsayılan
|
|
976
1048
|
* `true`'dur (`ZeyrekComponent.ts:62`); `false` diyen yalnız sekiz tip var — auth-layout, html,
|
|
977
1049
|
* image, layout, qrcode, table, text-editor, video.
|
|
978
1050
|
*
|
|
@@ -1758,18 +1830,19 @@ export function viewAliasNote(fixes) {
|
|
|
1758
1830
|
return [`view alanlarının entity bağı id'den alias'a çevrildi (${fixes.join(', ')}): yazma tarafı viewEntityAlias ister, okuma tarafı viewEntityId döndürür — alias boş kalsa platform tüm alanları ilk tabloya düşürürdü`];
|
|
1759
1831
|
}
|
|
1760
1832
|
/**
|
|
1761
|
-
*
|
|
1762
|
-
*
|
|
1763
|
-
*
|
|
1833
|
+
* Değişken seti tek bir kayıtta yaşar: `CreateAppVariableCommand`/`CreatePageVariableCommand`
|
|
1834
|
+
* yalnız `Data` alanı taşır (Studio uygulama başına ve sayfa başına TEK satır tutar —
|
|
1835
|
+
* `IsVariableExistForApplicationAsync` doluysa create update'e döner). Studio'nun gönderdiği şekil
|
|
1836
|
+
* `data`'nın **JSON string** olmasıdır: "[{\"key\":\"MyTest\",\"value\":{\"isActive\":true}}]".
|
|
1837
|
+
* `Data` tipi `object` olduğu için platform her gövdeyi kabul eder; alan adı tutmayan bir gövde
|
|
1838
|
+
* (name/type/defaultValue gibi) `Data`'yı null bırakır ve istek 200 döner ama HİÇBİR ŞEY yazılmaz
|
|
1839
|
+
* (17/Ç1). Okuma tarafı da aynı string'i geri verir (`AppVariablesDto.Map` → GetRawText).
|
|
1764
1840
|
*/
|
|
1765
1841
|
export function parseVariableEntries(data) {
|
|
1766
1842
|
const source = typeof data === 'string' ? safeParse(data) : data;
|
|
1767
1843
|
return asObjects(source)
|
|
1768
1844
|
.filter(entry => typeof entry.key === 'string' && entry.key !== '')
|
|
1769
|
-
.map(entry => {
|
|
1770
|
-
const storage = STATE_STORAGE_KINDS.find(kind => kind === entry.storage);
|
|
1771
|
-
return { key: String(entry.key), value: entry.value, ...(storage ? { storage } : {}) };
|
|
1772
|
-
});
|
|
1845
|
+
.map(entry => ({ key: String(entry.key), value: entry.value }));
|
|
1773
1846
|
}
|
|
1774
1847
|
function safeParse(value) {
|
|
1775
1848
|
try {
|
|
@@ -1784,29 +1857,17 @@ function safeParse(value) {
|
|
|
1784
1857
|
* mevcut seti okuyup anahtar bazında birleştirir; `replace: true` verilirse bilinçli olarak ezer.
|
|
1785
1858
|
*/
|
|
1786
1859
|
export function mergeVariableEntries(existing, incoming, replace) {
|
|
1787
|
-
const stored = (entry, current) => {
|
|
1788
|
-
const storage = entry.storage === undefined ? current?.storage : STATE_STORAGE_KINDS.find(kind => kind === entry.storage);
|
|
1789
|
-
const value = entry.value === undefined ? (current ? current.value : null) : entry.value;
|
|
1790
|
-
return { key: entry.key, value, ...(storage ? { storage } : {}) };
|
|
1791
|
-
};
|
|
1792
1860
|
if (replace)
|
|
1793
|
-
return { entries: incoming
|
|
1861
|
+
return { entries: incoming, fixes: [] };
|
|
1794
1862
|
const merged = [...existing];
|
|
1795
1863
|
const kept = [];
|
|
1796
|
-
const keptStorage = [];
|
|
1797
|
-
const keptValue = [];
|
|
1798
1864
|
for (const entry of incoming) {
|
|
1799
1865
|
const index = merged.findIndex(current => current.key === entry.key);
|
|
1800
1866
|
if (index === -1) {
|
|
1801
|
-
merged.push(
|
|
1867
|
+
merged.push(entry);
|
|
1802
1868
|
continue;
|
|
1803
1869
|
}
|
|
1804
|
-
|
|
1805
|
-
if (entry.storage === undefined && current?.storage)
|
|
1806
|
-
keptStorage.push(`'${entry.key}' → ${current.storage}`);
|
|
1807
|
-
if (entry.value === undefined)
|
|
1808
|
-
keptValue.push(`'${entry.key}'`);
|
|
1809
|
-
merged[index] = stored(entry, current);
|
|
1870
|
+
merged[index] = entry;
|
|
1810
1871
|
}
|
|
1811
1872
|
for (const entry of existing) {
|
|
1812
1873
|
if (!incoming.some(current => current.key === entry.key))
|
|
@@ -1814,17 +1875,9 @@ export function mergeVariableEntries(existing, incoming, replace) {
|
|
|
1814
1875
|
}
|
|
1815
1876
|
return {
|
|
1816
1877
|
entries: merged,
|
|
1817
|
-
fixes:
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
: []),
|
|
1821
|
-
...(keptStorage.length > 0
|
|
1822
|
-
? [`saklama türü korundu (${keptStorage.join(', ')}): gelen değişken storage taşımıyordu, kayıttaki tür silinmedi — belleğe çevirmek için storage: 'memory' verin`]
|
|
1823
|
-
: []),
|
|
1824
|
-
...(keptValue.length > 0
|
|
1825
|
-
? [`değer korundu (${keptValue.join(', ')}): gelen değişken value taşımıyordu, kayıttaki değer silinmedi — boşaltmak için value: null verin`]
|
|
1826
|
-
: [])
|
|
1827
|
-
]
|
|
1878
|
+
fixes: kept.length > 0
|
|
1879
|
+
? [`mevcut değişkenler korundu (${kept.join(', ')}): uç seti komple değiştirir, gateway anahtar bazında birleştirdi — kasten silmek için replace: true verin`]
|
|
1880
|
+
: []
|
|
1828
1881
|
};
|
|
1829
1882
|
}
|
|
1830
1883
|
export function blockSizeNote(clamped) {
|
|
@@ -1860,7 +1913,7 @@ export function rootAddsNote(retargeted, containerElementId) {
|
|
|
1860
1913
|
export function componentDefaultsNote(fixed) {
|
|
1861
1914
|
if (fixed.length === 0)
|
|
1862
1915
|
return [];
|
|
1863
|
-
return [`komponent gövdelerine eksik
|
|
1916
|
+
return [`komponent gövdelerine eksik varsayılan alanlar eklendi (${fixed.join(' · ')}): bunlar olmadan platform NullReferenceException verir ve page_schema_validate bunu yakalamaz. blocks eklenmez — gövdede olmalı (PAGE-037)`];
|
|
1864
1917
|
}
|
|
1865
1918
|
/**
|
|
1866
1919
|
* Create yolu junction kaydını açar ama fiziksel tabloyu kurmaz (platform bug'ı P-01,
|
|
@@ -1905,22 +1958,12 @@ export function nestedRepeaterNodes(nodes) {
|
|
|
1905
1958
|
walk(asObjects(nodes), false);
|
|
1906
1959
|
return found;
|
|
1907
1960
|
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
* `grouped-list` (ui-native, ADR 0007). Web'de karşılığı yok — web mesajı textarea tarifinde kalır.
|
|
1911
|
-
*/
|
|
1912
|
-
export function nestedRepeaterMessage(ids, platform = 'web') {
|
|
1913
|
-
const measured = `PAGE-013 — repeater içinde repeater (istek gönderilmedi): ${ids.join(' · ')}. `
|
|
1961
|
+
export function nestedRepeaterMessage(ids) {
|
|
1962
|
+
return `PAGE-013 — repeater içinde repeater (istek gönderilmedi): ${ids.join(' · ')}. `
|
|
1914
1963
|
+ 'Ölçüldü (2026-08-19): iç repeater OKUMADA çalışır ama girilen değer dış satıra GERİ YAZILMAZ '
|
|
1915
1964
|
+ '(_repeaterValues null kalır) ve tek düzenlemeden sonra DOM bozulur. Sebep yapısal: şemada iç '
|
|
1916
|
-
+ 'repeater tek düğümdür, dış satır başına ayrı düğüm yoktur. '
|
|
1917
|
-
|
|
1918
|
-
if (platform !== 'mobile')
|
|
1919
|
-
return measured + textarea;
|
|
1920
|
-
return measured
|
|
1921
|
-
+ 'Başlıklar altında gruplanmış liste (güne/kategoriye göre) için mobilde tek `grouped-list` kur: düz `rows` + '
|
|
1922
|
-
+ '`groupBy` alan yolu; çocuk 0 bölüm başlığı (`{{ Section.title }}`), çocuk 1 öğe şablonu (`Row`, `{{ item.<alan> }}`) — '
|
|
1923
|
-
+ "platform_guide('mobile') §Güne göre görev listesi. Satır içinde düzenlenen alt liste gerekiyorsa: " + textarea;
|
|
1965
|
+
+ 'repeater tek düğümdür, dış satır başına ayrı düğüm yoktur. Satır içi listeyi tek bir textarea '
|
|
1966
|
+
+ "ile topla (satır başına bir öğe) ve kaydederken split('\n') ile böl — platform_guide('page') Kural 1g.";
|
|
1924
1967
|
}
|
|
1925
1968
|
/**
|
|
1926
1969
|
* `style` prop'u düz CSS STRING verilmiş düğümler. Çalışır (emotion string'i CSS metni sayar) ama
|
|
@@ -1934,7 +1977,7 @@ export function stringStyleNodes(nodes) {
|
|
|
1934
1977
|
for (const node of list) {
|
|
1935
1978
|
const props = (node.props ?? {});
|
|
1936
1979
|
const style = props.style;
|
|
1937
|
-
if (style && typeof style.data === 'string' && style.data.includes(':')
|
|
1980
|
+
if (style && typeof style.data === 'string' && style.data.includes(':')) {
|
|
1938
1981
|
found.push(String(node.elementId ?? node.name ?? '?'));
|
|
1939
1982
|
}
|
|
1940
1983
|
walk(asObjects(node.children));
|
|
@@ -2073,26 +2116,10 @@ export function flowBindings(schema, hostEvents) {
|
|
|
2073
2116
|
*/
|
|
2074
2117
|
export function orphanedFlowPlan(schema, pageEvents, ops) {
|
|
2075
2118
|
const nodes = asObjects(schema);
|
|
2076
|
-
|
|
2077
|
-
// `remove_component` akışı uyarısız siliyordu).
|
|
2078
|
-
const opList = asObjects(ops).flatMap(op => op.op === 'batch' ? asObjects(op.ops) : [op]);
|
|
2119
|
+
const opList = asObjects(ops);
|
|
2079
2120
|
const plan = [];
|
|
2080
|
-
// Plan yamanın SON durumuna bakar: aynı yamada başka düğüme ya da eklenen gövdeye bağlanan akış
|
|
2081
|
-
// referanssız değildir (K37-d: bağı `click`'ten `itemPress`'e taşıyan yama reddediliyordu). Aynı
|
|
2082
|
-
// yamada kaldırılan düğüme eklenen bağ sayılmaz.
|
|
2083
|
-
const removedTargets = new Set(opList.filter(op => op.op === 'remove_component').map(op => String(op.target ?? '')));
|
|
2084
|
-
const boundByPatch = new Set();
|
|
2085
|
-
for (const op of opList) {
|
|
2086
|
-
if ((op.op === 'add_event' || op.op === 'set_event') && typeof op.eventValue === 'string' && !removedTargets.has(String(op.target ?? ''))) {
|
|
2087
|
-
boundByPatch.add(op.eventValue);
|
|
2088
|
-
}
|
|
2089
|
-
if (op.op === 'add_component' && op.component && typeof op.component === 'object') {
|
|
2090
|
-
for (const flowId of collectFlowRefs(op.component))
|
|
2091
|
-
boundByPatch.add(flowId);
|
|
2092
|
-
}
|
|
2093
|
-
}
|
|
2094
2121
|
const survivingRefs = (skipElementId, skipEvent) => {
|
|
2095
|
-
const surviving = new Set(
|
|
2122
|
+
const surviving = new Set();
|
|
2096
2123
|
for (const event of asObjects(pageEvents)) {
|
|
2097
2124
|
if (typeof event.value === 'string')
|
|
2098
2125
|
surviving.add(event.value);
|
|
@@ -2142,7 +2169,7 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
|
|
|
2142
2169
|
if (op.op === 'remove_event' && target === 'page' && Array.isArray(pageEvents)) {
|
|
2143
2170
|
const hostEvents = asObjects(pageEvents);
|
|
2144
2171
|
const removed = removedBy(boundTo(hostEvents));
|
|
2145
|
-
const surviving = new Set(
|
|
2172
|
+
const surviving = new Set(hostEvents.filter(event => !removed.includes(event) && typeof event.value === 'string').map(event => String(event.value)));
|
|
2146
2173
|
collectFlowRefsExcept(nodes, '', surviving);
|
|
2147
2174
|
const flowIds = [...new Set(removed.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
|
|
2148
2175
|
if (flowIds.length > 0)
|