@nitra/cursor 1.8.99 → 1.8.100

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/mdc/abie.mdc CHANGED
@@ -115,7 +115,7 @@ spec:
115
115
 
116
116
  ## k8s: overlay **ru** і **Service** (у т. ч. headless → NodePort)
117
117
 
118
- Для кожного **Service** в YAML під **`…/k8s/…`**, де шлях файлу **не** містить **`k8s/ua/`** чи **`k8s/ru/`** (маніфести base / спільного шару; у т. ч. **headless** з **`spec.clusterIP: None`** і **`-hl`**), якщо ще не **`spec.type: NodePort`** / **`LoadBalancer`** / **`ExternalName`**, у **`k8s/ru/kustomization.yaml`** того ж пакета (overlay **ru**) додай **inline** **JSON6902** у **`patches`**: **`target.kind: Service`**, **`target.name`** як у маніфеста, **`path: /spec/type`**, **`value: NodePort`**. Якщо в base було **`spec.clusterIP: None`** або **`spec.clusterIPs`** з **`None`** (типово **headless**), у тому ж **patch** додай **`op: remove`** для **`/spec/clusterIP`** та **`/spec/clusterIPs`**інакше API відхилить **NodePort** з помилкою на **`clusterIPs`**. Деталі — **`check-abie.mjs`**.
118
+ Для кожного **Service** в YAML під **`…/k8s/…`**, де шлях файлу **не** містить **`k8s/ua/`** чи **`k8s/ru/`** (маніфести base / спільного шару; у т. ч. **headless** з **`spec.clusterIP: None`** і **`-hl`**), якщо ще не **`spec.type: NodePort`** / **`LoadBalancer`** / **`ExternalName`**, у **`k8s/ru/kustomization.yaml`** того ж пакета (overlay **ru**) додай **inline** **JSON6902** у **`patches`**: **`target.kind: Service`**, **`target.name`** як у маніфеста, **`path: /spec/type`**, **`value: NodePort`**. Якщо в base було **`spec.clusterIP: None`**, у тому ж **patch** додай **`op: remove`** для **`/spec/clusterIP`** (не додавай **`remove`** на **`/spec/clusterIPs`**: у статичному YAML ключа часто немає **`kubectl kustomize`** падає з *Unable to remove nonexistent key*). Деталі — **`check-abie.mjs`**.
119
119
 
120
120
  ```yaml title="…/ru/kustomization.yaml (фрагмент, headless → NodePort)"
121
121
  patches:
@@ -128,8 +128,6 @@ patches:
128
128
  value: NodePort
129
129
  - op: remove
130
130
  path: /spec/clusterIP
131
- - op: remove
132
- path: /spec/clusterIPs
133
131
  ```
134
132
 
135
133
  ## k8s: overlay **ru** і HealthCheckPolicy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "1.8.99",
3
+ "version": "1.8.100",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -34,7 +34,7 @@
34
34
  * Вибір **`op`** — **k8s.mdc**.
35
35
  *
36
36
  * **Service (overlay ru):** для кожного **Service**, оголошеного в YAML під **`…/k8s/…`**, де шлях **не** проходить через **`k8s/ua/`** чи **`k8s/ru/`** (маніфести base / спільного шару, у т. ч. **headless** з **`clusterIP: None`** і **`-hl`**), якщо ще не **NodePort** / **LoadBalancer** / **ExternalName**,
37
- * у файлі **`k8s/ru/kustomization.yaml`** того ж пакета (overlay середовища **ru**) — inline **JSON6902** на **`kind: Service`** з тим самим **`target.name`**: **`path: /spec/type`**, **`value: NodePort`**; якщо в base було **`spec.clusterIP: None`** або **`spec.clusterIPs`** з **`None`** — у тому ж patch додай **`op: remove`** для **`/spec/clusterIP`** та **`/spec/clusterIPs`** (інакше **NodePort** з **`None`** відхиляє API).
37
+ * у файлі **`k8s/ru/kustomization.yaml`** того ж пакета (overlay середовища **ru**) — inline **JSON6902** на **`kind: Service`** з тим самим **`target.name`**: **`path: /spec/type`**, **`value: NodePort`**; якщо в base було **`spec.clusterIP: None`** — у тому ж patch додай **`op: remove`** для **`/spec/clusterIP`** (поле **`clusterIPs`** у статичному YAML часто відсутнє — **`remove`** на **`/spec/clusterIPs`** ламає **`kubectl kustomize`**).
38
38
  */
39
39
  import { existsSync } from 'node:fs'
40
40
  import { readFile } from 'node:fs/promises'
@@ -370,9 +370,9 @@ export function serviceDocumentRequiresAbieRuNodePortOverlay(obj) {
370
370
  }
371
371
 
372
372
  /**
373
- * Чи в base-**Service** є **headless** **`None`**, який треба прибрати в **ru** перед **NodePort** (**clusterIP** / **clusterIPs**).
373
+ * Чи в base-**Service** задано **headless** через **`spec.clusterIP: None`**, який треба прибрати в **ru** перед **NodePort**.
374
374
  * @param {unknown} obj корінь YAML (**Service**)
375
- * @returns {boolean} **true**, якщо **`spec.clusterIP === 'None'`** або **`spec.clusterIPs`** містить **`'None'`**
375
+ * @returns {boolean} **true**, якщо **`spec.clusterIP === 'None'`**
376
376
  */
