@appaflytech/zeyrek-ai-mcp 0.0.30 → 0.0.32
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/README.md +5 -5
- package/dist/config.js +0 -37
- package/dist/index.js +0 -2
- package/dist/knowledge/backendConstraints.js +1 -18
- package/dist/knowledge/boxSections.js +184 -0
- package/dist/knowledge/componentCatalog.js +232 -562
- package/dist/knowledge/componentEvents.js +21 -141
- package/dist/knowledge/layoutSummary.js +2 -140
- package/dist/knowledge/normalize.js +67 -236
- package/dist/knowledge/outlines.js +0 -36
- package/dist/knowledge/policy.js +4 -18
- package/dist/knowledge/reservedTables.js +0 -79
- package/dist/knowledge/rules.js +21 -319
- package/dist/knowledge/schemaGuard.js +0 -11
- package/dist/knowledge/styleResolve.js +38 -55
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +3 -6
- package/dist/platform/diagnostics.js +4 -10
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/errors.js +10 -162
- package/dist/platform/http.js +8 -29
- package/dist/platform/responses.js +5 -39
- package/dist/platform/{capture/capture.js → screenshot.js} +519 -105
- package/dist/platform/secrets.js +1 -17
- 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-detail-profile.json +1 -2
- package/dist/resources/examples/page-dynamic-form.json +2 -3
- package/dist/resources/examples/page-flex-sections.json +1 -1
- package/dist/resources/examples/page-html-embed.json +1 -1
- package/dist/resources/examples/workflow-basic.json +2 -8
- package/dist/resources/guides/component.md +4 -91
- package/dist/resources/guides/entity.md +8 -50
- package/dist/resources/guides/expressions.md +5 -14
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/getting-started.md +1 -38
- package/dist/resources/guides/layout.md +58 -55
- package/dist/resources/guides/microservice.md +2 -81
- package/dist/resources/guides/middleware.md +2 -44
- package/dist/resources/guides/page.md +75 -454
- package/dist/resources/guides/theme.md +2 -8
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +1 -58
- package/dist/resources/rules.js +5 -11
- package/dist/resources/schema-fingerprint.json +5 -7
- package/dist/resources/schemas/CreateEntityCommand.json +0 -118
- package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/CreateQueryCommand.json +0 -4
- package/dist/resources/schemas/CreateWorkflowCommand.json +1 -143
- package/dist/resources/schemas/DataJobDto.json +1 -6
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
- package/dist/resources/schemas/MicroserviceDto.json +3 -15
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
- package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -22
- package/dist/resources/schemas/StepDto.json +1 -22
- package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
- package/dist/resources/schemas/UpdateViewCommand.json +2 -0
- package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -143
- package/dist/server.js +1 -27
- package/dist/tools/access.js +2 -369
- package/dist/tools/applications.js +3 -60
- package/dist/tools/common.js +0 -7
- package/dist/tools/components.js +14 -118
- package/dist/tools/datasources.js +3 -3
- package/dist/tools/dependencies.js +1 -1
- package/dist/tools/deployments.js +2 -2
- package/dist/tools/designSchemaPatch.js +18 -34
- package/dist/tools/dtos.js +5 -36
- package/dist/tools/entities.js +12 -79
- package/dist/tools/externalComponents.js +5 -26
- package/dist/tools/flows.js +14 -122
- package/dist/tools/folders.js +1 -1
- package/dist/tools/imports.js +2 -5
- package/dist/tools/layouts.js +17 -50
- package/dist/tools/merges.js +1 -1
- package/dist/tools/microservices.js +25 -77
- package/dist/tools/pages.js +112 -465
- package/dist/tools/platformInfo.js +8 -27
- package/dist/tools/projects.js +9 -71
- package/dist/tools/rows.js +13 -69
- package/dist/tools/schemaOps.js +1 -61
- package/dist/tools/screenWrite.js +8 -37
- package/dist/tools/screens.js +5 -95
- package/dist/tools/templates.js +1 -26
- package/dist/tools/translations.js +1 -1
- package/dist/tools/variables.js +5 -11
- package/dist/tools/workflows.js +5 -10
- 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 -859
- package/dist/knowledge/mobileComponentEvents.js +0 -239
- 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/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 -243
- 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 -672
- 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 -495
- 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/UpdateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
- 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/modules.js +0 -48
- package/dist/tools/organizationStructure.js +0 -137
- package/dist/tools/profileWrite.js +0 -92
|
@@ -1,9 +1,7 @@
|
|
|
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 { STATE_STORAGE_KINDS, STEP_ALIASES } from './platform/profile.js';
|
|
6
|
-
import { inlineStyleFields } from './componentCatalog.js';
|
|
4
|
+
import { TYPED_STYLE_COMPONENTS } from './styleResolve.js';
|
|
7
5
|
const SORT_DEFAULT = { name: 'sortField', type: 'sortType', source: 'query-string' };
|
|
8
6
|
const LIMIT_DEFAULT = { name: 'limit', offset: 'offset', source: 'query-string' };
|
|
9
7
|
function asArray(value) {
|
|
@@ -271,11 +269,12 @@ export function normalizeWorkflowDefinition(definition) {
|
|
|
271
269
|
*/
|
|
272
270
|
/**
|
|
273
271
|
* Adım tipi sözlüğü backend'in, KOŞAN tipler barındırıcının: motor yedi tip register eder, web
|
|
274
|
-
* `Runtime.svelte` altı, mobil `
|
|
272
|
+
* `Runtime.svelte` altı, mobil `ScreenRuntime.tsx` beş tip ekler ve aynı sayfa kaydı ikisinde de
|
|
275
273
|
* koşar. Register edilmemiş bir tipe gelen akış sessizce ölür (`flow-engine.ts` `process()`
|
|
276
274
|
* callback bulamazsa next/completed/stopped hiç çağrılmaz), üstelik `run()` promise'i
|
|
277
275
|
* çözülmediği için `__ngAppsFlowActivity.running` sıfıra inmez. İki hâl tamamen türetilebilir
|
|
278
|
-
* olduğu için lint değil NORMALİZASYON
|
|
276
|
+
* olduğu için lint değil NORMALİZASYON — kalanı (`confirm`/`download` mobilde yok) yalnız
|
|
277
|
+
* uygulama tarafında kapanabilir, `FLOW-023` onları uyarır.
|
|
279
278
|
*/
|
|
280
279
|
function normalizeFlowHostGaps(steps, list) {
|
|
281
280
|
const fixes = [];
|
|
@@ -289,15 +288,12 @@ function normalizeFlowHostGaps(steps, list) {
|
|
|
289
288
|
.map(step => String(step.stepId ?? ''))
|
|
290
289
|
.filter(id => id.length > 0));
|
|
291
290
|
for (const step of list) {
|
|
292
|
-
// navigate ile redirect'in argümanı AYNI ({ path, pageId, query, targetBlank
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const original = String(step.type);
|
|
299
|
-
step.type = alias;
|
|
300
|
-
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`);
|
|
291
|
+
// navigate ile redirect'in argümanı AYNI ({ path, pageId, query, targetBlank }) ama navigate'i
|
|
292
|
+
// yalnız mobil register eder; redirect ise iki barındırıcıda da koşar (mobilde aynı navigate
|
|
293
|
+
// uygulamasına eşlenir), yani redirect kesin üstün.
|
|
294
|
+
if (step.type === 'navigate') {
|
|
295
|
+
step.type = 'redirect';
|
|
296
|
+
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`);
|
|
301
297
|
}
|
|
302
298
|
if (endStepIds.size === 0)
|
|
303
299
|
continue;
|
|
@@ -373,17 +369,9 @@ const REQUIRED_COLLECTIONS = ['events', 'validations', 'stateBindings', 'childre
|
|
|
373
369
|
// PropValueType (DesignComponentProperty.cs:421) — 'translation' listeden düşünce çeviriye bağlı
|
|
374
370
|
// prop'un KENDİSİ veri sanılıp static Prop'a sarılıyordu: istek 200 dönüyor, prop bozuk kuruluyordu
|
|
375
371
|
// (09-04 Y-22). Enum burada eksiksiz tutulur.
|
|
376
|
-
export const PROP_VALUE_TYPES = new Set(['static', 'file', 'flow', 'widget', 'element', 'page', 'code', 'translation'
|
|
377
|
-
// Prop'un TAŞIYICISI da aranır: `type` tek başına yetmez, çünkü liste öğesinin kendi `type` alanı
|
|
378
|
-
// olabilir ve değeri Prop tipi adıyla çakışabilir — datatable kolonunda dosya alanı tam olarak
|
|
379
|
-
// böyledir (`{ name, label, type: 'file', isFilterable }`). Yalnız `type`'a bakan sürüm o öğeyi
|
|
380
|
-
// kurulu bir Prop sanıp sarmadan bırakıyordu ve platform 500 JsonException veriyordu (koşu
|
|
381
|
-
// bulgusu S-2'nin gateway ayağı; Studio ayağı `staticFieldListItems` ile aynı kararı verdi).
|
|
372
|
+
export const PROP_VALUE_TYPES = new Set(['static', 'file', 'flow', 'widget', 'element', 'page', 'code', 'translation']);
|
|
382
373
|
function isPropShaped(value) {
|
|
383
|
-
|
|
384
|
-
return false;
|
|
385
|
-
const candidate = value;
|
|
386
|
-
return PROP_VALUE_TYPES.has(String(candidate.type)) && ('data' in candidate || 'ref' in candidate);
|
|
374
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && PROP_VALUE_TYPES.has(String(value.type));
|
|
387
375
|
}
|
|
388
376
|
function wrapPropDictionaryValues(dictionary) {
|
|
389
377
|
let wrapped = false;
|
|
@@ -626,16 +614,12 @@ export function codePropTemplateErrors(ops) {
|
|
|
626
614
|
*
|
|
627
615
|
* Seçici anahtarlara (`&__body`, `:hover`, `--token`) DOKUNULMAZ; yalnız `a-b` biçimli düz CSS
|
|
628
616
|
* özellik adları camelCase'e çevrilir ve çevrim `gatewayNormalized` ile bildirilir.
|
|
629
|
-
*
|
|
630
|
-
* TB-129 — `inlineFields` verilirse o ÜST DÜZEY alanların altına hiç girilmez: `table.style.th`
|
|
631
|
-
* gibi dallar satır içi `style` attribute'una basılır ve kebab-case zorunludur
|
|
632
|
-
* (`INLINE_STYLE_FIELDS_BY_TYPE`). Çeviri orada stili öldürüyordu.
|
|
633
617
|
*/
|
|
634
618
|
const styleKeyPattern = /^[a-z][a-z0-9]*(-[a-z0-9]+)+$/;
|
|
635
619
|
export function isStylePropName(name) {
|
|
636
620
|
return name === 'style' || /Style$/.test(name);
|
|
637
621
|
}
|
|
638
|
-
export function normalizeStyleKeys(value, label, fixed
|
|
622
|
+
export function normalizeStyleKeys(value, label, fixed) {
|
|
639
623
|
if (Array.isArray(value)) {
|
|
640
624
|
for (const entry of value)
|
|
641
625
|
normalizeStyleKeys(entry, label, fixed);
|
|
@@ -644,10 +628,7 @@ export function normalizeStyleKeys(value, label, fixed, inlineFields) {
|
|
|
644
628
|
if (!value || typeof value !== 'object')
|
|
645
629
|
return;
|
|
646
630
|
const record = value;
|
|
647
|
-
const skipped = new Set(inlineFields ?? []);
|
|
648
631
|
for (const key of Object.keys(record)) {
|
|
649
|
-
if (skipped.has(key))
|
|
650
|
-
continue;
|
|
651
632
|
normalizeStyleKeys(record[key], label, fixed);
|
|
652
633
|
if (!styleKeyPattern.test(key))
|
|
653
634
|
continue;
|
|
@@ -669,44 +650,6 @@ export function styleKeyNote(fixed) {
|
|
|
669
650
|
+ 'değer kaydedilir ama hiç uygulanmaz ve tek işareti tarayıcı konsoludur (F-06). '
|
|
670
651
|
+ "Seçici anahtarlara ('&__body', ':hover', '--token') dokunulmadı."];
|
|
671
652
|
}
|
|
672
|
-
/**
|
|
673
|
-
* Kabın `states.isDroppable`ı KATALOĞUN kararıdır. Gateway düğümü kurarken bu alanı
|
|
674
|
-
* yazmıyordu (`DEFAULT_STATES` hepsini `false` bırakır) ve Studio kanvası düğümü kap saymıyordu:
|
|
675
|
-
* imleç `scroll-view`un İÇİNDEYKEN bırakma planı sayfa kabına düşüyor, çizgi kabın üst kenarına
|
|
676
|
-
* çiziliyordu (ölçüldü 2026-09-21, `test/mobile app` › `Satislar`). Aynı tipi paletten ekleyen
|
|
677
|
-
* Studio katalog değerini yazdığı için tek şemada iki türlü davranan kap oluyordu.
|
|
678
|
-
*
|
|
679
|
-
* Değer uygulamanın KENDİ sözlüğünden gelir (`listComponents`; mobil uygulamada `type=mobile`
|
|
680
|
-
* satırları), yani kural platformdan bağımsızdır ve kuruluşun kendi komponentlerini de kapsar.
|
|
681
|
-
* Yalnız `true` yazılır: katalog bir tipi kap saymıyorsa düğüme dokunulmaz.
|
|
682
|
-
*/
|
|
683
|
-
export function normalizeDroppableStates(nodes, droppable) {
|
|
684
|
-
const fixed = [];
|
|
685
|
-
if (droppable.size === 0)
|
|
686
|
-
return fixed;
|
|
687
|
-
for (const node of asObjects(nodes)) {
|
|
688
|
-
const type = typeof node.type === 'string' ? node.type : '';
|
|
689
|
-
if (droppable.get(type) === true) {
|
|
690
|
-
// `states` normalde `normalizeComponentDefaults`tan geçmiş olur; gelmediyse burada da
|
|
691
|
-
// eksiksiz kurulur — yarım `states` platformda NullReference üretir.
|
|
692
|
-
if (!node.states || typeof node.states !== 'object' || Array.isArray(node.states)) {
|
|
693
|
-
node.states = { ...DEFAULT_STATES };
|
|
694
|
-
}
|
|
695
|
-
const states = node.states;
|
|
696
|
-
if (states.isDroppable !== true) {
|
|
697
|
-
states.isDroppable = true;
|
|
698
|
-
fixed.push(`'${String(node.elementId ?? node.name ?? type)}' (${type})`);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
fixed.push(...normalizeDroppableStates(node.children, droppable));
|
|
702
|
-
}
|
|
703
|
-
return fixed;
|
|
704
|
-
}
|
|
705
|
-
export function droppableStatesNote(fixed) {
|
|
706
|
-
return fixed.length === 0
|
|
707
|
-
? []
|
|
708
|
-
: [`states.isDroppable katalogdan yazıldı (${fixed.join(' · ')}) — kataloğun kap saydığı düğüm Studio kanvasında da kap olmalı; alanı bilerek kapatmak için resize_component/set_states kullanın`];
|
|
709
|
-
}
|
|
710
653
|
export function normalizeComponentDefaults(nodes) {
|
|
711
654
|
const fixed = [];
|
|
712
655
|
for (const node of asObjects(nodes)) {
|
|
@@ -746,10 +689,8 @@ export function normalizeComponentDefaults(nodes) {
|
|
|
746
689
|
if (node.props && typeof node.props === 'object' && !Array.isArray(node.props)) {
|
|
747
690
|
const props = node.props;
|
|
748
691
|
const styleKeys = [];
|
|
749
|
-
// Satır içi stil dalları komponent TİPİNE göre atlanır; tip bilinmiyorsa eski davranış.
|
|
750
|
-
const inlineFields = (name) => name === 'style' ? inlineStyleFields(typeof node.type === 'string' ? node.type : undefined) : undefined;
|
|
751
692
|
for (const name of Object.keys(props).filter(isStylePropName)) {
|
|
752
|
-
normalizeStyleKeys(props[name], `${String(node.elementId ?? node.name ?? '?')}.${name}`, styleKeys
|
|
693
|
+
normalizeStyleKeys(props[name], `${String(node.elementId ?? node.name ?? '?')}.${name}`, styleKeys);
|
|
753
694
|
}
|
|
754
695
|
if (styleKeys.length > 0)
|
|
755
696
|
missing.push(`stil anahtarları camelCase'e çevrildi: ${styleKeys.join(' · ')}`);
|
|
@@ -854,31 +795,19 @@ function normalizeReplacePropValue(op) {
|
|
|
854
795
|
}
|
|
855
796
|
return notes;
|
|
856
797
|
}
|
|
857
|
-
// connectData sarmalı burada değiştirilmez: gövde duvarı (CD-005, `connectDataOpIssues`) op'u
|
|
858
|
-
// set_connect_data'ya yönlendirerek rejectedOps'a yazar; burada atmak listeyi tek hataya indirirdi.
|
|
859
|
-
if (propType === 'connectData')
|
|
860
|
-
return notes;
|
|
861
798
|
// Applier her sarmalın tipini korur, ama page/file/flow/widget/element taşıyıcıları başka alanlara
|
|
862
799
|
// (FlowId, RedirectPageId, dosya) yazılır ve bu op'la bağları kurulmaz. Remove+add önerilmez:
|
|
863
800
|
// düğümü yeniden kurmak ona yazan setter iteratee'lerinin element'ini siler (G-04, FLOW-018).
|
|
864
801
|
throw new PlatformApiError(`${label}: '${propType}' tipli Prop replace_prop ile kurulmaz — bu op static, code ve translation sarmalını taşır. Komponenti silip yeniden EKLEMEYİN: ona yazan setter adımlarının hedefi silinir (FLOW-018). Akış bağı için set_event, diğer tipler için page_update(schema) ile tam şema yazın.`, 400);
|
|
865
802
|
}
|
|
866
|
-
|
|
867
|
-
* `typesByElementId` — TB-129: `replace_prop` op'u yalnız elementId taşır, stil çevirisinin
|
|
868
|
-
* komponent tipine bakabilmesi için haritayı çağıran (okuduğu şemadan) verir. Verilmezse çeviri
|
|
869
|
-
* tip ayrımı yapmaz; bu, harita okunamadığında yazmayı engellememek için bilinçli düşüştür.
|
|
870
|
-
*/
|
|
871
|
-
export function normalizeSchemaOps(ops, typesByElementId) {
|
|
803
|
+
export function normalizeSchemaOps(ops) {
|
|
872
804
|
const components = [];
|
|
873
805
|
const props = [];
|
|
874
806
|
const validations = [];
|
|
875
807
|
for (const op of asObjects(ops)) {
|
|
876
808
|
if (op.op === 'replace_prop') {
|
|
877
809
|
if (isStylePropName(String(op.prop ?? ''))) {
|
|
878
|
-
|
|
879
|
-
? inlineStyleFields(typesByElementId?.get(String(op.target ?? '')))
|
|
880
|
-
: undefined;
|
|
881
|
-
normalizeStyleKeys(op.value, `'${String(op.target ?? '?')}.${String(op.prop)}'`, props, inline);
|
|
810
|
+
normalizeStyleKeys(op.value, `'${String(op.target ?? '?')}.${String(op.prop)}'`, props);
|
|
882
811
|
}
|
|
883
812
|
props.push(...normalizeReplacePropValue(op));
|
|
884
813
|
continue;
|
|
@@ -955,11 +884,11 @@ export function pageContainerNode() {
|
|
|
955
884
|
* çekilirlerse sayfa içeriğinin akışına girer ve katman olarak açılmazlar.
|
|
956
885
|
*/
|
|
957
886
|
const ROOT_LAYER_TYPES = new Set(['modal', 'drawer']);
|
|
958
|
-
export function ensurePageContainer(schema
|
|
887
|
+
export function ensurePageContainer(schema) {
|
|
959
888
|
const nodes = asObjects(schema);
|
|
960
889
|
if (nodes.some(node => node.elementId === PAGE_CONTAINER_ELEMENT_ID))
|
|
961
890
|
return { schema: nodes, fixes: [] };
|
|
962
|
-
const container =
|
|
891
|
+
const container = pageContainerNode();
|
|
963
892
|
const layers = nodes.filter(node => ROOT_LAYER_TYPES.has(String(node.type ?? '')));
|
|
964
893
|
container.children = nodes.filter(node => !ROOT_LAYER_TYPES.has(String(node.type ?? '')));
|
|
965
894
|
const moved = container.children.length;
|
|
@@ -1002,7 +931,7 @@ export function clampBlockSizes(nodes, maxSizes) {
|
|
|
1002
931
|
* başlatır (`ComponentHeightType.Fixed = 0`), yani "alan yok" = "sabit yükseklik". Studio'nun
|
|
1003
932
|
* kendi bırakma yolu bunu ASLA yapmaz: katalogdaki `isDefaultAutoHeight`e bakıp
|
|
1004
933
|
* `heightType: isDefaultAutoHeight ? 'auto' : 'fixed'` yazar
|
|
1005
|
-
* (`ScreenBuilderDroppable.svelte:701`, `store-converter.ts`
|
|
934
|
+
* (`ScreenBuilderDroppable.svelte:701`, `store-converter.ts:233`). Katalogda varsayılan
|
|
1006
935
|
* `true`'dur (`ZeyrekComponent.ts:62`); `false` diyen yalnız sekiz tip var — auth-layout, html,
|
|
1007
936
|
* image, layout, qrcode, table, text-editor, video.
|
|
1008
937
|
*
|
|
@@ -1788,18 +1717,19 @@ export function viewAliasNote(fixes) {
|
|
|
1788
1717
|
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ü`];
|
|
1789
1718
|
}
|
|
1790
1719
|
/**
|
|
1791
|
-
*
|
|
1792
|
-
*
|
|
1793
|
-
*
|
|
1720
|
+
* Değişken seti tek bir kayıtta yaşar: `CreateAppVariableCommand`/`CreatePageVariableCommand`
|
|
1721
|
+
* yalnız `Data` alanı taşır (Studio uygulama başına ve sayfa başına TEK satır tutar —
|
|
1722
|
+
* `IsVariableExistForApplicationAsync` doluysa create update'e döner). Studio'nun gönderdiği şekil
|
|
1723
|
+
* `data`'nın **JSON string** olmasıdır: "[{\"key\":\"MyTest\",\"value\":{\"isActive\":true}}]".
|
|
1724
|
+
* `Data` tipi `object` olduğu için platform her gövdeyi kabul eder; alan adı tutmayan bir gövde
|
|
1725
|
+
* (name/type/defaultValue gibi) `Data`'yı null bırakır ve istek 200 döner ama HİÇBİR ŞEY yazılmaz
|
|
1726
|
+
* (17/Ç1). Okuma tarafı da aynı string'i geri verir (`AppVariablesDto.Map` → GetRawText).
|
|
1794
1727
|
*/
|
|
1795
1728
|
export function parseVariableEntries(data) {
|
|
1796
1729
|
const source = typeof data === 'string' ? safeParse(data) : data;
|
|
1797
1730
|
return asObjects(source)
|
|
1798
1731
|
.filter(entry => typeof entry.key === 'string' && entry.key !== '')
|
|
1799
|
-
.map(entry => {
|
|
1800
|
-
const storage = STATE_STORAGE_KINDS.find(kind => kind === entry.storage);
|
|
1801
|
-
return { key: String(entry.key), value: entry.value, ...(storage ? { storage } : {}) };
|
|
1802
|
-
});
|
|
1732
|
+
.map(entry => ({ key: String(entry.key), value: entry.value }));
|
|
1803
1733
|
}
|
|
1804
1734
|
function safeParse(value) {
|
|
1805
1735
|
try {
|
|
@@ -1814,29 +1744,17 @@ function safeParse(value) {
|
|
|
1814
1744
|
* mevcut seti okuyup anahtar bazında birleştirir; `replace: true` verilirse bilinçli olarak ezer.
|
|
1815
1745
|
*/
|
|
1816
1746
|
export function mergeVariableEntries(existing, incoming, replace) {
|
|
1817
|
-
const stored = (entry, current) => {
|
|
1818
|
-
const storage = entry.storage === undefined ? current?.storage : STATE_STORAGE_KINDS.find(kind => kind === entry.storage);
|
|
1819
|
-
const value = entry.value === undefined ? (current ? current.value : null) : entry.value;
|
|
1820
|
-
return { key: entry.key, value, ...(storage ? { storage } : {}) };
|
|
1821
|
-
};
|
|
1822
1747
|
if (replace)
|
|
1823
|
-
return { entries: incoming
|
|
1748
|
+
return { entries: incoming, fixes: [] };
|
|
1824
1749
|
const merged = [...existing];
|
|
1825
1750
|
const kept = [];
|
|
1826
|
-
const keptStorage = [];
|
|
1827
|
-
const keptValue = [];
|
|
1828
1751
|
for (const entry of incoming) {
|
|
1829
1752
|
const index = merged.findIndex(current => current.key === entry.key);
|
|
1830
1753
|
if (index === -1) {
|
|
1831
|
-
merged.push(
|
|
1754
|
+
merged.push(entry);
|
|
1832
1755
|
continue;
|
|
1833
1756
|
}
|
|
1834
|
-
|
|
1835
|
-
if (entry.storage === undefined && current?.storage)
|
|
1836
|
-
keptStorage.push(`'${entry.key}' → ${current.storage}`);
|
|
1837
|
-
if (entry.value === undefined)
|
|
1838
|
-
keptValue.push(`'${entry.key}'`);
|
|
1839
|
-
merged[index] = stored(entry, current);
|
|
1757
|
+
merged[index] = entry;
|
|
1840
1758
|
}
|
|
1841
1759
|
for (const entry of existing) {
|
|
1842
1760
|
if (!incoming.some(current => current.key === entry.key))
|
|
@@ -1844,17 +1762,9 @@ export function mergeVariableEntries(existing, incoming, replace) {
|
|
|
1844
1762
|
}
|
|
1845
1763
|
return {
|
|
1846
1764
|
entries: merged,
|
|
1847
|
-
fixes:
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
: []),
|
|
1851
|
-
...(keptStorage.length > 0
|
|
1852
|
-
? [`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`]
|
|
1853
|
-
: []),
|
|
1854
|
-
...(keptValue.length > 0
|
|
1855
|
-
? [`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`]
|
|
1856
|
-
: [])
|
|
1857
|
-
]
|
|
1765
|
+
fixes: kept.length > 0
|
|
1766
|
+
? [`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`]
|
|
1767
|
+
: []
|
|
1858
1768
|
};
|
|
1859
1769
|
}
|
|
1860
1770
|
export function blockSizeNote(clamped) {
|
|
@@ -1935,22 +1845,12 @@ export function nestedRepeaterNodes(nodes) {
|
|
|
1935
1845
|
walk(asObjects(nodes), false);
|
|
1936
1846
|
return found;
|
|
1937
1847
|
}
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
* `grouped-list` (ui-native, ADR 0007). Web'de karşılığı yok — web mesajı textarea tarifinde kalır.
|
|
1941
|
-
*/
|
|
1942
|
-
export function nestedRepeaterMessage(ids, platform = 'web') {
|
|
1943
|
-
const measured = `PAGE-013 — repeater içinde repeater (istek gönderilmedi): ${ids.join(' · ')}. `
|
|
1848
|
+
export function nestedRepeaterMessage(ids) {
|
|
1849
|
+
return `PAGE-013 — repeater içinde repeater (istek gönderilmedi): ${ids.join(' · ')}. `
|
|
1944
1850
|
+ 'Ölçüldü (2026-08-19): iç repeater OKUMADA çalışır ama girilen değer dış satıra GERİ YAZILMAZ '
|
|
1945
1851
|
+ '(_repeaterValues null kalır) ve tek düzenlemeden sonra DOM bozulur. Sebep yapısal: şemada iç '
|
|
1946
|
-
+ 'repeater tek düğümdür, dış satır başına ayrı düğüm yoktur. '
|
|
1947
|
-
|
|
1948
|
-
if (platform !== 'mobile')
|
|
1949
|
-
return measured + textarea;
|
|
1950
|
-
return measured
|
|
1951
|
-
+ 'Başlıklar altında gruplanmış liste (güne/kategoriye göre) için mobilde tek `grouped-list` kur: düz `rows` + '
|
|
1952
|
-
+ '`groupBy` alan yolu; çocuk 0 bölüm başlığı (`{{ Section.title }}`), çocuk 1 öğe şablonu (`Row`, `{{ item.<alan> }}`) — '
|
|
1953
|
-
+ "platform_guide('mobile') §Güne göre görev listesi. Satır içinde düzenlenen alt liste gerekiyorsa: " + textarea;
|
|
1852
|
+
+ 'repeater tek düğümdür, dış satır başına ayrı düğüm yoktur. Satır içi listeyi tek bir textarea '
|
|
1853
|
+
+ "ile topla (satır başına bir öğe) ve kaydederken split('\n') ile böl — platform_guide('page') Kural 1g.";
|
|
1954
1854
|
}
|
|
1955
1855
|
/**
|
|
1956
1856
|
* `style` prop'u düz CSS STRING verilmiş düğümler. Çalışır (emotion string'i CSS metni sayar) ama
|
|
@@ -1964,7 +1864,7 @@ export function stringStyleNodes(nodes) {
|
|
|
1964
1864
|
for (const node of list) {
|
|
1965
1865
|
const props = (node.props ?? {});
|
|
1966
1866
|
const style = props.style;
|
|
1967
|
-
if (style && typeof style.data === 'string' && style.data.includes(':')
|
|
1867
|
+
if (style && typeof style.data === 'string' && style.data.includes(':')) {
|
|
1968
1868
|
found.push(String(node.elementId ?? node.name ?? '?'));
|
|
1969
1869
|
}
|
|
1970
1870
|
walk(asObjects(node.children));
|
|
@@ -2095,95 +1995,6 @@ export function flowBindings(schema, hostEvents) {
|
|
|
2095
1995
|
visitNode(node);
|
|
2096
1996
|
return bindings;
|
|
2097
1997
|
}
|
|
2098
|
-
/**
|
|
2099
|
-
* TB-125 — op listesi UYGULANDIKTAN sonra şemada (ve düzey olaylarında) hâlâ referanslı olan
|
|
2100
|
-
* akışlar. Simülasyon yalnız akış referansını umursar: eklenen düğüm ağacın köküne konur (konum
|
|
2101
|
-
* sayıma girmez), silinen düğüm ağaçtan çıkarılır, olay op'ları olay dizisini günceller.
|
|
2102
|
-
* `batch` op'u iç listesiyle düzleştirilir.
|
|
2103
|
-
*/
|
|
2104
|
-
function survivingFlowRefs(nodes, hostEvents, ops) {
|
|
2105
|
-
const simulated = structuredClone(nodes);
|
|
2106
|
-
const simulatedHostEvents = structuredClone(hostEvents);
|
|
2107
|
-
const removeNode = (list, target) => {
|
|
2108
|
-
const index = list.findIndex(node => node.elementId === target);
|
|
2109
|
-
if (index >= 0) {
|
|
2110
|
-
list.splice(index, 1);
|
|
2111
|
-
return true;
|
|
2112
|
-
}
|
|
2113
|
-
for (const node of list) {
|
|
2114
|
-
if (Array.isArray(node.children) && removeNode(node.children, target))
|
|
2115
|
-
return true;
|
|
2116
|
-
}
|
|
2117
|
-
return false;
|
|
2118
|
-
};
|
|
2119
|
-
const eventsOf = (target) => {
|
|
2120
|
-
if (target === 'page')
|
|
2121
|
-
return simulatedHostEvents;
|
|
2122
|
-
const node = findNodeByElementId(simulated, target);
|
|
2123
|
-
if (!node)
|
|
2124
|
-
return undefined;
|
|
2125
|
-
if (!Array.isArray(node.events))
|
|
2126
|
-
node.events = [];
|
|
2127
|
-
return node.events;
|
|
2128
|
-
};
|
|
2129
|
-
const apply = (op) => {
|
|
2130
|
-
if (op.op === 'batch') {
|
|
2131
|
-
for (const inner of asObjects(op.ops))
|
|
2132
|
-
apply(inner);
|
|
2133
|
-
return;
|
|
2134
|
-
}
|
|
2135
|
-
if (op.op === 'add_component' && op.component && typeof op.component === 'object') {
|
|
2136
|
-
simulated.push(structuredClone(op.component));
|
|
2137
|
-
return;
|
|
2138
|
-
}
|
|
2139
|
-
const target = String(op.target ?? '');
|
|
2140
|
-
if (target === '')
|
|
2141
|
-
return;
|
|
2142
|
-
if (op.op === 'remove_component') {
|
|
2143
|
-
removeNode(simulated, target);
|
|
2144
|
-
return;
|
|
2145
|
-
}
|
|
2146
|
-
if (op.op !== 'set_event' && op.op !== 'add_event' && op.op !== 'remove_event')
|
|
2147
|
-
return;
|
|
2148
|
-
const events = eventsOf(target);
|
|
2149
|
-
if (events === undefined)
|
|
2150
|
-
return;
|
|
2151
|
-
const eventName = String(op.event ?? '');
|
|
2152
|
-
const eventValue = typeof op.eventValue === 'string' ? op.eventValue : undefined;
|
|
2153
|
-
const named = events.filter(event => String(event.name ?? '') === eventName && typeof event.value === 'string' && event.value !== '');
|
|
2154
|
-
if (op.op === 'add_event') {
|
|
2155
|
-
if (eventValue !== undefined)
|
|
2156
|
-
events.push({ name: eventName, value: eventValue });
|
|
2157
|
-
return;
|
|
2158
|
-
}
|
|
2159
|
-
if (op.op === 'set_event') {
|
|
2160
|
-
// set_event adın BÜTÜN bağlarını tek kayda indirir.
|
|
2161
|
-
for (const event of named)
|
|
2162
|
-
events.splice(events.indexOf(event), 1);
|
|
2163
|
-
if (eventValue !== undefined)
|
|
2164
|
-
events.push({ name: eventName, value: eventValue });
|
|
2165
|
-
return;
|
|
2166
|
-
}
|
|
2167
|
-
// Değersiz remove_event çoklu bağda platformda ambiguous-event ile düşer: hiçbir bağ kalkmaz.
|
|
2168
|
-
const removed = eventValue === undefined
|
|
2169
|
-
? (named.length === 1 ? named : [])
|
|
2170
|
-
: named.filter(event => event.value === eventValue);
|
|
2171
|
-
for (const event of removed)
|
|
2172
|
-
events.splice(events.indexOf(event), 1);
|
|
2173
|
-
};
|
|
2174
|
-
for (const op of ops)
|
|
2175
|
-
apply(op);
|
|
2176
|
-
const surviving = new Set();
|
|
2177
|
-
for (const event of simulatedHostEvents) {
|
|
2178
|
-
if (typeof event.value === 'string')
|
|
2179
|
-
surviving.add(event.value);
|
|
2180
|
-
}
|
|
2181
|
-
for (const node of simulated) {
|
|
2182
|
-
for (const flowId of collectFlowRefs(node))
|
|
2183
|
-
surviving.add(flowId);
|
|
2184
|
-
}
|
|
2185
|
-
return surviving;
|
|
2186
|
-
}
|
|
2187
1998
|
/**
|
|
2188
1999
|
* Bir yamanın SİLECEĞİ akışlar. Platform referanssız kalan akışı KALICI siler; uyarı yamadan sonra
|
|
2189
2000
|
* geldiğinde "önce yedekle" tavsiyesi uygulanamaz hâle geliyordu (09-05 koşusu: sekiz adımlı giriş
|
|
@@ -2192,15 +2003,26 @@ function survivingFlowRefs(nodes, hostEvents, ops) {
|
|
|
2192
2003
|
*/
|
|
2193
2004
|
export function orphanedFlowPlan(schema, pageEvents, ops) {
|
|
2194
2005
|
const nodes = asObjects(schema);
|
|
2195
|
-
|
|
2196
|
-
// `remove_component` akışı uyarısız siliyordu).
|
|
2197
|
-
const opList = asObjects(ops).flatMap(op => op.op === 'batch' ? asObjects(op.ops) : [op]);
|
|
2006
|
+
const opList = asObjects(ops);
|
|
2198
2007
|
const plan = [];
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2008
|
+
const survivingRefs = (skipElementId, skipEvent) => {
|
|
2009
|
+
const surviving = new Set();
|
|
2010
|
+
for (const event of asObjects(pageEvents)) {
|
|
2011
|
+
if (typeof event.value === 'string')
|
|
2012
|
+
surviving.add(event.value);
|
|
2013
|
+
}
|
|
2014
|
+
collectFlowRefsExcept(nodes, skipElementId, surviving);
|
|
2015
|
+
if (skipEvent !== undefined) {
|
|
2016
|
+
const node = findNodeByElementId(nodes, skipElementId);
|
|
2017
|
+
for (const event of asObjects(node?.events)) {
|
|
2018
|
+
if (String(event.name ?? '') !== skipEvent && typeof event.value === 'string')
|
|
2019
|
+
surviving.add(event.value);
|
|
2020
|
+
}
|
|
2021
|
+
for (const flowId of collectFlowRefs({ ...(node ?? {}), events: [] }))
|
|
2022
|
+
surviving.add(flowId);
|
|
2023
|
+
}
|
|
2024
|
+
return surviving;
|
|
2025
|
+
};
|
|
2204
2026
|
for (const op of opList) {
|
|
2205
2027
|
const target = String(op.target ?? '');
|
|
2206
2028
|
if (target === '')
|
|
@@ -2210,6 +2032,7 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
|
|
|
2210
2032
|
if (!doomed)
|
|
2211
2033
|
continue;
|
|
2212
2034
|
const losing = collectFlowRefs(doomed);
|
|
2035
|
+
const surviving = survivingRefs(target);
|
|
2213
2036
|
const orphaned = [...losing].filter(flowId => !surviving.has(flowId));
|
|
2214
2037
|
if (orphaned.length > 0)
|
|
2215
2038
|
plan.push({ target, op: 'remove_component', flowIds: orphaned });
|
|
@@ -2231,7 +2054,10 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
|
|
|
2231
2054
|
// oraya bağlı akış kapıdan geçip kalıcı silinirdi. Düzey olayı olmayan widget'ta applier da
|
|
2232
2055
|
// düğüm aramasına düşer.
|
|
2233
2056
|
if (op.op === 'remove_event' && target === 'page' && Array.isArray(pageEvents)) {
|
|
2234
|
-
const
|
|
2057
|
+
const hostEvents = asObjects(pageEvents);
|
|
2058
|
+
const removed = removedBy(boundTo(hostEvents));
|
|
2059
|
+
const surviving = new Set(hostEvents.filter(event => !removed.includes(event) && typeof event.value === 'string').map(event => String(event.value)));
|
|
2060
|
+
collectFlowRefsExcept(nodes, '', surviving);
|
|
2235
2061
|
const flowIds = [...new Set(removed.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
|
|
2236
2062
|
if (flowIds.length > 0)
|
|
2237
2063
|
plan.push({ target, op: 'remove_event', flowIds });
|
|
@@ -2243,6 +2069,11 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
|
|
|
2243
2069
|
const losing = op.op === 'set_event' ? named.filter(event => event.value !== eventValue) : removedBy(named);
|
|
2244
2070
|
if (losing.length === 0)
|
|
2245
2071
|
continue;
|
|
2072
|
+
const surviving = survivingRefs(target, eventName);
|
|
2073
|
+
for (const event of named) {
|
|
2074
|
+
if (!losing.includes(event))
|
|
2075
|
+
surviving.add(String(event.value));
|
|
2076
|
+
}
|
|
2246
2077
|
const flowIds = [...new Set(losing.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
|
|
2247
2078
|
if (flowIds.length > 0)
|
|
2248
2079
|
plan.push({ target, op: String(op.op), flowIds });
|
|
@@ -357,39 +357,3 @@ export function functionOutline(definition) {
|
|
|
357
357
|
view: 'outline'
|
|
358
358
|
};
|
|
359
359
|
}
|
|
360
|
-
export function processOutline(payload) {
|
|
361
|
-
const model = (payload.definition && typeof payload.definition === 'object' ? payload.definition : payload);
|
|
362
|
-
const describeAssignee = (value) => {
|
|
363
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
364
|
-
return value ?? null;
|
|
365
|
-
const assignee = value;
|
|
366
|
-
const rule = [assignee.rule, assignee.arg].filter(part => part !== undefined && part !== null).join(':');
|
|
367
|
-
return assignee.of ? `${rule} of ${String(assignee.of)}` : rule;
|
|
368
|
-
};
|
|
369
|
-
const describeNodes = (nodes, depth) => asArray(nodes).flatMap(node => [{
|
|
370
|
-
id: node.id,
|
|
371
|
-
type: node.type,
|
|
372
|
-
depth,
|
|
373
|
-
editable: node.editable ?? 'locked',
|
|
374
|
-
description: node.description ?? null,
|
|
375
|
-
assignee: describeAssignee(node.assignee ?? node.to),
|
|
376
|
-
policy: node.policy ?? null,
|
|
377
|
-
sla: Array.isArray(node.sla) ? asArray(node.sla).map(sla => sla.duration) : node.sla ?? null,
|
|
378
|
-
on: asArray(node.on).map(handler => `${String(handler.event)} → ${String(handler.handler?.type ?? '?')}${handler.afterHandlers ? ` (${String(handler.afterHandlers)})` : ''}`)
|
|
379
|
-
}, ...describeNodes(node.nodes, depth + 1)]);
|
|
380
|
-
const nodes = describeNodes(model.nodes, 0);
|
|
381
|
-
return {
|
|
382
|
-
id: payload.id ?? null,
|
|
383
|
-
slug: model.slug ?? payload.slug,
|
|
384
|
-
name: model.name ?? payload.name,
|
|
385
|
-
version: payload.version ?? null,
|
|
386
|
-
activeVersionId: payload.activeVersionId ?? null,
|
|
387
|
-
versions: asArray(payload.versions).map(version => ({ number: version.number, state: version.state })),
|
|
388
|
-
nodeCount: nodes.length,
|
|
389
|
-
nodes,
|
|
390
|
-
edgeCount: asArray(model.edges).length,
|
|
391
|
-
on: asArray(model.on).map(handler => String(handler.event)),
|
|
392
|
-
view: 'outline',
|
|
393
|
-
hint: "Tek düğüm için process_definition_get view:'part', part:'definition.nodes[id=<düğüm>]'; değişiklik için process_definition_patch (yol /nodes[id=<düğüm>]/…)."
|
|
394
|
-
};
|
|
395
|
-
}
|
package/dist/knowledge/policy.js
CHANGED
|
@@ -1,27 +1,13 @@
|
|
|
1
1
|
import { logStep } from '../observability/trace.js';
|
|
2
2
|
export class PolicyBlockError extends Error {
|
|
3
3
|
findings;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* `canOverride` kaçış cümlesini seçer. Her tool `policyOverride` girdisini
|
|
7
|
-
* TAŞIMAZ (row_*, datasource_*, folder_*, project_*, translation_*,
|
|
8
|
-
* external_component_*): oralarda "aynı çağrıyı policyOverride ile
|
|
9
|
-
* tekrarlayın" demek olmayan bir alana yönlendirmekti ve çağıran aynı
|
|
10
|
-
* isteği ikinci kez gönderip aynı duvara çarpıyordu (S-12, 2026-09-19).
|
|
11
|
-
* Girdiyi taşıyan tool'larda da mutlak kapılar vardır (BPM-001/014/018
|
|
12
|
-
* ortam ve imza kapıları): orada da bu dal seçilir, o yüzden cümle "bu
|
|
13
|
-
* çağrı" der.
|
|
14
|
-
*/
|
|
15
|
-
constructor(findings, canOverride = true) {
|
|
4
|
+
constructor(findings) {
|
|
16
5
|
super([
|
|
17
6
|
'Politika kontrolü isteği durdurdu (istek platforma gönderilmedi):',
|
|
18
7
|
...findings.map(finding => `- [${finding.ruleId}] ${finding.message}${finding.guide ? ` (rehber: ${finding.guide})` : ''}`),
|
|
19
|
-
|
|
20
|
-
? "Bilinçli bir istisnaysa aynı çağrıyı policyOverride: true ile tekrarlayın; kural yanlışsa zeyrek-mcp/docs/08-kural-envanteri.md'ye işleyin."
|
|
21
|
-
: "Bu çağrı policyOverride kabul etmez: çağrıyı kuralı sağlayacak biçimde değiştirin; kural yanlışsa zeyrek-mcp/docs/08-kural-envanteri.md'ye işleyin."
|
|
8
|
+
"Bilinçli bir istisnaysa aynı çağrıyı policyOverride: true ile tekrarlayın; kural yanlışsa zeyrek-mcp/docs/08-kural-envanteri.md'ye işleyin."
|
|
22
9
|
].join('\n'));
|
|
23
10
|
this.findings = findings;
|
|
24
|
-
this.canOverride = canOverride;
|
|
25
11
|
this.name = 'PolicyBlockError';
|
|
26
12
|
}
|
|
27
13
|
}
|
|
@@ -49,11 +35,11 @@ export function evaluatePolicy(config, rules, module, definition, context, polic
|
|
|
49
35
|
logStep('politika', `${module}/${context.operation}${context.workflowKind ? ` (${context.workflowKind})` : ''} · ${applicable.length} kural denendi · ${findings.length === 0 ? 'bulgu yok' : `${findings.length} bulgu`}${policyOverride ? ' · policyOverride açık' : ''}`, findings.map(finding => `[${finding.ruleId}] ${finding.severity}: ${finding.message}`));
|
|
50
36
|
return findings;
|
|
51
37
|
}
|
|
52
|
-
export function enforcePolicy(findings
|
|
38
|
+
export function enforcePolicy(findings) {
|
|
53
39
|
const blocking = findings.filter(finding => finding.severity === 'block');
|
|
54
40
|
if (blocking.length > 0) {
|
|
55
41
|
logStep('politika ✕', `${blocking.length} block bulgusu isteği durdurdu — platforma HİÇBİR istek gitmedi`, blocking.map(finding => `[${finding.ruleId}] ${finding.message}`));
|
|
56
|
-
throw new PolicyBlockError(blocking
|
|
42
|
+
throw new PolicyBlockError(blocking);
|
|
57
43
|
}
|
|
58
44
|
return findings;
|
|
59
45
|
}
|