@appaflytech/zeyrek-ai-mcp 0.0.9 → 0.0.10

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.
@@ -1,3 +1,4 @@
1
+ import fastJsonPatch from 'fast-json-patch';
1
2
  import { functionSignature } from './functionGuards.js';
2
3
  function asArray(value) {
3
4
  return Array.isArray(value) ? value.filter((entry) => Boolean(entry) && typeof entry === 'object') : [];
@@ -280,22 +281,38 @@ export function describePatchTarget(document, path) {
280
281
  const kind = entry.type ?? entry.dbType;
281
282
  return `${path} → '${label}'${kind ? ` (${String(kind)}` + `, id ${String(entry.id ?? '?')})` : `, id ${String(entry.id ?? '?')}`}`;
282
283
  }
284
+ /**
285
+ * Her op, KENDİSİNDEN ÖNCEKİ op'ların uygulanmış hâlindeki belgeye karşı çözülür ve hemen
286
+ * ardından o tek op çalışan kopyaya uygulanır (S-3): aynı diziye giden birden çok `remove`
287
+ * seçicisi tek seferde ORİJİNAL belgeye göre indekse çevrilseydi, ilk silme diziyi kısaltıp
288
+ * sonraki op'ların indeksini kaydırırdı — yanıt yine de "applied: true" derdi çünkü hedef adı da
289
+ * aynı bayat belgeden okunuyordu. Dönen `operations` dizisi, orijinal belgeye karşı SIRAYLA
290
+ * uygulandığında (tek `fastJsonPatch.applyPatch` çağrısıyla dahi) bu adım adım simülasyonla aynı
291
+ * sonucu üretir; çağıranların uygulama biçimini değiştirmesi gerekmez.
292
+ */
283
293
  export function resolvePatchOperations(document, operations, readTool = 'workflow_get') {
284
294
  const notes = [];
285
295
  const targets = [];
286
- const resolved = operations.map(operation => {
296
+ const resolvedOperations = [];
297
+ let working = structuredClone(document);
298
+ for (const operation of operations) {
287
299
  const path = typeof operation.path === 'string' ? operation.path : '';
288
300
  const op = typeof operation.op === 'string' ? operation.op : '';
289
- const outcome = resolvePatchPointer(document, path, readTool, op);
290
- const from = typeof operation.from === 'string' ? resolvePatchPointer(document, operation.from, readTool, op) : undefined;
301
+ const outcome = resolvePatchPointer(working, path, readTool, op);
302
+ const from = typeof operation.from === 'string' ? resolvePatchPointer(working, operation.from, readTool, op) : undefined;
291
303
  if (outcome.note)
292
304
  notes.push(outcome.note);
293
305
  if (from?.note)
294
306
  notes.push(from.note);
295
- targets.push(describePatchTarget(document, outcome.path));
296
- return from ? { ...operation, path: outcome.path, from: from.path } : { ...operation, path: outcome.path };
297
- });
298
- return { operations: resolved, notes, targets };
307
+ targets.push(describePatchTarget(working, outcome.path));
308
+ const resolvedOperation = from ? { ...operation, path: outcome.path, from: from.path } : { ...operation, path: outcome.path };
309
+ resolvedOperations.push(resolvedOperation);
310
+ // validate:false — bu yalnız SONRAKİ op'ların indeksini doğru izlemek için ara bir simülasyon;
311
+ // gerçek RFC6902 doğrulaması (ör. 'replace' hedefinin önceden var olması) çağıranın az sonra
312
+ // yapacağı asıl uygulamada (validate:true) hâlâ çalışır, burada erken ve gereksiz patlamaz.
313
+ working = fastJsonPatch.applyPatch(working, [resolvedOperation], false, true).newDocument;
314
+ }
315
+ return { operations: resolvedOperations, notes, targets };
299
316
  }
300
317
  /**
301
318
  * Fonksiyon özeti (G-07): kaynak, ad, kapsam, imza, parametre listesi, gövde satır sayısı —
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appaflytech/zeyrek-ai-mcp",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "type": "module",
5
5
  "description": "Zeyrek (NgApps) platform APIs as MCP tools — data, logic and Studio design surface in one gateway",
6
6
  "license": "UNLICENSED",
@@ -54,4 +54,4 @@
54
54
  "typescript": "^5.7.2",
55
55
  "vitest": "^3.0.0"
56
56
  }
57
- }
57
+ }
@@ -1,63 +0,0 @@
1
- import { guid, projectParam, environmentParam, readOnly, writes, updates, destructive } from './common.js';
2
- import { handle } from '../platform/responses.js';
3
- import { z } from 'zod';
4
- const identifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
5
- const nameParam = z.string().min(1).regex(identifier, 'Geçerli bir JavaScript tanımlayıcısı olmalı')
6
- .describe("Motorun bağlayacağı ad; ifadelerde bu adla çağrılır (sum(1, 2)). Sistem fonksiyonlarının adları (Now, UtcNow, GenerateGuid, crypto…) rezervedir ve reddedilir");
7
- const functionParam = z.string().min(1)
8
- .describe("Klasik ya da arrow JavaScript FONKSİYON İFADESİ: '(left, right) => left + right' ya da 'function (a) { return a * 2 }'. Deyim değil ifade olmalı — 'return a + b' gibi bir gövde tek başına reddedilir. Platform kaydetmeden önce gerçek bir Jint motorunda çalıştırıp sonucun çağrılabilir olduğunu doğrular; SÖZDİZİMİ ve çağrılabilirlik denetlenir, gövdenin içindeki serbest değişkenler DENETLENMEZ");
9
- const descriptionParam = z.string().min(1)
10
- .describe('Fonksiyonun ne işe yaradığı; Studio kod editöründe autocomplete infobox başlığı olarak görünür. Zorunludur');
11
- const schemaParam = z.array(z.object({
12
- name: z.string().min(1).regex(identifier, 'Geçerli bir JavaScript tanımlayıcısı olmalı')
13
- .describe('Parametre adı; fonksiyon içinde benzersiz olmalı'),
14
- description: z.string().min(1).describe('Parametrenin ne olduğu; infobox\'ta parametre satırı olarak görünür. Zorunludur')
15
- })).describe('Parametre şeması, SIRALI. Yalnız dokümantasyon ve autocomplete imzası için kullanılır — motor çağrıyı bu şemaya göre DOĞRULAMAZ, eksik argüman undefined gelir. Parametresiz fonksiyonda boş dizi verin');
16
- export function registerGlobalFunctionTools(server, platform) {
17
- const config = platform.config;
18
- server.registerTool('global_function_list', {
19
- title: 'Global fonksiyonları listele',
20
- description: "Tenant kapsamındaki global JavaScript fonksiyonlarını listeler. Bunlar her workflow/automation/middleware koşumunda ve Studio preview'ında motora bağlanır; ifadelerde çıplak adla çağrılırlar.",
21
- inputSchema: { project: projectParam, environment: environmentParam },
22
- annotations: readOnly
23
- }, handle(config, ({ project, environment }) => platform.tenant('GET', project, '/global-functions', { environment })));
24
- server.registerTool('global_function_get', {
25
- title: 'Global fonksiyonu getir',
26
- description: 'Tek bir global fonksiyonun adını, gövdesini, açıklamasını ve parametre şemasını getirir.',
27
- inputSchema: { project: projectParam, environment: environmentParam, id: guid },
28
- annotations: readOnly
29
- }, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/global-functions/${id}`, { environment })));
30
- server.registerTool('global_function_create', {
31
- title: 'Global fonksiyon tanımla',
32
- description: "Yeni global fonksiyon kaydeder. Ad tenant içinde BENZERSİZDİR. Fonksiyon açıklaması ve HER parametre açıklaması zorunludur — Studio bunları autocomplete infobox'ında gösterir. Gövde bağlamdan bağımsız olmalı: içinde 'input' ya da bir adım adı gibi SERBEST DEĞİŞKEN kullanırsanız kayıt geçer ama fonksiyon o değişkenin tanımlı olmadığı her akışta 'X is not defined' ile patlar; dinamik veriyi parametre olarak geçirin.",
33
- inputSchema: {
34
- project: projectParam,
35
- environment: environmentParam,
36
- name: nameParam,
37
- function: functionParam,
38
- description: descriptionParam,
39
- schema: schemaParam
40
- },
41
- annotations: writes
42
- }, handle(config, ({ project, environment, name, function: body, description, schema }) => platform.tenant('POST', project, '/global-functions', { environment, body: { name, function: body, description, schema } })));
43
- server.registerTool('global_function_update', {
44
- title: 'Global fonksiyonu güncelle',
45
- description: "Global fonksiyonun tamamını değiştirir (PUT — dört alanı da gönderin). ADI DEĞİŞTİRMEK, fonksiyonu çağıran bir workflow varsa 400 ile reddedilir (CantRenameUsedGlobalFunctionException); gövde/açıklama/şema değişikliği serbesttir. Adı gerçekten değiştirmeniz gerekiyorsa önce çağıran akışlardaki ifadeleri güncelleyin.",
46
- inputSchema: {
47
- project: projectParam,
48
- environment: environmentParam,
49
- id: guid,
50
- name: nameParam,
51
- function: functionParam,
52
- description: descriptionParam,
53
- schema: schemaParam
54
- },
55
- annotations: updates
56
- }, handle(config, ({ project, environment, id, name, function: body, description, schema }) => platform.tenant('PUT', project, `/global-functions/${id}`, { environment, body: { name, function: body, description, schema } })));
57
- server.registerTool('global_function_delete', {
58
- title: 'Global fonksiyonu sil',
59
- description: "Global fonksiyonu siler. Fonksiyonu çağıran bir workflow varsa 400 ile reddedilir (CantDeleteUsedGlobalFunctionException) ve mesaj çağıran akışların adlarını sayar. Eşleşme tam tanımlayıcı sınırıyla aranır: 'checksum' ya da 'mySum' içeren bir ifade 'sum' çağrısı sayılmaz.",
60
- inputSchema: { project: projectParam, environment: environmentParam, id: guid },
61
- annotations: destructive
62
- }, handle(config, ({ project, environment, id }) => platform.tenant('DELETE', project, `/global-functions/${id}`, { environment })));
63
- }