@appaflytech/zeyrek-ai-mcp 0.0.32 → 0.0.33
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 +15 -0
- package/dist/config.js +11 -0
- package/dist/index.js +2 -0
- package/dist/knowledge/access.js +802 -0
- package/dist/knowledge/case.js +41 -0
- package/dist/knowledge/componentCatalog.js +82 -213
- package/dist/knowledge/componentEvents.js +21 -19
- package/dist/knowledge/connectDataBind.js +819 -0
- package/dist/knowledge/connectDataDefinition.js +341 -0
- package/dist/knowledge/connectDataExecute.js +93 -0
- package/dist/knowledge/connectDataRules.js +128 -0
- package/dist/knowledge/decision.js +121 -0
- package/dist/knowledge/expressionPrelude.js +59 -0
- package/dist/knowledge/layoutSummary.js +140 -2
- package/dist/knowledge/microserviceParameters.js +58 -0
- package/dist/knowledge/mining.js +94 -0
- package/dist/knowledge/mobileComponentCatalog.js +864 -0
- package/dist/knowledge/mobileComponentEvents.js +239 -0
- package/dist/knowledge/mobileStore.js +227 -0
- package/dist/knowledge/normalize.js +121 -35
- package/dist/knowledge/platform/lint.js +385 -0
- package/dist/knowledge/platform/mobile.js +142 -0
- package/dist/knowledge/platform/mobileLayoutLint.js +324 -0
- package/dist/knowledge/platform/mobileRules.js +231 -0
- package/dist/knowledge/platform/mobileSpacing.js +82 -0
- package/dist/knowledge/platform/mobileTabs.js +108 -0
- package/dist/knowledge/platform/nativeBoxModel.js +44 -0
- package/dist/knowledge/platform/profile.js +25 -0
- package/dist/knowledge/platform/resolve.js +122 -0
- package/dist/knowledge/platform/web.js +39 -0
- package/dist/knowledge/process.js +510 -0
- package/dist/knowledge/rowFilter.js +43 -0
- package/dist/knowledge/rules.js +291 -19
- package/dist/knowledge/styleResolve.js +55 -38
- package/dist/knowledge/styleResolveNative.js +527 -0
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +1 -1
- package/dist/platform/argumentAliases.js +128 -0
- package/dist/platform/bodyFile.js +103 -0
- package/dist/platform/capture/actions.js +333 -0
- package/dist/platform/capture/browser.js +1 -0
- package/dist/platform/{screenshot.js → capture/capture.js} +81 -519
- package/dist/platform/capture/console-log.js +122 -0
- package/dist/platform/capture/index.js +11 -0
- package/dist/platform/capture/readiness.js +103 -0
- package/dist/platform/capture/summary.js +77 -0
- package/dist/platform/capture/target.js +5 -0
- package/dist/platform/capture/targets/studio-mobile.js +15 -0
- package/dist/platform/capture/targets/studio-web.js +5 -0
- package/dist/platform/diagnostics.js +10 -4
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/http.js +23 -7
- package/dist/platform/impersonation.js +45 -0
- package/dist/platform/jsonArray.js +24 -0
- package/dist/platform/responses.js +6 -2
- package/dist/platform/schemaReadMemory.js +60 -0
- package/dist/platform/secrets.js +9 -0
- package/dist/platform/strictArguments.js +68 -12
- package/dist/platform/tokenVault.js +187 -4
- package/dist/resources/examples/bpm-gorev-kontrol.json +294 -0
- package/dist/resources/examples/bpm-iso-dokuman.json +228 -0
- package/dist/resources/examples/bpm-satinalma.json +376 -0
- package/dist/resources/examples/connect-data-convert-verify.json +107 -0
- package/dist/resources/examples/connect-data-dropdown-roles.json +66 -0
- package/dist/resources/examples/connect-data-edit-m2m.json +73 -0
- package/dist/resources/examples/connect-data-query-params.json +50 -0
- package/dist/resources/examples/connect-data-table-entity.json +147 -0
- package/dist/resources/examples/connect-data-workflow-microservice.json +65 -0
- package/dist/resources/examples/layout-app-shell.json +229 -707
- package/dist/resources/examples/mobile-app-shell-drawer.json +244 -0
- package/dist/resources/examples/mobile-app-shell-stack.json +157 -0
- package/dist/resources/examples/mobile-app-shell-tab.json +208 -0
- package/dist/resources/examples/mobile-form-screen.json +365 -0
- package/dist/resources/examples/mobile-list-detail-form.json +703 -0
- package/dist/resources/examples/page-flex-sections.json +1 -1
- package/dist/resources/guides/access.md +796 -0
- package/dist/resources/guides/bpm.md +686 -0
- package/dist/resources/guides/case.md +153 -0
- package/dist/resources/guides/component.md +10 -2
- package/dist/resources/guides/decision.md +185 -0
- package/dist/resources/guides/expressions.md +14 -5
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/layout.md +55 -58
- package/dist/resources/guides/microservice.md +9 -2
- package/dist/resources/guides/middleware.md +34 -2
- package/dist/resources/guides/mobile-layout.md +193 -0
- package/dist/resources/guides/mobile.md +578 -0
- package/dist/resources/guides/page.md +221 -92
- package/dist/resources/guides/theme.md +8 -2
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +7 -1
- package/dist/resources/read.js +41 -0
- package/dist/resources/schema-fingerprint.json +4 -4
- package/dist/resources/schemas/AccessExplanationDto.json +144 -0
- package/dist/resources/schemas/AccessMatrixDto.json +170 -0
- package/dist/resources/schemas/AccessPermissionDto.json +57 -0
- package/dist/resources/schemas/AccessPolicyDto.json +223 -0
- package/dist/resources/schemas/AccessResourceDto.json +86 -0
- package/dist/resources/schemas/AppSessionDto.json +53 -0
- package/dist/resources/schemas/ConnectDataDescribeDto.json +344 -0
- package/dist/resources/schemas/ConnectDataRequestModel.json +202 -0
- package/dist/resources/schemas/ConnectDataResultDto.json +421 -0
- package/dist/resources/schemas/ConnectorCredentialDto.json +70 -0
- package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +37 -0
- package/dist/resources/schemas/CreateAccessPolicyCommand.json +209 -0
- package/dist/resources/schemas/CreateDecisionCommand.json +221 -0
- package/dist/resources/schemas/CreateProcessDefinitionCommand.json +1337 -0
- package/dist/resources/schemas/DecisionDto.json +302 -0
- package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +28 -0
- package/dist/resources/schemas/ExplainAccessQuery.json +33 -0
- package/dist/resources/schemas/GenerateProcessDocumentCommand.json +116 -0
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +3 -1
- package/dist/resources/schemas/MicroserviceDto.json +2 -2
- package/dist/resources/schemas/OrganizationProjectDto.json +335 -0
- package/dist/resources/schemas/OrganizationSchemaDto.json +196 -0
- package/dist/resources/schemas/OrganizationSchemaVersionDto.json +207 -0
- package/dist/resources/schemas/PatchProcessDefinitionCommand.json +76 -0
- package/dist/resources/schemas/ProcessDefinitionDto.json +1480 -0
- package/dist/resources/schemas/ProcessSimulationDto.json +96 -0
- package/dist/resources/schemas/SaveConnectorCredentialCommand.json +90 -0
- package/dist/resources/schemas/SaveProcessEventSourceCommand.json +61 -0
- package/dist/resources/schemas/SaveProcessMailSourceCommand.json +89 -0
- package/dist/resources/schemas/SignProcessTaskCommand.json +73 -0
- package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +92 -0
- package/dist/resources/schemas/StartMobileBuildCommand.json +54 -0
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
- package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
- package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +259 -0
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
- package/dist/server.js +7 -1
- package/dist/tools/accessOperations.js +135 -0
- package/dist/tools/accessPolicies.js +170 -0
- package/dist/tools/accessRuntime.js +203 -0
- package/dist/tools/applications.js +60 -3
- package/dist/tools/bpm.js +343 -0
- package/dist/tools/bpmGovernance.js +266 -0
- package/dist/tools/bpmOperations.js +230 -0
- package/dist/tools/bpmReporting.js +154 -0
- package/dist/tools/bpmRouting.js +150 -0
- package/dist/tools/bpmRuntime.js +396 -0
- package/dist/tools/case.js +178 -0
- package/dist/tools/caseRuntime.js +89 -0
- package/dist/tools/components.js +103 -12
- package/dist/tools/connectData.js +449 -0
- package/dist/tools/connectors.js +193 -0
- package/dist/tools/datasources.js +1 -1
- package/dist/tools/decisions.js +206 -0
- package/dist/tools/designSchemaPatch.js +22 -16
- package/dist/tools/externalComponents.js +25 -4
- package/dist/tools/flows.js +79 -6
- package/dist/tools/layouts.js +44 -12
- package/dist/tools/microservices.js +32 -10
- package/dist/tools/mobile.js +221 -0
- package/dist/tools/mobileStore.js +268 -0
- package/dist/tools/modules.js +48 -0
- package/dist/tools/organizationStructure.js +137 -0
- package/dist/tools/pages.js +391 -92
- package/dist/tools/platformInfo.js +7 -2
- package/dist/tools/profileWrite.js +92 -0
- package/dist/tools/rows.js +7 -1
- package/dist/tools/schemaOps.js +33 -1
- package/dist/tools/screenWrite.js +15 -7
- package/dist/tools/screens.js +90 -3
- package/dist/tools/variables.js +11 -5
- package/package.json +2 -2
- package/dist/knowledge/boxSections.js +0 -184
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { guid, projectParam, environmentParam, pagingParams, readOnly, writes } from './common.js';
|
|
2
|
+
import { identityHeaders } from '../platform/tokenVault.js';
|
|
3
|
+
import { PlatformApiError } from '../platform/errors.js';
|
|
4
|
+
import { assertProcessNotProduction } from './bpm.js';
|
|
5
|
+
import { handle } from '../platform/responses.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
const asUserParam = z.string().min(1).optional()
|
|
8
|
+
.describe("Uygulama kullanıcısının kimliği (ham JWT ya da access_session_create'in tokenRefs'teki tok_… referansı). Vaka başlatan ve plan öğesini değiştiren bu kişi olur; verilmezse gateway'in kendi kullanıcısı.");
|
|
9
|
+
const expectFailureParam = z.boolean().optional()
|
|
10
|
+
.describe('true: bu çağrıda hata BEKLENİYOR (kasıtlı negatif test: sentry sağlanmadan enable 422). Ölçüm plansız hata saymaz.');
|
|
11
|
+
const planItemOperations = ['enable', 'start', 'complete', 'disable'];
|
|
12
|
+
const caseInstanceOperations = [...planItemOperations, 'add-discretionary', 'update-case-file'];
|
|
13
|
+
export function registerCaseRuntimeTools(server, platform) {
|
|
14
|
+
const config = platform.config;
|
|
15
|
+
server.registerTool('case_execute', {
|
|
16
|
+
title: 'Vaka başlat',
|
|
17
|
+
description: "Yayındaki vaka tanımından vaka başlatır (POST bpm/cases/{slug}/start): subjectRowId iş satırı, caseFile başlangıç değerleri (tanımdaki varsayılanların üstüne yazılır). Yanıt vaka + planItems + availableActions. process.start izni ister. İnsan görevleri görev kutusuna kind 'case-task' olarak düşer ve process_task_update ile tamamlanır. production hedefi durur (BPM-001).",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
project: projectParam,
|
|
20
|
+
environment: environmentParam,
|
|
21
|
+
slug: z.string().min(1).max(100),
|
|
22
|
+
applicationId: guid.optional(),
|
|
23
|
+
subjectRowId: z.string().max(64).optional(),
|
|
24
|
+
caseFile: z.record(z.unknown()).optional().describe('vaka dosyası öğe id → değer'),
|
|
25
|
+
asUser: asUserParam
|
|
26
|
+
},
|
|
27
|
+
annotations: writes
|
|
28
|
+
}, handle(config, async ({ project, environment, slug, applicationId, subjectRowId, caseFile, asUser }) => {
|
|
29
|
+
assertProcessNotProduction('case_execute', environment, config);
|
|
30
|
+
return platform.tenant('POST', project, `/bpm/cases/${encodeURIComponent(slug)}/start`, {
|
|
31
|
+
environment,
|
|
32
|
+
body: { applicationId, subjectRowId, caseFile },
|
|
33
|
+
headers: identityHeaders(asUser, undefined, undefined)
|
|
34
|
+
});
|
|
35
|
+
}));
|
|
36
|
+
server.registerTool('case_instance_list', {
|
|
37
|
+
title: 'Vakaları listele',
|
|
38
|
+
description: "Vakaları listeler (GET bpm/case-instances; process.view-all ister): definitionId ve state (active | completed | terminated) süzgeci. Tek vakanın plan öğeleri, defteri ve availableActions için case_instance_get.",
|
|
39
|
+
inputSchema: {
|
|
40
|
+
project: projectParam,
|
|
41
|
+
environment: environmentParam,
|
|
42
|
+
definitionId: guid.optional(),
|
|
43
|
+
state: z.enum(['active', 'completed', 'terminated']).optional(),
|
|
44
|
+
...pagingParams
|
|
45
|
+
},
|
|
46
|
+
annotations: readOnly
|
|
47
|
+
}, handle(config, ({ project, environment, ...query }) => platform.tenant('GET', project, '/bpm/case-instances', { environment, query })));
|
|
48
|
+
server.registerTool('case_instance_get', {
|
|
49
|
+
title: 'Vakayı getir',
|
|
50
|
+
description: "Vakayı getirir (GET bpm/case-instances/{id}): state, caseFile, planItems[] (id — eylemlerdeki planItemId budur —, itemId, type, state, occurrence, taskId), events[] (vaka defteri) ve availableActions[] { action: start | complete | disable | discretionary, itemId, planItemId }. Katılımcı (başlatan, atanan, tamamlayan) ya da process.view-all görür. case_instance_update'ten önce okuyun: planItemId planItems[].id ya da availableActions[].planItemId'dir.",
|
|
51
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid, asUser: asUserParam },
|
|
52
|
+
annotations: readOnly
|
|
53
|
+
}, handle(config, ({ project, environment, id, asUser }) => platform.tenant('GET', project, `/bpm/case-instances/${id}`, { environment, headers: identityHeaders(asUser, undefined, undefined) })));
|
|
54
|
+
server.registerTool('case_instance_update', {
|
|
55
|
+
title: 'Vakada plan öğesi eylemi',
|
|
56
|
+
description: "Vaka eylemlerinin tek kapısı: operation enable | start | complete | disable (planItemId ZORUNLU: case_instance_get planItems[].id ya da availableActions[].planItemId — enable availableActions'ta hiç yoktur, kimliği planItems[].id'den okuyun; POST …/plan-items/{planItemId}/{operation}) | add-discretionary (itemDefinitionId: isteğe bağlı plan öğesinin tanımdaki id'si; POST …/discretionary) | update-case-file (itemId ve value ZORUNLU, silmek için value: null; PUT …/case-file — yerleşimi yeniden çalıştırır, ifPart'lar yeniden değerlendirilir). Hatalar: giriş sentry'si sağlanmadan enable 422 CaseSentryNotSatisfied (lint değil, çalışma zamanı: availableActions enable listelemez); yanlış durumdaki öğe ya da kapanmış vaka 409 InstanceStateTransitionNotAllowed; human-task görev ucundan (process_task_update) tamamlanır. production hedefi durur (BPM-001).",
|
|
57
|
+
inputSchema: {
|
|
58
|
+
project: projectParam,
|
|
59
|
+
environment: environmentParam,
|
|
60
|
+
id: guid,
|
|
61
|
+
operation: z.enum(caseInstanceOperations),
|
|
62
|
+
planItemId: guid.optional().describe('enable | start | complete | disable için case_instance_get planItems[].id (ya da availableActions[].planItemId)'),
|
|
63
|
+
itemDefinitionId: z.string().max(100).optional().describe('add-discretionary için tanımdaki plan öğesi id'),
|
|
64
|
+
itemId: z.string().max(100).optional().describe('update-case-file için vaka dosyası öğe id'),
|
|
65
|
+
value: z.unknown().optional().describe('update-case-file için yeni değer (herhangi bir JSON)'),
|
|
66
|
+
asUser: asUserParam,
|
|
67
|
+
expectFailure: expectFailureParam
|
|
68
|
+
},
|
|
69
|
+
annotations: writes
|
|
70
|
+
}, handle(config, async ({ project, environment, id, operation, planItemId, itemDefinitionId, itemId, value, asUser }) => {
|
|
71
|
+
assertProcessNotProduction('case_instance_update', environment, config);
|
|
72
|
+
const headers = identityHeaders(asUser, undefined, undefined);
|
|
73
|
+
if (operation === 'add-discretionary') {
|
|
74
|
+
if (!itemDefinitionId)
|
|
75
|
+
throw new PlatformApiError("case_instance_update: 'add-discretionary' itemDefinitionId ister (istek gönderilmedi).", 400);
|
|
76
|
+
return platform.tenant('POST', project, `/bpm/case-instances/${id}/discretionary`, { environment, body: { itemDefinitionId }, headers });
|
|
77
|
+
}
|
|
78
|
+
if (operation === 'update-case-file') {
|
|
79
|
+
if (!itemId)
|
|
80
|
+
throw new PlatformApiError("case_instance_update: 'update-case-file' itemId ister (istek gönderilmedi).", 400);
|
|
81
|
+
if (value === undefined)
|
|
82
|
+
throw new PlatformApiError("case_instance_update: 'update-case-file' value ister — verilmeyen değer öğeyi siler; silmek istiyorsanız value: null gönderin (istek gönderilmedi).", 400);
|
|
83
|
+
return platform.tenant('PUT', project, `/bpm/case-instances/${id}/case-file`, { environment, body: { itemId, value }, headers });
|
|
84
|
+
}
|
|
85
|
+
if (!planItemId)
|
|
86
|
+
throw new PlatformApiError(`case_instance_update: '${operation}' planItemId ister — case_instance_get planItems[].id ya da availableActions[].planItemId (istek gönderilmedi).`, 400);
|
|
87
|
+
return platform.tenant('POST', project, `/bpm/case-instances/${id}/plan-items/${planItemId}/${operation}`, { environment, headers });
|
|
88
|
+
}));
|
|
89
|
+
}
|
package/dist/tools/components.js
CHANGED
|
@@ -1,25 +1,81 @@
|
|
|
1
1
|
import { guid, projectParam, environmentParam, readOnly, writes, updates, destructive } from './common.js';
|
|
2
|
-
import { normalizeComponentDefaults, componentDefaultsNote, clampBlockSizes, blockSizeNote, normalizeHeightTypes, heightTypeNote, normalizeSizeStrings, sizeStringNote, withNormalization } from '../knowledge/normalize.js';
|
|
2
|
+
import { normalizeComponentDefaults, componentDefaultsNote, clampBlockSizes, blockSizeNote, normalizeHeightTypes, heightTypeNote, normalizeSizeStrings, sizeStringNote, normalizeDroppableStates, withNormalization } from '../knowledge/normalize.js';
|
|
3
3
|
import { eventContractsFor, eventPayloadNote } from '../knowledge/componentEvents.js';
|
|
4
4
|
import { componentPresetDefaults, readProjectTheme } from '../knowledge/themeSchema.js';
|
|
5
5
|
import { knowledgeFor, knowledgeNote, APPEARANCE_TOKEN_SETS, STATE_FLAG_NOTES, INTERNAL_ROLES_BY_TYPE } from '../knowledge/componentCatalog.js';
|
|
6
|
+
import { MOBILE_STATE_FLAG_NOTES, mobileComponentKnowledge } from '../knowledge/mobileComponentCatalog.js';
|
|
7
|
+
import { mobileComponentEventContracts } from '../knowledge/mobileComponentEvents.js';
|
|
6
8
|
import { componentUpdateBody, fetchHost, schemaParam, unwrap } from './screens.js';
|
|
7
9
|
import { PlatformApiError } from '../platform/errors.js';
|
|
8
10
|
import { handle } from '../platform/responses.js';
|
|
11
|
+
import { applicationTypeField, resolveProfile } from '../knowledge/platform/resolve.js';
|
|
12
|
+
import { mobileComponentNotes } from '../knowledge/platform/mobileRules.js';
|
|
13
|
+
import { randomUUID } from 'node:crypto';
|
|
9
14
|
import { z } from 'zod';
|
|
10
|
-
const typeParam = z.enum(['web', 'mobile']).optional().describe('Hedef platform;
|
|
15
|
+
const typeParam = z.enum(['web', 'mobile']).optional().describe('Hedef platform (ComponentType); verilmezse uygulamanın tipi — mobil uygulamada mobile');
|
|
11
16
|
const kindParam = z.enum(['component', 'widget']).optional()
|
|
12
17
|
.describe("component: sayfaya konan tekil eleman. widget: kendi şeması olan kapsayıcı (container/modal/drawer)");
|
|
13
18
|
const widgetTypeParam = z.enum(['container', 'modal', 'drawer']).optional()
|
|
14
19
|
.describe("kind:'widget' iken zorunlu");
|
|
20
|
+
/**
|
|
21
|
+
* Uç `type` verilmezse WEB kataloğunu döner (`GetComponentsQuery` `Type ?? Web`); mobil uygulamanın
|
|
22
|
+
* paleti, doğrulayıcısı ve widget'ları `type=mobile` satırlarıdır. Profil mobil derse sorgu tipi
|
|
23
|
+
* taşır; web'de sorgu profil öncesiyle aynıdır (G1 kilidi).
|
|
24
|
+
*/
|
|
15
25
|
async function listComponents(platform, project, environment, applicationId, scope) {
|
|
16
26
|
const path = scope === 'all' ? `/components/${applicationId}/all` : `/components/${applicationId}`;
|
|
27
|
+
const catalogType = scope === 'all' ? 'web' : (await resolveProfile(platform, applicationId)).profile.catalogType;
|
|
17
28
|
const response = await platform.tenant('GET', project, path, {
|
|
18
29
|
environment,
|
|
19
|
-
query: scope === 'all' ? undefined : { pageIndex: 0, pageLength: 999 }
|
|
30
|
+
query: scope === 'all' ? undefined : { pageIndex: 0, pageLength: 999, ...(catalogType === 'mobile' ? { type: 'mobile' } : {}) }
|
|
20
31
|
});
|
|
21
32
|
return response?.data ?? [];
|
|
22
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* CMP-002 (ARC-081) — runtime widget'ın kökünü yalnız `widget-area` (container) ya da `modal`/`drawer`
|
|
36
|
+
* tipinden tanır (`runtime-compose.ts` `getRuntimeWidgetRootNode`); düz `container` kökle kaydedilen
|
|
37
|
+
* widget her yüzeyde boş çizilir. Tipli kök yoksa düğümler Studio'nun `createWidgetRootNode`'u
|
|
38
|
+
* (`widget.functions.ts`) ile aynı şekilde bir köke sarılır: prop'lar uygulamanın kataloğundaki kök
|
|
39
|
+
* tipinin `definition.defaults`'ı, yükseklik `fixed`, kök bırakılabilir.
|
|
40
|
+
*/
|
|
41
|
+
function wrapWidgetRoot(schema, widgetType, components) {
|
|
42
|
+
const rootType = widgetType === 'container' ? 'widget-area' : widgetType;
|
|
43
|
+
// Runtime istenen tipin kökü yoksa öteki tipli köklere de düşer (`legacyRoot()`); tip değiştiren
|
|
44
|
+
// güncellemenin eski kökü ikinci kez sarılmaz.
|
|
45
|
+
const hasRoot = schema.some(node => node?.kind === 'component' && ['widget-area', 'modal', 'drawer'].includes(String(node.type)));
|
|
46
|
+
if (hasRoot)
|
|
47
|
+
return { schema, notes: [] };
|
|
48
|
+
const definition = (components.find(component => component.slug === rootType)?.definition ?? {});
|
|
49
|
+
const desktopBlock = Array.isArray(definition.blocks)
|
|
50
|
+
? definition.blocks.find(block => block?.breakpoint === 1024)
|
|
51
|
+
: undefined;
|
|
52
|
+
const elementId = `${rootType}${randomUUID().slice(0, 4)}`;
|
|
53
|
+
const root = {
|
|
54
|
+
id: randomUUID(),
|
|
55
|
+
elementId,
|
|
56
|
+
name: widgetType === 'container' ? 'container' : elementId,
|
|
57
|
+
widgetType,
|
|
58
|
+
kind: 'component',
|
|
59
|
+
type: rootType,
|
|
60
|
+
children: schema,
|
|
61
|
+
events: [],
|
|
62
|
+
props: { ...(definition.defaults ?? {}) },
|
|
63
|
+
blocks: desktopBlock ? [{ breakpoint: 1024, size: desktopBlock.size, position: { x: 0, y: 0 } }] : [],
|
|
64
|
+
validations: [],
|
|
65
|
+
appearance: { heightType: 'fixed' },
|
|
66
|
+
states: { isDroppable: true },
|
|
67
|
+
stateBindings: []
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
schema: [root],
|
|
71
|
+
notes: [`CMP-002: widget şemasında '${rootType}' kökü yoktu; ${schema.length} düğüm '${elementId}' köküne sarıldı (Studio'nun kurduğu şekil). Runtime widget'ı yalnız widget-area/modal/drawer kökünden çizer.`]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Uygulamanın kayıtlı bileşen slug'ları (mobil profilin MOB-003 denetimi). */
|
|
75
|
+
export async function fetchCatalogSlugs(platform, project, environment, applicationId) {
|
|
76
|
+
const components = await listComponents(platform, project, environment, applicationId);
|
|
77
|
+
return new Set(components.map(component => String(component.slug ?? '')).filter(slug => slug.length > 0));
|
|
78
|
+
}
|
|
23
79
|
/**
|
|
24
80
|
* Yerleşim normalizasyonlarının ikisi de aynı katalog listesinden beslenir; tek okumada
|
|
25
81
|
* çıkarılır ki yazma yolları fazladan istek atmasın. Uygulamanın kendi sözlüğü okunur
|
|
@@ -38,12 +94,17 @@ export async function fetchComponentLayoutRules(platform, project, environment,
|
|
|
38
94
|
export function componentLayoutRules(components) {
|
|
39
95
|
const maxSizes = new Map();
|
|
40
96
|
const autoHeights = new Map();
|
|
97
|
+
const droppable = new Map();
|
|
41
98
|
for (const component of components) {
|
|
42
99
|
const slug = typeof component.slug === 'string' ? component.slug : undefined;
|
|
43
100
|
if (!slug)
|
|
44
101
|
continue;
|
|
45
102
|
if (typeof component.isDefaultAutoHeight === 'boolean')
|
|
46
103
|
autoHeights.set(slug, component.isDefaultAutoHeight);
|
|
104
|
+
// Kap bilgisi sözlükten gelir; düğümün `states.isDroppable`ı onu izler (Studio paleti de
|
|
105
|
+
// aynı alanı katalogdan yazar). `true` gören tip kap sayılır.
|
|
106
|
+
if (typeof component.isDroppable === 'boolean')
|
|
107
|
+
droppable.set(slug, component.isDroppable);
|
|
47
108
|
const blocks = (component.definition ?? {}).blocks;
|
|
48
109
|
if (!Array.isArray(blocks))
|
|
49
110
|
continue;
|
|
@@ -58,7 +119,7 @@ export function componentLayoutRules(components) {
|
|
|
58
119
|
});
|
|
59
120
|
}
|
|
60
121
|
}
|
|
61
|
-
return { maxSizes, autoHeights };
|
|
122
|
+
return { maxSizes, autoHeights, droppable };
|
|
62
123
|
}
|
|
63
124
|
/**
|
|
64
125
|
* Katalog okuması başarısız olsa da yazma isteği gitmeli, ama iki normalizasyonun düşüş davranışı
|
|
@@ -69,14 +130,21 @@ export function componentLayoutRules(components) {
|
|
|
69
130
|
* varsayılanını (`fixed`, `DesignComponentManagementSchema.cs:24`) kabul etmek demektir; en fazla
|
|
70
131
|
* sekiz tipte (auth-layout/html/image/layout/qrcode/table/text-editor/video) fazladan yükseklik
|
|
71
132
|
* üretir, atlamak ise her tipte içerik kırpar.
|
|
133
|
+
* - `states.isDroppable` atlanır — katalog okunamadığında hangi tipin kap olduğu bilinmez ve
|
|
134
|
+
* uydurulmaz; düğüm bugünkü hâliyle yazılır.
|
|
72
135
|
*/
|
|
73
136
|
export async function applyCatalogLayoutRules(platform, project, environment, applicationId, nodes) {
|
|
74
137
|
try {
|
|
75
138
|
const rules = await fetchComponentLayoutRules(platform, project, environment, applicationId);
|
|
76
|
-
return {
|
|
139
|
+
return {
|
|
140
|
+
clamped: clampBlockSizes(nodes, rules.maxSizes),
|
|
141
|
+
heights: normalizeHeightTypes(nodes, rules.autoHeights),
|
|
142
|
+
sizes: normalizeSizeStrings(nodes),
|
|
143
|
+
states: normalizeDroppableStates(nodes, rules.droppable)
|
|
144
|
+
};
|
|
77
145
|
}
|
|
78
146
|
catch {
|
|
79
|
-
return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes) };
|
|
147
|
+
return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes), states: [] };
|
|
80
148
|
}
|
|
81
149
|
}
|
|
82
150
|
/**
|
|
@@ -116,6 +184,7 @@ export function registerComponentTools(server, platform) {
|
|
|
116
184
|
}, handle(config, async ({ project, environment, applicationId, scope, includeHidden }) => {
|
|
117
185
|
const components = await listComponents(platform, project, environment, applicationId, scope);
|
|
118
186
|
return {
|
|
187
|
+
...applicationTypeField(await resolveProfile(platform, applicationId)),
|
|
119
188
|
components: components
|
|
120
189
|
.filter(component => includeHidden === true || component.isHide !== true)
|
|
121
190
|
.map(component => ({
|
|
@@ -161,6 +230,15 @@ export function registerComponentTools(server, platform) {
|
|
|
161
230
|
: [];
|
|
162
231
|
const componentSlug = typeof component.slug === 'string' ? component.slug : undefined;
|
|
163
232
|
const knowledge = knowledgeFor(componentSlug);
|
|
233
|
+
// Mobil uygulamada kayıt mobil kataloğun satırıdır (`listComponents` type=mobile); davranış
|
|
234
|
+
// notları web runtime'ından gelir (`knowledge` — mobil şema web sınıfını genişletir), bileşenin
|
|
235
|
+
// mobil farkları `mobileKnowledge`'ta, bütün mobil bileşenlere geçen notlar `mobileNotes`'ta (G4).
|
|
236
|
+
// Web ikizi olmayan bileşende (`app-bar`, `tooltip`…) bilgi yalnız `mobileKnowledge`'tadır; olay
|
|
237
|
+
// yükleri de önce mobil sözlükten okunur (`mobileComponentEvents.ts`).
|
|
238
|
+
const mobile = (await resolveProfile(platform, applicationId)).profile.platform === 'mobile';
|
|
239
|
+
const mobileKnowledge = mobile && componentSlug !== undefined && Object.hasOwn(mobileComponentKnowledge, componentSlug)
|
|
240
|
+
? mobileComponentKnowledge[componentSlug]
|
|
241
|
+
: undefined;
|
|
164
242
|
// S-3 — `defaults` HAM katalogdur; Studio'da bırakılan düğüm ise temanın bileşen preseti
|
|
165
243
|
// kaplanmış katalogdan kurulur (`withThemeComponentDefaults`). Tema okunamazsa (uç düşer,
|
|
166
244
|
// yetki yoksa) alan yanıta HİÇ girmez: uydurulmuş bir varsayılan yanlış bilgidir.
|
|
@@ -177,7 +255,7 @@ export function registerComponentTools(server, platform) {
|
|
|
177
255
|
isDroppable: component.isDroppable,
|
|
178
256
|
props: definition.props,
|
|
179
257
|
defaults: definition.defaults,
|
|
180
|
-
events: eventContractsFor(componentSlug, eventNames),
|
|
258
|
+
events: eventContractsFor(componentSlug, eventNames, mobile ? mobileComponentEventContracts : undefined),
|
|
181
259
|
eventPayloadNote,
|
|
182
260
|
...(knowledge
|
|
183
261
|
? {
|
|
@@ -188,7 +266,7 @@ export function registerComponentTools(server, platform) {
|
|
|
188
266
|
},
|
|
189
267
|
...(knowledge.guide ? { guide: knowledge.guide } : {})
|
|
190
268
|
}
|
|
191
|
-
: { knowledgeNote }),
|
|
269
|
+
: mobileKnowledge ? {} : { knowledgeNote }),
|
|
192
270
|
...(componentSlug && INTERNAL_ROLES_BY_TYPE[componentSlug]
|
|
193
271
|
? {
|
|
194
272
|
internalRoles: INTERNAL_ROLES_BY_TYPE[componentSlug],
|
|
@@ -196,8 +274,9 @@ export function registerComponentTools(server, platform) {
|
|
|
196
274
|
}
|
|
197
275
|
: {}),
|
|
198
276
|
...(themeDefaults ? { themeDefaults } : {}),
|
|
277
|
+
...(mobile ? { platform: 'mobile', ...(mobileKnowledge ? { mobileKnowledge } : {}), mobileNotes: mobileComponentNotes(componentSlug) } : {}),
|
|
199
278
|
appearanceValues: APPEARANCE_TOKEN_SETS,
|
|
200
|
-
stateFlags: STATE_FLAG_NOTES,
|
|
279
|
+
stateFlags: mobile ? { ...STATE_FLAG_NOTES, ...MOBILE_STATE_FLAG_NOTES } : STATE_FLAG_NOTES,
|
|
201
280
|
validations: definition.validations,
|
|
202
281
|
sizes: definition.blocks
|
|
203
282
|
};
|
|
@@ -230,21 +309,27 @@ export function registerComponentTools(server, platform) {
|
|
|
230
309
|
if (body.kind === 'widget' && !body.widgetType) {
|
|
231
310
|
throw new PlatformApiError("kind:'widget' için widgetType (container | modal | drawer) zorunludur.");
|
|
232
311
|
}
|
|
312
|
+
const wrapped = body.kind === 'widget' && body.widgetType && (body.schema ?? []).length > 0
|
|
313
|
+
? wrapWidgetRoot(body.schema ?? [], body.widgetType, await listComponents(platform, project, environment, applicationId).catch(() => []))
|
|
314
|
+
: { schema: body.schema, notes: [] };
|
|
315
|
+
body.schema = wrapped.schema;
|
|
233
316
|
const fixed = normalizeComponentDefaults(body.schema);
|
|
234
317
|
const catalog = (body.schema ?? []).length > 0
|
|
235
318
|
? await applyCatalogLayoutRules(platform, project, environment, applicationId, body.schema)
|
|
236
319
|
: { clamped: [], heights: [], sizes: [] };
|
|
320
|
+
// Mobil uygulamanın widget'ı mobil katalog satırıdır; tip verilmezse uygulamanın tipi.
|
|
321
|
+
const defaultType = body.type ?? (await resolveProfile(platform, applicationId)).profile.catalogType;
|
|
237
322
|
return platform.tenant('POST', project, `/components/${applicationId}`, {
|
|
238
323
|
environment,
|
|
239
324
|
body: {
|
|
240
325
|
kind: 'component',
|
|
241
|
-
type:
|
|
326
|
+
type: defaultType,
|
|
242
327
|
categories: [],
|
|
243
328
|
definition: {},
|
|
244
329
|
schema: [],
|
|
245
330
|
...Object.fromEntries(Object.entries(body).filter(([, value]) => value !== undefined))
|
|
246
331
|
}
|
|
247
|
-
}).then(response => withNormalization(response, [...componentDefaultsNote(fixed), ...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)]));
|
|
332
|
+
}).then(response => withNormalization(response, [...wrapped.notes, ...componentDefaultsNote(fixed), ...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)]));
|
|
248
333
|
}));
|
|
249
334
|
server.registerTool('component_update', {
|
|
250
335
|
title: 'Komponent güncelle',
|
|
@@ -279,6 +364,12 @@ export function registerComponentTools(server, platform) {
|
|
|
279
364
|
? await fetchHost(platform, 'component', project, environment, applicationId, String(current.id))
|
|
280
365
|
: current;
|
|
281
366
|
const overrides = Object.fromEntries(Object.entries(changes).filter(([, value]) => value !== undefined));
|
|
367
|
+
const widgetType = changes.widgetType ?? detailed.widgetType;
|
|
368
|
+
const wrapped = detailed.kind === 'widget' && typeof widgetType === 'string' && changes.schema !== undefined && changes.schema.length > 0
|
|
369
|
+
? wrapWidgetRoot(changes.schema, widgetType, components)
|
|
370
|
+
: { schema: changes.schema, notes: [] };
|
|
371
|
+
if (overrides.schema !== undefined)
|
|
372
|
+
overrides.schema = wrapped.schema;
|
|
282
373
|
const fixed = normalizeComponentDefaults(overrides.schema);
|
|
283
374
|
const rules = componentLayoutRules(components);
|
|
284
375
|
const clamped = overrides.schema === undefined ? [] : clampBlockSizes(overrides.schema, rules.maxSizes);
|
|
@@ -286,7 +377,7 @@ export function registerComponentTools(server, platform) {
|
|
|
286
377
|
const sizes = overrides.schema === undefined ? [] : normalizeSizeStrings(overrides.schema);
|
|
287
378
|
const body = componentUpdateBody({ ...detailed, applicationId }, overrides);
|
|
288
379
|
await platform.tenant('PUT', project, `/components/${applicationId}/${slug}`, { environment, body });
|
|
289
|
-
return withNormalization({ slug, changed: Object.keys(overrides), preserved: { schemaNodes: body.schema.length } }, [...componentDefaultsNote(fixed), ...blockSizeNote(clamped), ...heightTypeNote(heights), ...sizeStringNote(sizes)]);
|
|
380
|
+
return withNormalization({ slug, changed: Object.keys(overrides), preserved: { schemaNodes: body.schema.length } }, [...wrapped.notes, ...componentDefaultsNote(fixed), ...blockSizeNote(clamped), ...heightTypeNote(heights), ...sizeStringNote(sizes)]);
|
|
290
381
|
}));
|
|
291
382
|
server.registerTool('component_delete', {
|
|
292
383
|
title: 'Komponent sil',
|