@appaflytech/zeyrek-ai-mcp 0.0.1

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.
Files changed (88) hide show
  1. package/.env.example +46 -0
  2. package/README.md +260 -0
  3. package/dist/config.js +128 -0
  4. package/dist/index.js +88 -0
  5. package/dist/knowledge/componentCatalog.js +438 -0
  6. package/dist/knowledge/componentEvents.js +164 -0
  7. package/dist/knowledge/coverage.js +60 -0
  8. package/dist/knowledge/normalize.js +1309 -0
  9. package/dist/knowledge/outlines.js +167 -0
  10. package/dist/knowledge/policy.js +44 -0
  11. package/dist/knowledge/reservedTables.js +75 -0
  12. package/dist/knowledge/rules.js +1725 -0
  13. package/dist/observability/trace.js +337 -0
  14. package/dist/platform/errors.js +132 -0
  15. package/dist/platform/http.js +169 -0
  16. package/dist/platform/responses.js +94 -0
  17. package/dist/platform/token.js +79 -0
  18. package/dist/resources/examples/entity-pair-m2m.json +105 -0
  19. package/dist/resources/examples/flow-list-to-form.json +65 -0
  20. package/dist/resources/examples/flow-load-table.json +178 -0
  21. package/dist/resources/examples/microservice-table-list.json +49 -0
  22. package/dist/resources/examples/middleware-authenticate.json +194 -0
  23. package/dist/resources/examples/page-detail-profile.json +95 -0
  24. package/dist/resources/examples/page-dynamic-form.json +221 -0
  25. package/dist/resources/examples/page-form-upsert.json +279 -0
  26. package/dist/resources/examples/page-html-embed.json +106 -0
  27. package/dist/resources/examples/page-sign-in.json +194 -0
  28. package/dist/resources/examples/workflow-basic.json +94 -0
  29. package/dist/resources/guides/component.md +108 -0
  30. package/dist/resources/guides/entity.md +348 -0
  31. package/dist/resources/guides/expressions.md +139 -0
  32. package/dist/resources/guides/getting-started.md +109 -0
  33. package/dist/resources/guides/html.md +106 -0
  34. package/dist/resources/guides/microservice.md +313 -0
  35. package/dist/resources/guides/middleware.md +271 -0
  36. package/dist/resources/guides/modify-existing.md +35 -0
  37. package/dist/resources/guides/page.md +1574 -0
  38. package/dist/resources/guides/view.md +89 -0
  39. package/dist/resources/guides/workflow.md +359 -0
  40. package/dist/resources/knowledge.js +44 -0
  41. package/dist/resources/schemas/CreateDatasourceCommand.json +54 -0
  42. package/dist/resources/schemas/CreateDiscoveredEntitiesCommand.json +133 -0
  43. package/dist/resources/schemas/CreateEntityCommand.json +387 -0
  44. package/dist/resources/schemas/CreateMicroserviceCommand.json +528 -0
  45. package/dist/resources/schemas/CreateQueryCommand.json +43 -0
  46. package/dist/resources/schemas/CreateViewCommand.json +158 -0
  47. package/dist/resources/schemas/CreateWorkflowCommand.json +1719 -0
  48. package/dist/resources/schemas/Filter.json +124 -0
  49. package/dist/resources/schemas/GetRowsQuery.json +122 -0
  50. package/dist/resources/schemas/PreviewMicroserviceCommand.json +565 -0
  51. package/dist/resources/schemas/PreviewQueryCommand.json +74 -0
  52. package/dist/resources/schemas/PreviewWorkflowCommand.json +981 -0
  53. package/dist/resources/schemas/StepDto.json +900 -0
  54. package/dist/resources/schemas/UpdateDatasourceCommand.json +58 -0
  55. package/dist/resources/schemas/UpdateEntityCommand.json +679 -0
  56. package/dist/resources/schemas/UpdateMicroserviceCommand.json +512 -0
  57. package/dist/resources/schemas/UpdateQueryCommand.json +86 -0
  58. package/dist/resources/schemas/UpdateViewCommand.json +153 -0
  59. package/dist/resources/schemas/UpdateWorkflowCommand.json +1719 -0
  60. package/dist/resources/schemas.js +40 -0
  61. package/dist/server.js +63 -0
  62. package/dist/tools/access.js +27 -0
  63. package/dist/tools/applications.js +59 -0
  64. package/dist/tools/automations.js +103 -0
  65. package/dist/tools/common.js +18 -0
  66. package/dist/tools/components.js +280 -0
  67. package/dist/tools/datasources.js +82 -0
  68. package/dist/tools/dependencies.js +17 -0
  69. package/dist/tools/deployments.js +17 -0
  70. package/dist/tools/dtos.js +54 -0
  71. package/dist/tools/entities.js +166 -0
  72. package/dist/tools/files.js +138 -0
  73. package/dist/tools/flows.js +226 -0
  74. package/dist/tools/folders.js +51 -0
  75. package/dist/tools/layouts.js +105 -0
  76. package/dist/tools/microservices.js +198 -0
  77. package/dist/tools/organizations.js +65 -0
  78. package/dist/tools/pages.js +597 -0
  79. package/dist/tools/platformInfo.js +44 -0
  80. package/dist/tools/projects.js +152 -0
  81. package/dist/tools/queries.js +48 -0
  82. package/dist/tools/rows.js +115 -0
  83. package/dist/tools/screens.js +97 -0
  84. package/dist/tools/templates.js +65 -0
  85. package/dist/tools/variables.js +94 -0
  86. package/dist/tools/views.js +58 -0
  87. package/dist/tools/workflows.js +196 -0
  88. package/package.json +49 -0
