@appaflytech/zeyrek-ai-mcp 0.0.28 → 0.0.30
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/README.md +5 -5
- package/dist/config.js +37 -0
- package/dist/index.js +2 -0
- package/dist/knowledge/access.js +802 -0
- package/dist/knowledge/backendConstraints.js +18 -1
- package/dist/knowledge/case.js +41 -0
- package/dist/knowledge/componentCatalog.js +494 -34
- package/dist/knowledge/componentEvents.js +132 -7
- 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 +859 -0
- package/dist/knowledge/mobileComponentEvents.js +239 -0
- package/dist/knowledge/normalize.js +236 -67
- package/dist/knowledge/outlines.js +36 -0
- 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/policy.js +18 -4
- package/dist/knowledge/process.js +510 -0
- package/dist/knowledge/reservedTables.js +79 -0
- package/dist/knowledge/rowFilter.js +43 -0
- package/dist/knowledge/rules.js +319 -21
- package/dist/knowledge/schemaGuard.js +11 -0
- package/dist/knowledge/styleResolve.js +50 -4
- package/dist/knowledge/styleResolveNative.js +527 -0
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +6 -3
- 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} +105 -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/errors.js +162 -10
- package/dist/platform/http.js +29 -8
- package/dist/platform/impersonation.js +45 -0
- package/dist/platform/jsonArray.js +24 -0
- package/dist/platform/responses.js +39 -5
- package/dist/platform/schemaReadMemory.js +60 -0
- package/dist/platform/secrets.js +17 -1
- 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/mobile-app-shell-drawer.json +243 -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 +672 -0
- package/dist/resources/examples/page-detail-profile.json +2 -1
- package/dist/resources/examples/page-dynamic-form.json +3 -2
- 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 +8 -2
- 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 +91 -4
- package/dist/resources/guides/decision.md +185 -0
- package/dist/resources/guides/entity.md +50 -8
- package/dist/resources/guides/expressions.md +14 -5
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/getting-started.md +38 -1
- package/dist/resources/guides/layout.md +11 -7
- package/dist/resources/guides/microservice.md +81 -2
- package/dist/resources/guides/middleware.md +44 -2
- package/dist/resources/guides/mobile-layout.md +193 -0
- package/dist/resources/guides/mobile.md +495 -0
- package/dist/resources/guides/page.md +454 -75
- package/dist/resources/guides/theme.md +8 -2
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +58 -1
- package/dist/resources/read.js +41 -0
- package/dist/resources/rules.js +11 -5
- package/dist/resources/schema-fingerprint.json +7 -5
- 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/CreateEntityCommand.json +118 -0
- package/dist/resources/schemas/CreateMicroserviceCommand.json +13 -1
- package/dist/resources/schemas/CreateProcessDefinitionCommand.json +1337 -0
- package/dist/resources/schemas/CreateQueryCommand.json +4 -0
- package/dist/resources/schemas/CreateWorkflowCommand.json +143 -1
- package/dist/resources/schemas/DataJobDto.json +6 -1
- 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 +21 -1
- package/dist/resources/schemas/MicroserviceDto.json +15 -3
- 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/PreviewMicroserviceCommand.json +10 -1
- package/dist/resources/schemas/PreviewWorkflowCommand.json +22 -1
- 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/StepDto.json +22 -1
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
- package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
- package/dist/resources/schemas/UpdateEntityCommand.json +118 -0
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +13 -1
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
- package/dist/resources/schemas/UpdateQueryCommand.json +4 -0
- package/dist/resources/schemas/UpdateViewCommand.json +0 -2
- package/dist/resources/schemas/UpdateWorkflowCommand.json +143 -1
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
- package/dist/server.js +27 -1
- package/dist/tools/access.js +369 -2
- 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/common.js +7 -0
- package/dist/tools/components.js +118 -14
- package/dist/tools/connectData.js +449 -0
- package/dist/tools/connectors.js +193 -0
- package/dist/tools/datasources.js +3 -3
- package/dist/tools/decisions.js +206 -0
- package/dist/tools/dependencies.js +1 -1
- package/dist/tools/deployments.js +2 -2
- package/dist/tools/designSchemaPatch.js +34 -9
- package/dist/tools/dtos.js +36 -5
- package/dist/tools/entities.js +79 -12
- package/dist/tools/externalComponents.js +26 -5
- package/dist/tools/flows.js +122 -14
- package/dist/tools/folders.js +1 -1
- package/dist/tools/imports.js +5 -2
- package/dist/tools/layouts.js +50 -17
- package/dist/tools/merges.js +1 -1
- package/dist/tools/microservices.js +77 -25
- package/dist/tools/mobile.js +221 -0
- package/dist/tools/modules.js +48 -0
- package/dist/tools/organizationStructure.js +137 -0
- package/dist/tools/pages.js +465 -98
- package/dist/tools/platformInfo.js +27 -8
- package/dist/tools/profileWrite.js +92 -0
- package/dist/tools/projects.js +71 -9
- package/dist/tools/rows.js +69 -13
- package/dist/tools/schemaOps.js +61 -1
- package/dist/tools/screenWrite.js +37 -8
- package/dist/tools/screens.js +95 -5
- package/dist/tools/templates.js +26 -1
- package/dist/tools/translations.js +1 -1
- package/dist/tools/variables.js +11 -5
- package/dist/tools/workflows.js +10 -5
- package/package.json +2 -2
|
@@ -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/common.js
CHANGED
|
@@ -28,6 +28,13 @@ export const environmentParam = z.string().min(1).optional()
|
|
|
28
28
|
.describe('Environment adı (X-Environment); boşsa DEFAULT_ENVIRONMENT kullanılır');
|
|
29
29
|
export const languageParam = z.string().min(1).optional()
|
|
30
30
|
.describe("İstek dili (ISO 639-1, ör. 'en'); X-Data-Language olarak gider. Çok dilli alanlar bu dilde okunur/yazılır, workflow'da context.language ve ham sorguda {{language}} bu değeri alır. Verilmezse platform Accept-Language'a, o da yoksa projenin varsayılan diline düşer. Bölgeli değer ('tr-TR') kabul edilir ve gateway indirger.");
|
|
31
|
+
/**
|
|
32
|
+
* 38/M-1: kompleks + enforce projede runtime araçları uygulama oturumu istiyordu ve oturum yalnız
|
|
33
|
+
* parolayla açılıyordu. Platform production dışında gateway'in kimliği doğrulanmış isteğine bu başlıkla
|
|
34
|
+
* özne kurar (`AppSessionMiddleware`); denetimler `platform/impersonation.ts`'tedir.
|
|
35
|
+
*/
|
|
36
|
+
export const asUserIdParam = z.string().uuid().optional()
|
|
37
|
+
.describe("Parolasız kullanıcı gözü: users satır id'si (user_list). İstek gateway kimliğiyle ve 'impersonated-user-id' başlığıyla gider; platform özneyi bu kullanıcı olarak kurar — kompleks projede politika, satır kapsamı ve alan maskesi o kullanıcınındır, parola ve oturum gerekmez. Yalnız development ya da dal: production'da platform başlığı düşürür, runtime araçları isteği göndermeden reddeder. asUser ve anonymous ile birlikte verilemez; projede olmayan id reddedilir (platform onu sessizce yok sayıp gateway kimliğiyle yürütürdü).");
|
|
31
38
|
export const definitionParam = z.record(z.unknown())
|
|
32
39
|
.describe('API komut gövdesi birebir geçirilir; şablon için ilgili *_get çıktısını ya da ngapps://schemas kaynağını kullanın');
|
|
33
40
|
/**
|
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");
|
|
15
|
-
|
|
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
|
+
*/
|
|
25
|
+
export 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
|
|
@@ -34,16 +90,33 @@ async function listComponents(platform, project, environment, applicationId, sco
|
|
|
34
90
|
export async function fetchComponentLayoutRules(platform, project, environment, applicationId) {
|
|
35
91
|
return componentLayoutRules(await listComponents(platform, project, environment, applicationId));
|
|
36
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Uygulamanın komponent sözlüğü, TEK okumada. Katalog gövdesi büyüktür (101 kayıt ≈ yüzlerce KB):
|
|
95
|
+
* hem TB-123 doğrulaması hem yerleşim normalizasyonu aynı listeden beslenir, iki istek atılmaz.
|
|
96
|
+
*/
|
|
97
|
+
export async function fetchCatalogComponents(platform, project, environment, applicationId) {
|
|
98
|
+
return listComponents(platform, project, environment, applicationId);
|
|
99
|
+
}
|
|
100
|
+
/** Katalog listesi elde varken yerleşim kurallarını uygular (ikinci okuma yapmaz). */
|
|
101
|
+
export function applyCatalogLayoutRulesFrom(components, nodes) {
|
|
102
|
+
const rules = componentLayoutRules(components);
|
|
103
|
+
return { clamped: clampBlockSizes(nodes, rules.maxSizes), heights: normalizeHeightTypes(nodes, rules.autoHeights), sizes: normalizeSizeStrings(nodes), states: normalizeDroppableStates(nodes, rules.droppable) };
|
|
104
|
+
}
|
|
37
105
|
/** Katalog listesini zaten okumuş çağıranlar (component_update) ikinci istek atmasın diye ayrı. */
|
|
38
106
|
export function componentLayoutRules(components) {
|
|
39
107
|
const maxSizes = new Map();
|
|
40
108
|
const autoHeights = new Map();
|
|
109
|
+
const droppable = new Map();
|
|
41
110
|
for (const component of components) {
|
|
42
111
|
const slug = typeof component.slug === 'string' ? component.slug : undefined;
|
|
43
112
|
if (!slug)
|
|
44
113
|
continue;
|
|
45
114
|
if (typeof component.isDefaultAutoHeight === 'boolean')
|
|
46
115
|
autoHeights.set(slug, component.isDefaultAutoHeight);
|
|
116
|
+
// Kap bilgisi sözlükten gelir; düğümün `states.isDroppable`ı onu izler (Studio paleti de
|
|
117
|
+
// aynı alanı katalogdan yazar). `true` gören tip kap sayılır.
|
|
118
|
+
if (typeof component.isDroppable === 'boolean')
|
|
119
|
+
droppable.set(slug, component.isDroppable);
|
|
47
120
|
const blocks = (component.definition ?? {}).blocks;
|
|
48
121
|
if (!Array.isArray(blocks))
|
|
49
122
|
continue;
|
|
@@ -58,7 +131,7 @@ export function componentLayoutRules(components) {
|
|
|
58
131
|
});
|
|
59
132
|
}
|
|
60
133
|
}
|
|
61
|
-
return { maxSizes, autoHeights };
|
|
134
|
+
return { maxSizes, autoHeights, droppable };
|
|
62
135
|
}
|
|
63
136
|
/**
|
|
64
137
|
* Katalog okuması başarısız olsa da yazma isteği gitmeli, ama iki normalizasyonun düşüş davranışı
|
|
@@ -69,14 +142,21 @@ export function componentLayoutRules(components) {
|
|
|
69
142
|
* varsayılanını (`fixed`, `DesignComponentManagementSchema.cs:24`) kabul etmek demektir; en fazla
|
|
70
143
|
* sekiz tipte (auth-layout/html/image/layout/qrcode/table/text-editor/video) fazladan yükseklik
|
|
71
144
|
* üretir, atlamak ise her tipte içerik kırpar.
|
|
145
|
+
* - `states.isDroppable` atlanır — katalog okunamadığında hangi tipin kap olduğu bilinmez ve
|
|
146
|
+
* uydurulmaz; düğüm bugünkü hâliyle yazılır.
|
|
72
147
|
*/
|
|
73
148
|
export async function applyCatalogLayoutRules(platform, project, environment, applicationId, nodes) {
|
|
74
149
|
try {
|
|
75
150
|
const rules = await fetchComponentLayoutRules(platform, project, environment, applicationId);
|
|
76
|
-
return {
|
|
151
|
+
return {
|
|
152
|
+
clamped: clampBlockSizes(nodes, rules.maxSizes),
|
|
153
|
+
heights: normalizeHeightTypes(nodes, rules.autoHeights),
|
|
154
|
+
sizes: normalizeSizeStrings(nodes),
|
|
155
|
+
states: normalizeDroppableStates(nodes, rules.droppable)
|
|
156
|
+
};
|
|
77
157
|
}
|
|
78
158
|
catch {
|
|
79
|
-
return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes) };
|
|
159
|
+
return { clamped: [], heights: normalizeHeightTypes(nodes, new Map()), sizes: normalizeSizeStrings(nodes), states: [] };
|
|
80
160
|
}
|
|
81
161
|
}
|
|
82
162
|
/**
|
|
@@ -116,6 +196,7 @@ export function registerComponentTools(server, platform) {
|
|
|
116
196
|
}, handle(config, async ({ project, environment, applicationId, scope, includeHidden }) => {
|
|
117
197
|
const components = await listComponents(platform, project, environment, applicationId, scope);
|
|
118
198
|
return {
|
|
199
|
+
...applicationTypeField(await resolveProfile(platform, applicationId)),
|
|
119
200
|
components: components
|
|
120
201
|
.filter(component => includeHidden === true || component.isHide !== true)
|
|
121
202
|
.map(component => ({
|
|
@@ -161,6 +242,15 @@ export function registerComponentTools(server, platform) {
|
|
|
161
242
|
: [];
|
|
162
243
|
const componentSlug = typeof component.slug === 'string' ? component.slug : undefined;
|
|
163
244
|
const knowledge = knowledgeFor(componentSlug);
|
|
245
|
+
// Mobil uygulamada kayıt mobil kataloğun satırıdır (`listComponents` type=mobile); davranış
|
|
246
|
+
// notları web runtime'ından gelir (`knowledge` — mobil şema web sınıfını genişletir), bileşenin
|
|
247
|
+
// mobil farkları `mobileKnowledge`'ta, bütün mobil bileşenlere geçen notlar `mobileNotes`'ta (G4).
|
|
248
|
+
// Web ikizi olmayan bileşende (`app-bar`, `tooltip`…) bilgi yalnız `mobileKnowledge`'tadır; olay
|
|
249
|
+
// yükleri de önce mobil sözlükten okunur (`mobileComponentEvents.ts`).
|
|
250
|
+
const mobile = (await resolveProfile(platform, applicationId)).profile.platform === 'mobile';
|
|
251
|
+
const mobileKnowledge = mobile && componentSlug !== undefined && Object.hasOwn(mobileComponentKnowledge, componentSlug)
|
|
252
|
+
? mobileComponentKnowledge[componentSlug]
|
|
253
|
+
: undefined;
|
|
164
254
|
// S-3 — `defaults` HAM katalogdur; Studio'da bırakılan düğüm ise temanın bileşen preseti
|
|
165
255
|
// kaplanmış katalogdan kurulur (`withThemeComponentDefaults`). Tema okunamazsa (uç düşer,
|
|
166
256
|
// yetki yoksa) alan yanıta HİÇ girmez: uydurulmuş bir varsayılan yanlış bilgidir.
|
|
@@ -177,7 +267,7 @@ export function registerComponentTools(server, platform) {
|
|
|
177
267
|
isDroppable: component.isDroppable,
|
|
178
268
|
props: definition.props,
|
|
179
269
|
defaults: definition.defaults,
|
|
180
|
-
events: eventContractsFor(componentSlug, eventNames),
|
|
270
|
+
events: eventContractsFor(componentSlug, eventNames, mobile ? mobileComponentEventContracts : undefined),
|
|
181
271
|
eventPayloadNote,
|
|
182
272
|
...(knowledge
|
|
183
273
|
? {
|
|
@@ -188,7 +278,7 @@ export function registerComponentTools(server, platform) {
|
|
|
188
278
|
},
|
|
189
279
|
...(knowledge.guide ? { guide: knowledge.guide } : {})
|
|
190
280
|
}
|
|
191
|
-
: { knowledgeNote }),
|
|
281
|
+
: mobileKnowledge ? {} : { knowledgeNote }),
|
|
192
282
|
...(componentSlug && INTERNAL_ROLES_BY_TYPE[componentSlug]
|
|
193
283
|
? {
|
|
194
284
|
internalRoles: INTERNAL_ROLES_BY_TYPE[componentSlug],
|
|
@@ -196,10 +286,12 @@ export function registerComponentTools(server, platform) {
|
|
|
196
286
|
}
|
|
197
287
|
: {}),
|
|
198
288
|
...(themeDefaults ? { themeDefaults } : {}),
|
|
289
|
+
...(mobile ? { platform: 'mobile', ...(mobileKnowledge ? { mobileKnowledge } : {}), mobileNotes: mobileComponentNotes(componentSlug) } : {}),
|
|
199
290
|
appearanceValues: APPEARANCE_TOKEN_SETS,
|
|
200
|
-
stateFlags: STATE_FLAG_NOTES,
|
|
291
|
+
stateFlags: mobile ? { ...STATE_FLAG_NOTES, ...MOBILE_STATE_FLAG_NOTES } : STATE_FLAG_NOTES,
|
|
201
292
|
validations: definition.validations,
|
|
202
|
-
sizes: definition.blocks
|
|
293
|
+
sizes: definition.blocks,
|
|
294
|
+
...(definition.connectData ? { connectData: definition.connectData } : { connectDataNote: "Bu komponentin veri kaynağına bağlanabilir prop kaydı yok (ya da katalog henüz eşitlenmedi): connect_data_bind bu tipte CD-001 döner." })
|
|
203
295
|
};
|
|
204
296
|
}));
|
|
205
297
|
server.registerTool('component_create', {
|
|
@@ -230,21 +322,27 @@ export function registerComponentTools(server, platform) {
|
|
|
230
322
|
if (body.kind === 'widget' && !body.widgetType) {
|
|
231
323
|
throw new PlatformApiError("kind:'widget' için widgetType (container | modal | drawer) zorunludur.");
|
|
232
324
|
}
|
|
325
|
+
const wrapped = body.kind === 'widget' && body.widgetType && (body.schema ?? []).length > 0
|
|
326
|
+
? wrapWidgetRoot(body.schema ?? [], body.widgetType, await listComponents(platform, project, environment, applicationId).catch(() => []))
|
|
327
|
+
: { schema: body.schema, notes: [] };
|
|
328
|
+
body.schema = wrapped.schema;
|
|
233
329
|
const fixed = normalizeComponentDefaults(body.schema);
|
|
234
330
|
const catalog = (body.schema ?? []).length > 0
|
|
235
331
|
? await applyCatalogLayoutRules(platform, project, environment, applicationId, body.schema)
|
|
236
332
|
: { clamped: [], heights: [], sizes: [] };
|
|
333
|
+
// Mobil uygulamanın widget'ı mobil katalog satırıdır; tip verilmezse uygulamanın tipi.
|
|
334
|
+
const defaultType = body.type ?? (await resolveProfile(platform, applicationId)).profile.catalogType;
|
|
237
335
|
return platform.tenant('POST', project, `/components/${applicationId}`, {
|
|
238
336
|
environment,
|
|
239
337
|
body: {
|
|
240
338
|
kind: 'component',
|
|
241
|
-
type:
|
|
339
|
+
type: defaultType,
|
|
242
340
|
categories: [],
|
|
243
341
|
definition: {},
|
|
244
342
|
schema: [],
|
|
245
343
|
...Object.fromEntries(Object.entries(body).filter(([, value]) => value !== undefined))
|
|
246
344
|
}
|
|
247
|
-
}).then(response => withNormalization(response, [...componentDefaultsNote(fixed), ...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)]));
|
|
345
|
+
}).then(response => withNormalization(response, [...wrapped.notes, ...componentDefaultsNote(fixed), ...blockSizeNote(catalog.clamped), ...heightTypeNote(catalog.heights), ...sizeStringNote(catalog.sizes)]));
|
|
248
346
|
}));
|
|
249
347
|
server.registerTool('component_update', {
|
|
250
348
|
title: 'Komponent güncelle',
|
|
@@ -279,6 +377,12 @@ export function registerComponentTools(server, platform) {
|
|
|
279
377
|
? await fetchHost(platform, 'component', project, environment, applicationId, String(current.id))
|
|
280
378
|
: current;
|
|
281
379
|
const overrides = Object.fromEntries(Object.entries(changes).filter(([, value]) => value !== undefined));
|
|
380
|
+
const widgetType = changes.widgetType ?? detailed.widgetType;
|
|
381
|
+
const wrapped = detailed.kind === 'widget' && typeof widgetType === 'string' && changes.schema !== undefined && changes.schema.length > 0
|
|
382
|
+
? wrapWidgetRoot(changes.schema, widgetType, components)
|
|
383
|
+
: { schema: changes.schema, notes: [] };
|
|
384
|
+
if (overrides.schema !== undefined)
|
|
385
|
+
overrides.schema = wrapped.schema;
|
|
282
386
|
const fixed = normalizeComponentDefaults(overrides.schema);
|
|
283
387
|
const rules = componentLayoutRules(components);
|
|
284
388
|
const clamped = overrides.schema === undefined ? [] : clampBlockSizes(overrides.schema, rules.maxSizes);
|
|
@@ -286,7 +390,7 @@ export function registerComponentTools(server, platform) {
|
|
|
286
390
|
const sizes = overrides.schema === undefined ? [] : normalizeSizeStrings(overrides.schema);
|
|
287
391
|
const body = componentUpdateBody({ ...detailed, applicationId }, overrides);
|
|
288
392
|
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)]);
|
|
393
|
+
return withNormalization({ slug, changed: Object.keys(overrides), preserved: { schemaNodes: body.schema.length } }, [...wrapped.notes, ...componentDefaultsNote(fixed), ...blockSizeNote(clamped), ...heightTypeNote(heights), ...sizeStringNote(sizes)]);
|
|
290
394
|
}));
|
|
291
395
|
server.registerTool('component_delete', {
|
|
292
396
|
title: 'Komponent sil',
|