377
377
  export function serviceDocumentRequiresRuClusterIPNoneRemoval(obj) {
378
378
  if (!isServiceDoc(obj)) {
@@ -384,14 +384,7 @@ export function serviceDocumentRequiresRuClusterIPNoneRemoval(obj) {
384
384
  return false
385
385
  }
386
386
  const sp = /** @type {Record<string, unknown>} */ (spec)
387
- if (sp.clusterIP === 'None') {
388
- return true
389
- }
390
- const cips = sp.clusterIPs
391
- if (Array.isArray(cips) && cips.includes('None')) {
392
- return true
393
- }
394
- return false
387
+ return sp.clusterIP === 'None'
395
388
  }
396
389
 
397
390
  /**
@@ -404,24 +397,21 @@ export function jsonPatchRemovesPath(patchText, posixPath) {
404
397
  if (typeof patchText !== 'string' || patchText.trim() === '') {
405
398
  return false
406
399
  }
407
- if (posixPath !== '/spec/clusterIP' && posixPath !== '/spec/clusterIPs') {
400
+ if (posixPath !== '/spec/clusterIP') {
408
401
  return false
409
402
  }
410
- const pathRe =
411
- posixPath === '/spec/clusterIP'
412
- ? String.raw`path:\s*\/spec\/clusterIP\b`
413
- : String.raw`path:\s*\/spec\/clusterIPs\b`
403
+ const pathRe = String.raw`path:\s*\/spec\/clusterIP\b`
414
404
  const opRe = String.raw`op:\s*remove\b`
415
405
  return new RegExp(`${opRe}[\\s\\S]{0,200}?${pathRe}`, 'mu').test(patchText) || new RegExp(`${pathRe}[\\s\\S]{0,200}?${opRe}`, 'mu').test(patchText)
416
406
  }
417
407
 
418
408
  /**
419
- * Чи patch прибирає **headless** поля **`clusterIP`** / **`clusterIPs`**, щоб **NodePort** пройшов валідацію API.
409
+ * Чи patch містить **`op: remove`** для **`/spec/clusterIP`**, щоб прибрати **headless** перед **NodePort**.
420
410
  * @param {string} patchText поле **patch** у kustomization
421
- * @returns {boolean} true, якщо є **remove** і для **`/spec/clusterIP`**, і для **`/spec/clusterIPs`**
411
+ * @returns {boolean} true, якщо є **remove** для **`/spec/clusterIP`**
422
412
  */
423
413
  export function jsonPatchTextClearsHeadlessServiceClusterIPNone(patchText) {
424
- return jsonPatchRemovesPath(patchText, '/spec/clusterIP') && jsonPatchRemovesPath(patchText, '/spec/clusterIPs')
414
+ return jsonPatchRemovesPath(patchText, '/spec/clusterIP')
425
415
  }
426
416
 
427
417
  /**
@@ -538,7 +528,7 @@ export function getAbieRuServiceNodePortPatchErrors(raw, targetsByName) {
538
528
  }
539
529
  if (requiresClear && !jsonPatchTextClearsHeadlessServiceClusterIPNone(pt)) {
540
530
  errors.push(
541
- `${name}: для spec.clusterIP/spec.clusterIPs: None додай у той самий patch op: remove для path /spec/clusterIP та /spec/clusterIPs (abie.mdc)`
531
+ `${name}: для spec.clusterIP: None додай у той самий patch op: remove для path /spec/clusterIP (abie.mdc)`
542
532
  )
543
533
  }
544
534
  }
@@ -617,7 +607,7 @@ async function collectAbieRuNodePortServiceTargetsByPackage(root, yamlAbs, fail)
617
607
  }
618
608
 
619
609
  /**
620
- * У **`k8s/ru/kustomization.yaml`** для кожного **Service** з YAML **`k8s`**, шлях якого без сегментів **`k8s/ua/`** та **`k8s/ru/`** (у т. ч. **headless** / **`-hl`**) — **JSON6902** **`/spec/type` → NodePort**; якщо в base було **`clusterIP: None`** / **`clusterIPs: None`** — також **`op: remove`** на **`/spec/clusterIP`** та **`/spec/clusterIPs`** (abie.mdc).
610
+ * У **`k8s/ru/kustomization.yaml`** для кожного **Service** з YAML **`k8s`**, шлях якого без сегментів **`k8s/ua/`** та **`k8s/ru/`** (у т. ч. **headless** / **`-hl`**) — **JSON6902** **`/spec/type` → NodePort**; якщо в base було **`clusterIP: None`** — також **`op: remove`** на **`/spec/clusterIP`** (abie.mdc).
621
611
  * @param {string} root корінь
622
612
  * @param {string[]} yamlFilesAbs yaml під **k8s**
623
613
  * @param {(msg: string) => void} fail callback
@@ -637,7 +627,7 @@ async function ensureRuAbieServiceNodePortPatches(root, yamlFilesAbs, fail, pass
637
627
  const nameList = [...targetsByName.keys()].toSorted((a, b) => a.localeCompare(b))
638
628
  if (!existsSync(ruAbs)) {
639
629
  fail(
640
- `${relPkg}/k8s: є Service, для overlay ru потрібен patch Service (NodePort; для headless — ще remove clusterIP/clusterIPs): ${nameList.join(', ')} — додай ru/kustomization.yaml (abie.mdc)`
630
+ `${relPkg}/k8s: є Service, для overlay ru потрібен patch Service (NodePort; для headless — ще remove /spec/clusterIP): ${nameList.join(', ')} — додай ru/kustomization.yaml (abie.mdc)`
641
631
  )
642
632
  return
643
633
  }