@@ -0,0 +1,152 @@
1
+ import { guid, projectParam, environmentParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
+ import { projectCoverageGaps } from '../knowledge/coverage.js';
3
+ import { handle } from '../platform/responses.js';
4
+ import { z } from 'zod';
5
+ function pick(entry, keys) {
6
+ if (!entry || typeof entry !== 'object')
7
+ return {};
8
+ return Object.fromEntries(keys
9
+ .map(key => [key, entry[key]])
10
+ .filter(([, value]) => value !== undefined && value !== null));
11
+ }
12
+ function rows(payload) {
13
+ const data = payload?.data;
14
+ return Array.isArray(data) ? data : [];
15
+ }
16
+ const applicationInput = z.object({
17
+ slug: z.string().min(1),
18
+ name: z.string().min(1),
19
+ color: z.string().optional(),
20
+ dns: z.string().optional(),
21
+ type: z.string().optional().describe('ApplicationType; varsayılan Web')
22
+ });
23
+ const templateOptionsInput = z.object({
24
+ templateId: guid,
25
+ templateReceiveUpdates: z.boolean().optional()
26
+ });
27
+ export function registerProjectTools(server, platform) {
28
+ const config = platform.config;
29
+ server.registerTool('project_list', {
30
+ title: 'Projeleri listele',
31
+ description: 'Organizasyondaki projeleri arar ve sayfalı listeler.',
32
+ inputSchema: { searchTerm: z.string().optional(), ...pagingParams },
33
+ annotations: readOnly
34
+ }, handle(config, args => platform.org('GET', '/projects', { query: args })));
35
+ server.registerTool('project_get', {
36
+ title: 'Proje getir',
37
+ description: 'Tek projeyi id ya da slug ile getirir; environment listesi de yanıttadır.',
38
+ inputSchema: { id: guid.optional(), slug: z.string().optional().describe('id verilmediyse zorunlu') },
39
+ annotations: readOnly
40
+ }, handle(config, args => {
41
+ if (args.id)
42
+ return platform.org('GET', `/projects/${args.id}`);
43
+ if (args.slug)
44
+ return platform.org('GET', `/p/${args.slug}`);
45
+ throw new Error("'id' ya da 'slug' parametrelerinden biri zorunlu.");
46
+ }));
47
+ server.registerTool('project_create', {
48
+ title: 'Proje oluştur',
49
+ description: "Yeni proje oluşturur. templateOptions verilmezse 'application' zorunludur (ilk application projeyle birlikte açılır). LoaderImage bu tool'da desteklenmez.",
50
+ inputSchema: {
51
+ name: z.string().min(1),
52
+ slug: z.string().min(1),
53
+ theme: z.string().optional().describe('Tema JSON\'u string olarak'),
54
+ application: applicationInput.optional(),
55
+ templateOptions: templateOptionsInput.optional().describe('Verilirse proje template\'ten kurulur (asenkron); sonucu project_list ile izleyin')
56
+ },
57
+ annotations: writes
58
+ }, handle(config, args => {
59
+ const form = new URLSearchParams({ Name: args.name, Slug: args.slug });
60
+ if (args.theme)
61
+ form.set('Theme', args.theme);
62
+ if (args.application) {
63
+ form.set('Application.Slug', args.application.slug);
64
+ form.set('Application.Name', args.application.name);
65
+ if (args.application.color)
66
+ form.set('Application.Color', args.application.color);
67
+ if (args.application.dns)
68
+ form.set('Application.Dns', args.application.dns);
69
+ if (args.application.type)
70
+ form.set('Application.Type', args.application.type);
71
+ }
72
+ if (args.templateOptions) {
73
+ form.set('TemplateOptions.TemplateId', args.templateOptions.templateId);
74
+ if (args.templateOptions.templateReceiveUpdates !== undefined) {
75
+ form.set('TemplateOptions.TemplateReceiveUpdates', String(args.templateOptions.templateReceiveUpdates));
76
+ }
77
+ }
78
+ return platform.org('POST', '/projects', { form });
79
+ }));
80
+ server.registerTool('project_update', {
81
+ title: 'Proje güncelle',
82
+ description: 'Proje adını, slug\'ını ve temasını günceller. LoaderImage bu tool\'da desteklenmez.',
83
+ inputSchema: {
84
+ id: guid,
85
+ name: z.string().min(1),
86
+ slug: z.string().optional(),
87
+ theme: z.string().optional()
88
+ },
89
+ annotations: updates
90
+ }, handle(config, args => {
91
+ const form = new URLSearchParams({ Name: args.name });
92
+ if (args.slug)
93
+ form.set('Slug', args.slug);
94
+ if (args.theme)
95
+ form.set('Theme', args.theme);
96
+ return platform.org('PUT', `/projects/${args.id}`, { form });
97
+ }));
98
+ server.registerTool('project_delete', {
99
+ title: 'Proje sil',
100
+ description: 'Projeyi tüm environment\'larıyla birlikte kalıcı olarak siler.',
101
+ inputSchema: { id: guid },
102
+ annotations: destructive
103
+ }, handle(config, args => platform.org('DELETE', `/projects/${args.id}`)));
104
+ server.registerTool('project_overview', {
105
+ title: 'Proje haritası',
106
+ description: 'Projenin kompakt envanteri: application\'lar, datasource+entity ağacı, microservice/workflow/query/SAYFA listeleri (yalnız id/ad/tip) + tutarlılık boşlukları (coverageGaps: kimlik var ama giriş sayfası yok, yazma ucu var ama sayfa yok). Var olan bir projede çalışmaya HER ZAMAN buradan başlayın; detay için ilgili *_get tool\'unu kullanın.',
107
+ inputSchema: { project: projectParam, environment: environmentParam },
108
+ annotations: readOnly
109
+ }, handle(config, async ({ project, environment }) => {
110
+ const projectSlug = platform.resolveProject(project);
111
+ const projectPayload = await platform.org('GET', `/p/${projectSlug}`);
112
+ const projectData = (projectPayload?.data ?? {});
113
+ const applicationsPayload = projectData.id
114
+ ? await platform.org('GET', '/applications', { query: { projectId: projectData.id, pageLength: 100 } })
115
+ : { data: [] };
116
+ const datasourceTreePayload = await platform.tenant('GET', projectSlug, '/datasources/tree', { environment });
117
+ const queriesPayload = await platform.tenant('GET', projectSlug, '/queries', { environment, query: { pageLength: 200 } });
118
+ const applications = [];
119
+ for (const applicationEntry of rows(applicationsPayload)) {
120
+ const applicationId = applicationEntry.id;
121
+ const [microservicesPayload, workflowsPayload, pagesPayload] = await Promise.all([
122
+ platform.tenant('GET', projectSlug, `/microservices/${applicationId}`, { environment, query: { pageLength: 200 } }).catch(() => undefined),
123
+ platform.tenant('GET', projectSlug, `/workflows/${applicationId}`, { environment, query: { pageLength: 200 } }).catch(() => undefined),
124
+ platform.tenant('GET', projectSlug, `/pages/${applicationId}`, { environment, query: { pageIndex: 0, pageLength: 200 } }).catch(() => undefined)
125
+ ]);
126
+ const microservices = rows(microservicesPayload).map(entry => pick(entry, ['id', 'slug', 'name', 'type', 'httpMethod', 'source', 'entityId', 'workflowId']));
127
+ const workflows = rows(workflowsPayload).map(entry => pick(entry, ['id', 'slug', 'name', 'type', 'entityId']));
128
+ const pages = rows(pagesPayload).map(entry => pick(entry, ['id', 'slug', 'name']));
129
+ const gaps = projectCoverageGaps({ pages, microservices, workflows });
130
+ applications.push({
131
+ ...pick(applicationEntry, ['id', 'slug', 'name', 'type']),
132
+ microservices,
133
+ workflows,
134
+ pages,
135
+ ...(gaps.length > 0 ? { coverageGaps: gaps } : {})
136
+ });
137
+ }
138
+ return {
139
+ project: pick(projectData, ['id', 'slug', 'name']),
140
+ environments: (Array.isArray(projectData.environments) ? projectData.environments : []).map(entry => pick(entry, ['id', 'name'])),
141
+ environment: platform.resolveEnvironment(environment),
142
+ applications,
143
+ datasources: rows(datasourceTreePayload).map(datasourceEntry => ({
144
+ ...pick(datasourceEntry, ['id', 'name', 'type']),
145
+ entities: (Array.isArray(datasourceEntry.entities) ? datasourceEntry.entities : [])
146
+ .map(entry => pick(entry, ['id', 'slug', 'name']))
147
+ })),
148
+ queries: rows(queriesPayload).map(entry => pick(entry, ['id', 'name', 'datasourceId'])),
149
+ hint: 'Detay: entity_get/microservice_get/workflow_get (büyük kayıtlarda view:\'outline\'); değişiklik: *_patch.'
150
+ };
151
+ }));
152
+ }
@@ -0,0 +1,48 @@
1
+ import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
+ import { handle } from '../platform/responses.js';
3
+ import { z } from 'zod';
4
+ export function registerQueryTools(server, platform) {
5
+ const config = platform.config;
6
+ server.registerTool('query_list', {
7
+ title: 'Query listele',
8
+ description: 'Projedeki query tanımlarını listeler.',
9
+ inputSchema: { project: projectParam, environment: environmentParam, searchTerm: z.string().optional(), ...pagingParams },
10
+ annotations: readOnly
11
+ }, handle(config, ({ project, environment, ...query }) => platform.tenant('GET', project, '/queries', { environment, query })));
12
+ server.registerTool('query_get', {
13
+ title: 'Query getir',
14
+ description: 'Tek query tanımını getirir; query_create için en iyi gövde şablonudur.',
15
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid },
16
+ annotations: readOnly
17
+ }, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/queries/${id}`, { environment })));
18
+ server.registerTool('query_create', {
19
+ title: 'Query oluştur',
20
+ description: 'Yeni query tanımlar. definition = CreateQueryCommand gövdesi.',
21
+ inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam },
22
+ annotations: writes
23
+ }, handle(config, ({ project, environment, definition }) => platform.tenant('POST', project, '/queries', { environment, body: definition })));
24
+ server.registerTool('query_update', {
25
+ title: 'Query güncelle',
26
+ description: 'Query tanımını günceller. definition = UpdateQueryCommand gövdesi.',
27
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid, definition: definitionParam },
28
+ annotations: updates
29
+ }, handle(config, ({ project, environment, id, definition }) => platform.tenant('PUT', project, `/queries/${id}`, { environment, body: definition })));
30
+ server.registerTool('query_delete', {
31
+ title: 'Query sil',
32
+ description: 'Query tanımını siler.',
33
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid },
34
+ annotations: destructive
35
+ }, handle(config, ({ project, environment, id }) => platform.tenant('DELETE', project, `/queries/${id}`, { environment })));
36
+ server.registerTool('query_clone', {
37
+ title: 'Query klonla',
38
+ description: 'Query\'nin kopyasını oluşturur.',
39
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid },
40
+ annotations: writes
41
+ }, handle(config, ({ project, environment, id }) => platform.tenant('POST', project, `/queries/${id}/clone`, { environment })));
42
+ server.registerTool('query_preview', {
43
+ title: 'Query önizle',
44
+ description: 'Kaydedilmemiş query tanımını datasource üzerinde çalıştırır. definition = PreviewQueryCommand gövdesi.',
45
+ inputSchema: { project: projectParam, environment: environmentParam, datasourceId: guid, definition: definitionParam },
46
+ annotations: writes
47
+ }, handle(config, ({ project, environment, datasourceId, definition }) => platform.tenant('POST', project, `/queries/${datasourceId}/preview`, { environment, body: definition })));
48
+ }
@@ -0,0 +1,115 @@
1
+ import { guid, projectParam, environmentParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
+ import { handle } from '../platform/responses.js';
3
+ import { z } from 'zod';
4
+ const rowValues = z.record(z.unknown()).describe("Alan SLUG'ı → değer sözlüğü; anahtarlar entity_get çıktısındaki field SLUG'larıdır (name değil — name kullanmak 'Please enter a valid value' hatası verir)");
5
+ export function registerRowTools(server, platform) {
6
+ const config = platform.config;
7
+ server.registerTool('row_list', {
8
+ title: 'Satırları listele',
9
+ description: 'Entity satırlarını filtre/sıralama/sayfalama ile listeler; selectedFields verilirse satırlar bu alanlara indirgenir (id her zaman dahil).',
10
+ inputSchema: {
11
+ project: projectParam,
12
+ environment: environmentParam,
13
+ entityId: guid,
14
+ selectedFields: z.array(z.string()).optional().describe('Dönen satırlar bu alan adlarına indirgenir, id her zaman dahildir; platform tam satırı hesapladığı için kırpma gateway tarafında yapılır'),
15
+ filters: z.array(z.record(z.unknown())).optional().describe('Platform Filter dizisi; biçim için row_list\'i filtresiz çağırıp Studio\'daki bir filtreyi referans alın'),
16
+ ...pagingParams
17
+ },
18
+ annotations: readOnly
19
+ }, handle(config, async ({ project, environment, entityId, ...body }) => {
20
+ const payload = await platform.tenant('POST', project, `/entities/${entityId}/row/list`, { environment, body });
21
+ const wanted = body.selectedFields ?? [];
22
+ if (!wanted.length || !payload || typeof payload !== 'object' || Array.isArray(payload))
23
+ return payload;
24
+ const rows = payload.data;
25
+ if (!Array.isArray(rows))
26
+ return payload;
27
+ const keep = new Set([...wanted.map(field => field.toLowerCase()), 'id']);
28
+ return {
29
+ ...payload,
30
+ data: rows.map(row => row && typeof row === 'object' && !Array.isArray(row)
31
+ ? Object.fromEntries(Object.entries(row).filter(([key]) => keep.has(key.toLowerCase())))
32
+ : row)
33
+ };
34
+ }));
35
+ server.registerTool('row_get', {
36
+ title: 'Satır getir',
37
+ description: 'Tek satırı id ile getirir.',
38
+ inputSchema: { project: projectParam, environment: environmentParam, entityId: guid, id: z.string().min(1) },
39
+ annotations: readOnly
40
+ }, handle(config, ({ project, environment, entityId, id }) => platform.tenant('GET', project, `/entities/${entityId}/row/${encodeURIComponent(id)}`, { environment })));
41
+ server.registerTool('row_create', {
42
+ title: 'Satır ekle',
43
+ description: "Tek satır için 'row', çoklu ekleme için 'rows' verin (ikisi birden verilmez).",
44
+ inputSchema: {
45
+ project: projectParam,
46
+ environment: environmentParam,
47
+ entityId: guid,
48
+ row: rowValues.optional(),
49
+ rows: z.array(z.record(z.unknown())).optional()
50
+ },
51
+ annotations: writes
52
+ }, handle(config, ({ project, environment, entityId, row, rows }) => {
53
+ if (row && rows)
54
+ throw new Error("'row' ve 'rows' birlikte verilemez.");
55
+ if (rows)
56
+ return platform.tenant('POST', project, `/entities/${entityId}/row/bulk`, { environment, body: { rows } });
57
+ if (row)
58
+ return platform.tenant('POST', project, `/entities/${entityId}/row`, { environment, body: { row } });
59
+ throw new Error("'row' ya da 'rows' parametrelerinden biri zorunlu.");
60
+ }));
61
+ server.registerTool('row_update', {
62
+ title: 'Satır güncelle',
63
+ description: "Tek satır için 'row', çoklu güncelleme için 'rows' verin; satır id alanı gövdede olmalıdır.",
64
+ inputSchema: {
65
+ project: projectParam,
66
+ environment: environmentParam,
67
+ entityId: guid,
68
+ row: rowValues.optional(),
69
+ rows: z.array(z.record(z.unknown())).optional()
70
+ },
71
+ annotations: updates
72
+ }, handle(config, ({ project, environment, entityId, row, rows }) => {
73
+ if (row && rows)
74
+ throw new Error("'row' ve 'rows' birlikte verilemez.");
75
+ if (rows)
76
+ return platform.tenant('PUT', project, `/entities/${entityId}/row/bulk`, { environment, body: { rows } });
77
+ if (row)
78
+ return platform.tenant('PUT', project, `/entities/${entityId}/row`, { environment, body: { row } });
79
+ throw new Error("'row' ya da 'rows' parametrelerinden biri zorunlu.");
80
+ }));
81
+ server.registerTool('row_delete', {
82
+ title: 'Satır sil',
83
+ description: "Tek satır için 'id', çoklu silme için 'ids' verin.",
84
+ inputSchema: {
85
+ project: projectParam,
86
+ environment: environmentParam,
87
+ entityId: guid,
88
+ id: z.string().optional(),
89
+ ids: z.array(z.union([z.string(), z.number()])).optional()
90
+ },
91
+ annotations: destructive
92
+ }, handle(config, ({ project, environment, entityId, id, ids }) => {
93
+ if (id && ids)
94
+ throw new Error("'id' ve 'ids' birlikte verilemez.");
95
+ if (ids)
96
+ return platform.tenant('POST', project, `/entities/${entityId}/row/bulk/delete`, { environment, body: { rowIds: ids } });
97
+ if (id)
98
+ return platform.tenant('DELETE', project, `/entities/${entityId}/row/${encodeURIComponent(id)}`, { environment });
99
+ throw new Error("'id' ya da 'ids' parametrelerinden biri zorunlu.");
100
+ }));
101
+ server.registerTool('row_next_code', {
102
+ title: 'Sıradaki kodu üret',
103
+ description: 'Incremental tipli alan için sıradaki kodu döner.',
104
+ inputSchema: {
105
+ project: projectParam,
106
+ environment: environmentParam,
107
+ entityId: guid,
108
+ fieldId: guid,
109
+ prefix: z.string().optional(),
110
+ separator: z.string().optional(),
111
+ digitCount: z.number().int().optional()
112
+ },
113
+ annotations: readOnly
114
+ }, handle(config, ({ project, environment, entityId, ...body }) => platform.tenant('POST', project, `/entities/${entityId}/row/next-code`, { environment, body })));
115
+ }
@@ -0,0 +1,97 @@
1
+ import { PlatformApiError } from '../platform/errors.js';
2
+ import { z } from 'zod';
3
+ export const hostParam = z.enum(['page', 'layout', 'component'])
4
+ .describe("Akışın barındırıcısı: page | layout | component (widget de component'tir)");
5
+ export const schemaParam = z.array(z.record(z.unknown()))
6
+ .describe('Komponent ağacı (DesignComponentManagementSchema listesi); verilmezse mevcut şema korunur');
7
+ export const eventsParam = z.array(z.record(z.unknown()))
8
+ .describe("Sayfa/layout düzeyi olaylar: [{ name, value }] — value bir flow id'sidir");
9
+ function asArray(value) {
10
+ return Array.isArray(value) ? value : [];
11
+ }
12
+ function identifiers(value) {
13
+ return asArray(value)
14
+ .map(entry => (entry && typeof entry === 'object' ? entry.id : entry))
15
+ .filter((id) => typeof id === 'string');
16
+ }
17
+ export function unwrap(payload) {
18
+ const data = payload?.data;
19
+ return ((data ?? payload) ?? {});
20
+ }
21
+ export function hostPath(host, applicationId, hostId) {
22
+ if (host === 'page')
23
+ return `/pages/${applicationId}/${hostId}`;
24
+ if (host === 'layout')
25
+ return `/layouts/${applicationId}/${hostId}`;
26
+ return `/components/${applicationId}/${hostId}`;
27
+ }
28
+ export function flowPath(host, applicationId, hostId, flowId) {
29
+ const root = host === 'page'
30
+ ? `/pages/${hostId}/flows`
31
+ : host === 'layout'
32
+ ? `/layouts/${hostId}/flows`
33
+ : `/components/${applicationId}/${hostId}/flows`;
34
+ return flowId ? `${root}/${flowId}` : root;
35
+ }
36
+ export function pageUpdateBody(page, overrides = {}) {
37
+ const layout = (page.layout ?? {});
38
+ return {
39
+ id: page.id,
40
+ applicationId: page.applicationId,
41
+ name: page.name,
42
+ slug: page.slug,
43
+ browserTitle: page.browserTitle ?? '',
44
+ schema: page.schema ?? [],
45
+ events: asArray(page.events).filter(event => event?.value),
46
+ middlewareIds: page.middlewareIds ?? [],
47
+ roleIds: Array.isArray(page.roleIds) ? page.roleIds : identifiers(page.roles),
48
+ layoutId: page.layoutId ?? layout.id ?? null,
49
+ ...overrides
50
+ };
51
+ }
52
+ export function layoutUpdateBody(layout, overrides = {}) {
53
+ return {
54
+ id: layout.id,
55
+ applicationId: layout.applicationId,
56
+ name: layout.name,
57
+ parameters: layout.parameters ?? null,
58
+ views: layout.views ?? [],
59
+ events: asArray(layout.events).filter(event => event?.value),
60
+ ...overrides
61
+ };
62
+ }
63
+ export function componentUpdateBody(component, overrides = {}) {
64
+ return {
65
+ applicationId: component.applicationId,
66
+ type: component.type ?? 'web',
67
+ widgetType: component.widgetType ?? null,
68
+ slug: component.slug,
69
+ name: component.name,
70
+ description: component.description ?? '',
71
+ icon: component.icon ?? '',
72
+ categories: component.categories ?? [],
73
+ definition: component.definition ?? {},
74
+ schema: component.schema ?? [],
75
+ isHide: component.isHide ?? false,
76
+ isDroppable: component.isDroppable ?? false,
77
+ isSticky: component.isSticky ?? false,
78
+ isDeletable: component.isDeletable ?? true,
79
+ isDefaultAutoHeight: component.isDefaultAutoHeight ?? false,
80
+ ...overrides
81
+ };
82
+ }
83
+ export async function fetchHost(platform, host, project, environment, applicationId, hostId) {
84
+ const payload = await platform.tenant('GET', project, hostPath(host, applicationId, hostId), { environment });
85
+ const record = unwrap(payload);
86
+ if (!record.id) {
87
+ throw new PlatformApiError(`${host} kaydı okunamadı (${hostId}); id doğru mu, application eşleşiyor mu kontrol edin.`);
88
+ }
89
+ return record;
90
+ }
91
+ export function hostUpdateBody(host, record, overrides = {}) {
92
+ if (host === 'page')
93
+ return pageUpdateBody(record, overrides);
94
+ if (host === 'layout')
95
+ return layoutUpdateBody(record, overrides);
96
+ return componentUpdateBody(record, overrides);
97
+ }
@@ -0,0 +1,65 @@
1
+ import { guid, pagingParams, readOnly, writes, updates } from './common.js';
2
+ import { handle } from '../platform/responses.js';
3
+ import { z } from 'zod';
4
+ export function registerTemplateTools(server, platform) {
5
+ const config = platform.config;
6
+ server.registerTool('template_list', {
7
+ title: 'Şablonları listele',
8
+ description: "Organizasyonun proje şablonlarını listeler. project_create'in templateOptions.templateId parametresi buradan gelir.",
9
+ inputSchema: {
10
+ searchTerm: z.string().optional(),
11
+ sourceModule: z.string().optional().describe("Module filtresi, ör. 'project'"),
12
+ ...pagingParams
13
+ },
14
+ annotations: readOnly
15
+ }, handle(config, query => platform.org('GET', '/templates', { query })));
16
+ server.registerTool('template_get', {
17
+ title: 'Şablon getir',
18
+ description: 'Tek şablonun künyesini getirir (sürüm, changelog, görseller).',
19
+ inputSchema: { id: guid },
20
+ annotations: readOnly
21
+ }, handle(config, ({ id }) => platform.org('GET', `/templates/${id}`)));
22
+ server.registerTool('template_items', {
23
+ title: 'Şablon içeriğini listele',
24
+ description: "Şablonun bir modüldeki kayıtlarını listeler (project_create'in templateOptions.filters'ını doldurmak için).",
25
+ inputSchema: {
26
+ id: guid,
27
+ module: z.string().describe("Module değeri: entity | microservice | workflow | page | layout | component | query | view …")
28
+ },
29
+ annotations: readOnly
30
+ }, handle(config, ({ id, module }) => platform.org('GET', `/templates/${id}/items`, { query: { module } })));
31
+ server.registerTool('template_create', {
32
+ title: 'Projeyi şablon olarak yayımla',
33
+ description: 'Mevcut projeden yeni bir şablon sürümü üretir. Görsel yükleme bu tool\'da desteklenmez (ikili aktarım kapsam dışı).',
34
+ inputSchema: {
35
+ projectId: guid,
36
+ name: z.string().min(1),
37
+ version: z.string().min(1).describe("Sürüm etiketi, ör. '1.0.0'"),
38
+ description: z.string().optional(),
39
+ changeLog: z.string().optional(),
40
+ environmentId: guid.optional().describe('Hangi environment\'ın içeriği paketlenecek; boşsa varsayılan')
41
+ },
42
+ annotations: writes
43
+ }, handle(config, ({ projectId, name, version, description, changeLog, environmentId }) => {
44
+ const form = new URLSearchParams({ Name: name, Version: version });
45
+ if (description)
46
+ form.set('Description', description);
47
+ if (changeLog)
48
+ form.set('ChangeLog', changeLog);
49
+ if (environmentId)
50
+ form.set('EnvironmentId', environmentId);
51
+ return platform.org('POST', `/projects/${projectId}/templates`, { form });
52
+ }));
53
+ server.registerTool('template_check_updates', {
54
+ title: 'Şablon güncellemesi var mı',
55
+ description: 'Şablondan kurulmuş projenin kaynak şablonunda yeni sürüm var mı kontrol eder.',
56
+ inputSchema: { projectId: guid },
57
+ annotations: readOnly
58
+ }, handle(config, ({ projectId }) => platform.org('GET', `/projects/${projectId}/templates/check-for-updates`)));
59
+ server.registerTool('template_receive_updates', {
60
+ title: 'Şablon güncellemelerini al',
61
+ description: 'Kaynak şablondaki güncellemeleri projeye uygular; önce template_check_updates ile neyin geleceğini görün. Proje içeriğini değiştirir.',
62
+ inputSchema: { projectId: guid },
63
+ annotations: updates
64
+ }, handle(config, ({ projectId }) => platform.org('POST', `/projects/${projectId}/templates/receive-updates`)));
65
+ }
@@ -0,0 +1,94 @@
1
+ import { parseVariableEntries, mergeVariableEntries, withNormalization } from '../knowledge/normalize.js';
2
+ import { guid, projectParam, environmentParam, readOnly, writes, updates, destructive } from './common.js';
3
+ import { handle } from '../platform/responses.js';
4
+ import { z } from 'zod';
5
+ const variablePath = (applicationId, pageId) => pageId ? `/variables/${applicationId}/${pageId}` : `/variables/${applicationId}`;
6
+ const variablesParam = z.array(z.object({
7
+ key: z.string().min(1).describe("Değişken adı; sayfada state.page.<key> ile okunur"),
8
+ value: z.unknown().describe('Herhangi bir JSON değeri; nesne verirseniz alanlarına state.page.<key>.<alan> ile erişilir')
9
+ })).min(1).describe("Değişken listesi: [{ key: 'MyTest', value: { isActive: true } }]. Gateway bunu platformun beklediği JSON string'e çevirir.");
10
+ const replaceParam = z.boolean().optional()
11
+ .describe('true: seti komple bunlarla değiştir (diğer değişkenler silinir). Varsayılan false — gateway mevcut setle birleştirir.');
12
+ export function registerVariableTools(server, platform) {
13
+ const config = platform.config;
14
+ const readEntries = async (project, environment, applicationId, pageId) => {
15
+ try {
16
+ const payload = await platform.tenant('GET', project, variablePath(applicationId, pageId), { environment });
17
+ const record = (payload?.data ?? payload);
18
+ return parseVariableEntries(record?.data);
19
+ }
20
+ catch {
21
+ return [];
22
+ }
23
+ };
24
+ const write = async (method, { project, environment, applicationId, pageId, variables, replace }) => {
25
+ const incoming = variables.map(entry => ({ key: entry.key, value: entry.value ?? null }));
26
+ const existing = replace === true ? [] : await readEntries(project, environment, applicationId, pageId);
27
+ const merged = mergeVariableEntries(existing, incoming, replace === true);
28
+ const response = await platform.tenant(method, project, variablePath(applicationId, pageId), {
29
+ environment,
30
+ body: {
31
+ applicationId,
32
+ ...(pageId ? { pageId } : {}),
33
+ data: JSON.stringify(merged.entries)
34
+ }
35
+ });
36
+ return withNormalization({
37
+ scope: pageId ? 'page' : 'application',
38
+ variables: merged.entries.map(entry => entry.key),
39
+ response
40
+ }, [
41
+ ...merged.fixes,
42
+ `data alanı JSON string'e çevrildi (platform sözleşmesi: "[{\\"key\\":…,\\"value\\":…}]") — dizi olarak gönderilse Studio çalışma zamanı okuyamaz`
43
+ ]);
44
+ };
45
+ server.registerTool('variable_list', {
46
+ title: 'Değişkenleri getir',
47
+ description: "Application (pageId verilirse sayfa) değişken setini getirir. Platform seti tek kayıtta ve JSON STRING olarak tutar; gateway çözüp [{key, value}] dizisi döndürür. Sayfada okuma yolu: state.page.<key> (uygulama düzeyinde state.app.<key>).",
48
+ inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, pageId: guid.optional() },
49
+ annotations: readOnly
50
+ }, handle(config, async ({ project, environment, applicationId, pageId }) => ({
51
+ scope: pageId ? 'page' : 'application',
52
+ applicationId,
53
+ ...(pageId ? { pageId } : {}),
54
+ variables: await readEntries(project, environment, applicationId, pageId)
55
+ })));
56
+ server.registerTool('variable_pages', {
57
+ title: 'Sayfa değişkenlerini listele',
58
+ description: 'Application altında sayfa bazlı tanımlanmış değişken setlerini listeler.',
59
+ inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid },
60
+ annotations: readOnly
61
+ }, handle(config, ({ project, environment, applicationId }) => platform.tenant('GET', project, `/variables/${applicationId}/pages`, { environment })));
62
+ server.registerTool('variable_create', {
63
+ title: 'Değişken tanımla',
64
+ description: "Application (pageId verilirse sayfa) değişkeni tanımlar. Platform uygulama/sayfa başına TEK kayıt tutar ve seti komple değiştirir; gateway mevcut setle birleştirir (replace: true ile ezersiniz). Sayfada kullanım: prop { type:'code', ref:\"{{ state.page.<key>.<alan> }}\" } ya da flow'da value { type:'state', ref:'<key>' }.",
65
+ inputSchema: {
66
+ project: projectParam,
67
+ environment: environmentParam,
68
+ applicationId: guid,
69
+ pageId: guid.optional().describe('Verilirse sayfa düzeyi (state.page), verilmezse uygulama düzeyi (state.app)'),
70
+ variables: variablesParam,
71
+ replace: replaceParam
72
+ },
73
+ annotations: writes
74
+ }, handle(config, input => write('POST', input)));
75
+ server.registerTool('variable_update', {
76
+ title: 'Değişken güncelle',
77
+ description: "Var olan değişken setini günceller (variable_create zaten kayıt varsa update'e düşer; ikisi de aynı sonucu verir). Anahtar bazında birleştirir, replace: true ile seti komple değiştirir.",
78
+ inputSchema: {
79
+ project: projectParam,
80
+ environment: environmentParam,
81
+ applicationId: guid,
82
+ pageId: guid.optional(),
83
+ variables: variablesParam,
84
+ replace: replaceParam
85
+ },
86
+ annotations: updates
87
+ }, handle(config, input => write('PUT', input)));
88
+ server.registerTool('variable_delete', {
89
+ title: 'Değişken setini sil',
90
+ description: "Application (pageId verilirse sayfa) değişken setinin TAMAMINI siler — tek değişken silmek için variable_update'e kalan listeyi replace: true ile gönderin.",
91
+ inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, pageId: guid.optional() },
92
+ annotations: destructive
93
+ }, handle(config, ({ project, environment, applicationId, pageId }) => platform.tenant('DELETE', project, variablePath(applicationId, pageId), { environment })));
94
+ }
@@ -0,0 +1,58 @@
1
+ import { normalizeViewDefinition, viewAliasNote, withNormalization } from '../knowledge/normalize.js';
2
+ import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
3
+ import { PlatformApiError } from '../platform/errors.js';
4
+ import { handle } from '../platform/responses.js';
5
+ import { z } from 'zod';
6
+ export function registerViewTools(server, platform) {
7
+ const config = platform.config;
8
+ const normalizeSource = (definition) => {
9
+ const { fixes, errors } = normalizeViewDefinition(definition);
10
+ if (errors.length > 0)
11
+ throw new PlatformApiError(errors.join(' · '), 400);
12
+ return fixes;
13
+ };
14
+ server.registerTool('view_list', {
15
+ title: 'View listele',
16
+ description: 'Projedeki view arama indekslerini listeler. DİKKAT: view modülü RAPORLAMA/özet için DEĞİL, tam metin (global) ARAMA içindir.',
17
+ inputSchema: { project: projectParam, environment: environmentParam, searchTerm: z.string().optional(), ...pagingParams },
18
+ annotations: readOnly
19
+ }, handle(config, ({ project, environment, ...query }) => platform.tenant('GET', project, '/views', { environment, query })));
20
+ server.registerTool('view_get', {
21
+ title: 'View getir',
22
+ description: 'Tek view tanımını getirir; view_create için en iyi gövde şablonudur.',
23
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid },
24
+ annotations: readOnly
25
+ }, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/views/${id}`, { environment })));
26
+ server.registerTool('view_create', {
27
+ title: 'View oluştur',
28
+ description: "TAM METİN ARAMA indeksi tanımlar (definition = CreateViewCommand; gövde şeması ngapps://schemas/CreateViewCommand, analizör sözlüğü platform_guide('view')) — raporlama/agregasyon aracı DEĞİLDİR. Seçilen tablo/alanlar analizörden (tokenizer/dil) geçirilip slug adlı projeksiyon tablosuna indekslenir; tüketimi source:'view' microservice'idir ve o uç ZORUNLU 'searchText' parametresi ister (+limit/offset). Rapor/özet için raw query (query_create) + query kaynaklı microservice kullanın. Birden çok entity verilebilir (entities: [{entityId, alias}], fields alias'la bağlanır: viewEntityAlias) ama bu JOIN DEĞİLDİR: her tablo ayrı ayrı indekslenir, aralarında ilişki tanımı yoktur ve eşleşme hangi tablodan geldiyse dönen kayıt o tablonun satırıdır. İlişkili içeriği tek kayıtta aratmak için denormalize bir alan kullanın (yorum metnini talebe yazan automation + tek entity'li view).",
29
+ inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam },
30
+ annotations: writes
31
+ }, handle(config, async ({ project, environment, definition }) => {
32
+ const fixes = normalizeSource(definition);
33
+ const response = await platform.tenant('POST', project, '/views', { environment, body: definition });
34
+ return withNormalization(response, viewAliasNote(fixes));
35
+ }));
36
+ server.registerTool('view_update', {
37
+ title: 'View güncelle',
38
+ description: "View tanımını günceller (definition = UpdateViewCommand, şema ngapps://schemas/UpdateViewCommand); mevcut hâli view_get ile alın. UpdateViewCommand'da datasourceId YOKTUR (create'te bağlanır). DİKKAT: view_get alanları 'viewEntityId' ile döndürür, yazma tarafı 'viewEntityAlias' ister — okuduğunuzu birebir geri yazarsanız gateway id'yi alias'a çevirir, çeviremezse isteği reddeder.",
39
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid, definition: definitionParam },
40
+ annotations: updates
41
+ }, handle(config, async ({ project, environment, id, definition }) => {
42
+ const fixes = normalizeSource(definition);
43
+ const response = await platform.tenant('PUT', project, `/views/${id}`, { environment, body: definition });
44
+ return withNormalization(response, viewAliasNote(fixes));
45
+ }));
46
+ server.registerTool('view_delete', {
47
+ title: 'View sil',
48
+ description: 'View projeksiyonunu siler.',
49
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid },
50
+ annotations: destructive
51
+ }, handle(config, ({ project, environment, id }) => platform.tenant('DELETE', project, `/views/${id}`, { environment })));
52
+ server.registerTool('view_rebuild', {
53
+ title: 'View yeniden kur',
54
+ description: 'View projeksiyon tablosunu yeniden inşa eder (veri değişikliklerinden sonra senkron için).',
55
+ inputSchema: { project: projectParam, environment: environmentParam, id: guid },
56
+ annotations: writes
57
+ }, handle(config, ({ project, environment, id }) => platform.tenant('POST', project, `/views/${id}/rebuild`, { environment })));
58
+ }