@elaraai/tsserver-plugin-east 1.0.14 → 1.0.15

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 (2) hide show
  1. package/dist/index.cjs +731 -153
  2. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -24,8 +24,6 @@ __export(tsserver_plugin_exports, {
24
24
  init: () => init
25
25
  });
26
26
  module.exports = __toCommonJS(tsserver_plugin_exports);
27
- var import_node_fs = require("node:fs");
28
- var import_node_path2 = require("node:path");
29
27
 
30
28
  // ../east-diagnostics/dist/src/east-type.js
31
29
  function isEastExprType(type) {
@@ -71,40 +69,64 @@ function matchBlockBuilderCall(node, ctx) {
71
69
  // ../east-diagnostics/dist/src/rules/no-redundant-east-cast.js
72
70
  var NAME = "no-redundant-east-cast";
73
71
  var CODE = 990001;
72
+ function isEastValueCall(expr, t) {
73
+ if (!t.isCallExpression(expr))
74
+ return false;
75
+ const callee = expr.expression;
76
+ return t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "East" && callee.name.text === "value";
77
+ }
78
+ function report(ctx, target, messageText, fixDescription, newText) {
79
+ const sf = ctx.sourceFile;
80
+ const start = target.getStart(sf);
81
+ const length = target.getEnd() - start;
82
+ ctx.report({
83
+ ruleName: NAME,
84
+ code: CODE,
85
+ start,
86
+ length,
87
+ messageText,
88
+ category: "warning",
89
+ fix: { description: fixDescription, changes: [{ start, length, newText }] }
90
+ });
91
+ }
74
92
  var noRedundantEastCast = {
75
93
  name: NAME,
76
94
  code: CODE,
77
- description: "Disallow a TypeScript cast on the value argument of $.let/$.const when the East type argument is present (the type argument already drives inference).",
95
+ description: "Disallow TypeScript type info on the value of $.let/$.const that the East type argument already governs (a cast, `new Map<K,V>()` generics, or an `East.value(x,T)` wrapper).",
78
96
  check(node, ctx) {
79
97
  const match = matchBlockBuilderCall(node, ctx);
80
- if (match === void 0 || match.args.length < 2)
98
+ if (match === void 0)
81
99
  return;
82
100
  const t = ctx.ts;
83
101
  const value = match.args[0];
84
102
  if (value === void 0)
85
103
  return;
86
- let inner;
104
+ const sf = ctx.sourceFile;
105
+ if (isEastValueCall(value, t)) {
106
+ const inner = value.arguments[0];
107
+ if (inner === void 0)
108
+ return;
109
+ const typeArg = match.args[1] ?? value.arguments[1];
110
+ const receiverText = match.call.expression.getText(sf);
111
+ const newText = `${receiverText}(${inner.getText(sf)}${typeArg !== void 0 ? `, ${typeArg.getText(sf)}` : ""})`;
112
+ report(ctx, match.call, `Redundant \`East.value(...)\` inside \`$.${match.method}\`: pass the value (and its East type) to \`$.${match.method}\` directly.`, "Lift the value and type out of East.value(...)", newText);
113
+ return;
114
+ }
115
+ if (match.args.length < 2)
116
+ return;
117
+ let cast;
87
118
  if (t.isAsExpression(value))
88
- inner = value.expression;
119
+ cast = value.expression;
89
120
  else if (t.isTypeAssertionExpression(value))
90
- inner = value.expression;
91
- if (inner === void 0)
121
+ cast = value.expression;
122
+ if (cast !== void 0) {
123
+ report(ctx, value, `Redundant cast: \`$.${match.method}\` infers the value type from the East type argument; drop the \`as \u2026\` on the value.`, "Remove redundant cast", cast.getText(sf));
92
124
  return;
93
- const sf = ctx.sourceFile;
94
- const start = value.getStart(sf);
95
- const length = value.getEnd() - start;
96
- ctx.report({
97
- ruleName: NAME,
98
- code: CODE,
99
- start,
100
- length,
101
- messageText: `Redundant cast: \`$.${match.method}\` infers the value type from the East type argument; drop the \`as \u2026\` on the value.`,
102
- category: "warning",
103
- fix: {
104
- description: "Remove redundant cast",
105
- changes: [{ start, length, newText: inner.getText(sf) }]
106
- }
107
- });
125
+ }
126
+ if (t.isNewExpression(value) && value.typeArguments !== void 0 && value.typeArguments.length > 0) {
127
+ const ctorArgs = (value.arguments ?? []).map((a) => a.getText(sf)).join(", ");
128
+ report(ctx, value, `Redundant type arguments: \`$.${match.method}\` infers the value type from the East type argument; drop the \`<\u2026>\` on \`new ${value.expression.getText(sf)}\`.`, "Remove redundant constructor type arguments", `new ${value.expression.getText(sf)}(${ctorArgs})`);
129
+ }
108
130
  }
109
131
  };
110
132
 
@@ -336,6 +358,59 @@ var preferLetConstOverEastValue = {
336
358
  }
337
359
  };
338
360
 
361
+ // ../east-diagnostics/dist/src/east-source.js
362
+ var import_node_fs = require("node:fs");
363
+ var import_node_path = require("node:path");
364
+ var importsCache = /* @__PURE__ */ new WeakMap();
365
+ function importsEastPackage(sf, t) {
366
+ const cached = importsCache.get(sf);
367
+ if (cached !== void 0)
368
+ return cached;
369
+ let found = false;
370
+ for (const stmt of sf.statements) {
371
+ if (!t.isImportDeclaration(stmt) && !t.isExportDeclaration(stmt))
372
+ continue;
373
+ const spec = stmt.moduleSpecifier;
374
+ if (spec !== void 0 && t.isStringLiteral(spec) && spec.text.startsWith("@elaraai/")) {
375
+ found = true;
376
+ break;
377
+ }
378
+ }
379
+ importsCache.set(sf, found);
380
+ return found;
381
+ }
382
+ var pkgDirCache = /* @__PURE__ */ new Map();
383
+ function packageDirOf(p) {
384
+ const start = (0, import_node_path.dirname)((0, import_node_path.resolve)(p));
385
+ if (pkgDirCache.has(start))
386
+ return pkgDirCache.get(start);
387
+ let dir = start;
388
+ let result;
389
+ for (; ; ) {
390
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(dir, "package.json"))) {
391
+ result = dir;
392
+ break;
393
+ }
394
+ const parent = (0, import_node_path.dirname)(dir);
395
+ if (parent === dir)
396
+ break;
397
+ dir = parent;
398
+ }
399
+ pkgDirCache.set(start, result);
400
+ return result;
401
+ }
402
+ function resolvesWithinOwnPackage(sourceFileName, specifierText) {
403
+ try {
404
+ const own = packageDirOf(sourceFileName);
405
+ if (own === void 0)
406
+ return false;
407
+ const targetAbs = (0, import_node_path.resolve)((0, import_node_path.dirname)(sourceFileName), specifierText);
408
+ return packageDirOf(targetAbs) === own;
409
+ } catch {
410
+ return true;
411
+ }
412
+ }
413
+
339
414
  // ../east-diagnostics/dist/src/rules/no-relative-src-import.js
340
415
  var NAME7 = "no-relative-src-import";
341
416
  var CODE7 = 990007;
@@ -361,6 +436,8 @@ var noRelativeSrcImport = {
361
436
  const deepPackageSrc = DEEP_PACKAGE_SRC.test(text);
362
437
  if (!relativeIntoSrc && !deepPackageSrc)
363
438
  return;
439
+ if (relativeIntoSrc && !deepPackageSrc && resolvesWithinOwnPackage(ctx.sourceFile.fileName, text))
440
+ return;
364
441
  const sf = ctx.sourceFile;
365
442
  const start = specifier.getStart(sf);
366
443
  ctx.report({
@@ -395,8 +472,8 @@ var noLetConstInExpression = {
395
472
  }
396
473
  if (parent === void 0)
397
474
  return;
398
- const usedInExpression = t.isPropertyAccessExpression(parent) && parent.expression === current || t.isElementAccessExpression(parent) && parent.expression === current || t.isBinaryExpression(parent) && (parent.left === current || parent.right === current) || t.isCallExpression(parent) && parent.arguments.some((arg) => arg === current);
399
- if (!usedInExpression)
475
+ const allowed = t.isVariableDeclaration(parent) && parent.initializer === current || t.isExpressionStatement(parent) && parent.expression === current || t.isReturnStatement(parent) && parent.expression === current || t.isArrowFunction(parent) && parent.body === current;
476
+ if (allowed)
400
477
  return;
401
478
  const sf = ctx.sourceFile;
402
479
  const start = call.getStart(sf);
@@ -411,6 +488,40 @@ var noLetConstInExpression = {
411
488
  }
412
489
  };
413
490
 
491
+ // ../east-diagnostics/dist/src/east-ir.js
492
+ function chainRootReceiver(node, ctx) {
493
+ const t = ctx.ts;
494
+ let root = node;
495
+ for (; ; ) {
496
+ if (t.isCallExpression(root))
497
+ root = root.expression;
498
+ else if (t.isPropertyAccessExpression(root) || t.isElementAccessExpression(root)) {
499
+ root = root.expression;
500
+ } else {
501
+ return root;
502
+ }
503
+ }
504
+ }
505
+ function bodyBuildsEastIr(body, ctx) {
506
+ const t = ctx.ts;
507
+ let found = false;
508
+ const visit = (n) => {
509
+ if (found)
510
+ return;
511
+ if (isBlockBuilderCallback(n, ctx))
512
+ return;
513
+ if (t.isCallExpression(n)) {
514
+ if (matchBlockBuilderCall(n, ctx) !== void 0 || isBlockBuilderType(ctx.checker.getTypeAtLocation(chainRootReceiver(n.expression, ctx)))) {
515
+ found = true;
516
+ return;
517
+ }
518
+ }
519
+ t.forEachChild(n, visit);
520
+ };
521
+ visit(body);
522
+ return found;
523
+ }
524
+
414
525
  // ../east-diagnostics/dist/src/rules/no-unexecuted-east-expression.js
415
526
  var NAME9 = "no-unexecuted-east-expression";
416
527
  var CODE9 = 990009;
@@ -423,16 +534,7 @@ var noUnexecutedEastExpression = {
423
534
  if (!t.isExpressionStatement(node))
424
535
  return;
425
536
  const expr = node.expression;
426
- let root = expr;
427
- for (; ; ) {
428
- if (t.isCallExpression(root)) {
429
- root = root.expression;
430
- } else if (t.isPropertyAccessExpression(root) || t.isElementAccessExpression(root)) {
431
- root = root.expression;
432
- } else {
433
- break;
434
- }
435
- }
537
+ const root = chainRootReceiver(expr, ctx);
436
538
  if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
437
539
  return;
438
540
  if (!isEastExprType(ctx.checker.getTypeAtLocation(expr)))
@@ -509,79 +611,9 @@ var noReinlinedEastBinding = {
509
611
  }
510
612
  };
511
613
 
512
- // ../east-diagnostics/dist/src/rules/no-east-data-builder-helper.js
513
- var NAME11 = "no-east-data-builder-helper";
514
- var CODE11 = 990011;
515
- var VALUE_CONSTRUCTORS = /* @__PURE__ */ new Set(["variant", "some"]);
516
- function isEastValueConstructor(expr, t) {
517
- if (t.isCallExpression(expr)) {
518
- const callee = expr.expression;
519
- if (t.isIdentifier(callee) && VALUE_CONSTRUCTORS.has(callee.text))
520
- return true;
521
- return t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "East" && callee.name.text === "value";
522
- }
523
- return t.isIdentifier(expr) && expr.text === "none";
524
- }
525
- function returnExpressions(fn, t) {
526
- if (fn.body === void 0)
527
- return [];
528
- if (!t.isBlock(fn.body))
529
- return [fn.body];
530
- const out = [];
531
- const visit = (n) => {
532
- if (t.isFunctionDeclaration(n) || t.isFunctionExpression(n) || t.isArrowFunction(n))
533
- return;
534
- if (t.isReturnStatement(n) && n.expression !== void 0)
535
- out.push(n.expression);
536
- t.forEachChild(n, visit);
537
- };
538
- t.forEachChild(fn.body, visit);
539
- return out;
540
- }
541
- function isBuilderFunction(fn, ctx) {
542
- const t = ctx.ts;
543
- const first = fn.parameters[0];
544
- if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name))) {
545
- return false;
546
- }
547
- const returns = returnExpressions(fn, t);
548
- return returns.length > 0 && returns.every((r) => isEastValueConstructor(r, t));
549
- }
550
- var noEastDataBuilderHelper = {
551
- name: NAME11,
552
- code: CODE11,
553
- description: "Flag a TS helper whose only job is to return a hand-built East value (variant/some/none/East.value) \u2014 inline it or make it a real East.function.",
554
- check(node, ctx) {
555
- const t = ctx.ts;
556
- let fn;
557
- let reportNode;
558
- if (t.isFunctionDeclaration(node) && node.body !== void 0) {
559
- fn = node;
560
- reportNode = node.name ?? node;
561
- } else if (t.isVariableDeclaration(node) && node.initializer !== void 0 && (t.isArrowFunction(node.initializer) || t.isFunctionExpression(node.initializer))) {
562
- fn = node.initializer;
563
- reportNode = node.name;
564
- }
565
- if (fn === void 0 || reportNode === void 0)
566
- return;
567
- if (!isBuilderFunction(fn, ctx))
568
- return;
569
- const sf = ctx.sourceFile;
570
- const start = reportNode.getStart(sf);
571
- ctx.report({
572
- ruleName: NAME11,
573
- code: CODE11,
574
- start,
575
- length: reportNode.getEnd() - start,
576
- messageText: "This helper just returns a hand-built East value (`variant`/`some`/`none`/`East.value`), so it is an authoring-time macro, not a real East function. Inline the constructor at each call site (repetition is welcome), or make it a real `East.function` if you need a reusable East computation.",
577
- category: "warning"
578
- });
579
- }
580
- };
581
-
582
614
  // ../east-diagnostics/dist/src/rules/prefer-jsx-over-factory-call.js
583
- var NAME12 = "prefer-jsx-over-factory-call";
584
- var CODE12 = 990012;
615
+ var NAME11 = "prefer-jsx-over-factory-call";
616
+ var CODE11 = 990012;
585
617
  var jsxElementCache = /* @__PURE__ */ new WeakMap();
586
618
  function jsxElementType(ctx) {
587
619
  const cached = jsxElementCache.get(ctx.sourceFile);
@@ -647,8 +679,8 @@ function sameType(a, b, checker) {
647
679
  return c.isTypeAssignableTo(a, b) && c.isTypeAssignableTo(b, a);
648
680
  }
649
681
  var preferJsxOverFactoryCall = {
650
- name: NAME12,
651
- code: CODE12,
682
+ name: NAME11,
683
+ code: CODE11,
652
684
  description: "In a .tsx file, prefer the <Foo> JSX tag over a factory's Foo.Root(...) when the call produces a JSX element.",
653
685
  check(node, ctx) {
654
686
  const t = ctx.ts;
@@ -680,8 +712,8 @@ var preferJsxOverFactoryCall = {
680
712
  const sf = ctx.sourceFile;
681
713
  const start = callee.getStart(sf);
682
714
  ctx.report({
683
- ruleName: NAME12,
684
- code: CODE12,
715
+ ruleName: NAME11,
716
+ code: CODE11,
685
717
  start,
686
718
  length: callee.getEnd() - start,
687
719
  messageText: `Author this with the \`<${tagName}>\` JSX tag instead of \`${factoryIdent.text}.Root(...)\` \u2014 in a .tsx file the JSX tag is the authoring surface (the call already produces a JSX element).`,
@@ -691,8 +723,8 @@ var preferJsxOverFactoryCall = {
691
723
  };
692
724
 
693
725
  // ../east-diagnostics/dist/src/rules/no-untracked-east-data.js
694
- var NAME13 = "no-untracked-east-data";
695
- var CODE13 = 990013;
726
+ var NAME12 = "no-untracked-east-data";
727
+ var CODE12 = 990013;
696
728
  function plainLiteralInitializer(decl, t) {
697
729
  const init2 = decl.initializer;
698
730
  if (init2 === void 0)
@@ -704,8 +736,8 @@ function plainLiteralInitializer(decl, t) {
704
736
  return void 0;
705
737
  }
706
738
  var noUntrackedEastData = {
707
- name: NAME13,
708
- code: CODE13,
739
+ name: NAME12,
740
+ code: CODE12,
709
741
  description: "Inside East blocks, bind data consumed in East-typed positions with $.const/$.let, not a bare JS const.",
710
742
  check(node, ctx) {
711
743
  const t = ctx.ts;
@@ -732,8 +764,8 @@ var noUntrackedEastData = {
732
764
  const sf = ctx.sourceFile;
733
765
  const start = node.getStart(sf);
734
766
  ctx.report({
735
- ruleName: NAME13,
736
- code: CODE13,
767
+ ruleName: NAME12,
768
+ code: CODE12,
737
769
  start,
738
770
  length: node.getEnd() - start,
739
771
  messageText: `Bare \`const ${node.text} = \u2026\` isn't tracked by the East block builder. Bind East data with \`$.const([...], Type)\` (or \`$.let\`) so the binding carries its East type and is evaluated once.`,
@@ -742,8 +774,569 @@ var noUntrackedEastData = {
742
774
  }
743
775
  };
744
776
 
777
+ // ../east-diagnostics/dist/src/rules/no-compile-time-data-injection.js
778
+ var NAME13 = "no-compile-time-data-injection";
779
+ var CODE13 = 990015;
780
+ var FS_MODULES = /* @__PURE__ */ new Set(["node:fs", "fs", "node:fs/promises", "fs/promises"]);
781
+ function fire(ctx, target, messageText) {
782
+ const sf = ctx.sourceFile;
783
+ const start = target.getStart(sf);
784
+ ctx.report({ ruleName: NAME13, code: CODE13, start, length: target.getEnd() - start, messageText, category: "warning" });
785
+ }
786
+ function importOfSymbol(sym, t) {
787
+ for (const d of sym?.declarations ?? []) {
788
+ let n = d;
789
+ if (t.isImportSpecifier(n))
790
+ n = n.parent.parent.parent;
791
+ else if (t.isNamespaceImport(n))
792
+ n = n.parent.parent;
793
+ else if (t.isImportClause(n))
794
+ n = n.parent;
795
+ else
796
+ continue;
797
+ if (t.isImportDeclaration(n))
798
+ return n;
799
+ }
800
+ return void 0;
801
+ }
802
+ function resolvesToFsImport(id, ctx) {
803
+ const t = ctx.ts;
804
+ const imp = importOfSymbol(ctx.checker.getSymbolAtLocation(id), t);
805
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && FS_MODULES.has(imp.moduleSpecifier.text);
806
+ }
807
+ function isProcessEnv(node, t) {
808
+ return t.isPropertyAccessExpression(node) && t.isIdentifier(node.expression) && node.expression.text === "process" && node.name.text === "env";
809
+ }
810
+ var noCompileTimeDataInjection = {
811
+ name: NAME13,
812
+ code: CODE13,
813
+ description: "Flag build-time data ingestion (a node:fs import or call, JSON.parse, process.env) at module scope \u2014 load data at runtime via e3.input / datasets / platform tasks.",
814
+ check(node, ctx) {
815
+ const t = ctx.ts;
816
+ if (!importsEastPackage(ctx.sourceFile, t))
817
+ return;
818
+ if (t.isImportDeclaration(node)) {
819
+ const spec = node.moduleSpecifier;
820
+ if (t.isStringLiteral(spec) && FS_MODULES.has(spec.text)) {
821
+ fire(ctx, node, `Importing \`${spec.text}\` into East/e3 source bakes build-time file I/O into the deployed program. Read data at runtime via \`e3.input\` / a dataset, or an \`east-node-io\` platform task.`);
822
+ }
823
+ return;
824
+ }
825
+ if (insideBlockScope(node, ctx))
826
+ return;
827
+ if (isProcessEnv(node, t)) {
828
+ fire(ctx, node, "Reading `process.env` at module scope couples the deployed program to its build environment. Make it an `e3.input` / dataset parameter.");
829
+ return;
830
+ }
831
+ if (!t.isCallExpression(node))
832
+ return;
833
+ const callee = node.expression;
834
+ const base = t.isIdentifier(callee) ? callee : t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) ? callee.expression : void 0;
835
+ if (base !== void 0 && resolvesToFsImport(base, ctx)) {
836
+ fire(ctx, node, "This `node:fs` call reads/probes the filesystem at build/deploy time and bakes the result into the program. Ingest at runtime via `e3.input` / a dataset / an `east-node-io` task.");
837
+ return;
838
+ }
839
+ if (t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "JSON" && callee.name.text === "parse") {
840
+ fire(ctx, node, "`JSON.parse(...)` at module scope bakes parsed data into the program. Load it at runtime via `e3.input` / a dataset.");
841
+ }
842
+ }
843
+ };
844
+
845
+ // ../east-diagnostics/dist/src/rules/no-compile-time-seed-data.js
846
+ var NAME14 = "no-compile-time-seed-data";
847
+ var CODE14 = 990021;
848
+ function fire2(ctx, target, messageText) {
849
+ const sf = ctx.sourceFile;
850
+ const start = target.getStart(sf);
851
+ ctx.report({ ruleName: NAME14, code: CODE14, start, length: target.getEnd() - start, messageText, category: "warning" });
852
+ }
853
+ function importDeclOfSymbol(sym, t) {
854
+ for (const d of sym?.declarations ?? []) {
855
+ let n = d;
856
+ if (t.isImportSpecifier(n))
857
+ n = n.parent.parent.parent;
858
+ else if (t.isNamespaceImport(n))
859
+ n = n.parent.parent;
860
+ else if (t.isImportClause(n))
861
+ n = n.parent;
862
+ else
863
+ continue;
864
+ if (t.isImportDeclaration(n))
865
+ return n;
866
+ }
867
+ return void 0;
868
+ }
869
+ function resolvesToEastImport(id, ctx) {
870
+ const t = ctx.ts;
871
+ const imp = importDeclOfSymbol(ctx.checker.getSymbolAtLocation(id), t);
872
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text.startsWith("@elaraai/");
873
+ }
874
+ function isE3InputCall(node, ctx) {
875
+ const t = ctx.ts;
876
+ const callee = node.expression;
877
+ if (!t.isPropertyAccessExpression(callee) || callee.name.text !== "input")
878
+ return false;
879
+ if (!t.isIdentifier(callee.expression))
880
+ return false;
881
+ const imp = importDeclOfSymbol(ctx.checker.getSymbolAtLocation(callee.expression), t);
882
+ return imp !== void 0 && t.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === "@elaraai/e3";
883
+ }
884
+ function rootIdentifier(node, t) {
885
+ let cur = node;
886
+ for (; ; ) {
887
+ if (t.isPropertyAccessExpression(cur) || t.isElementAccessExpression(cur))
888
+ cur = cur.expression;
889
+ else if (t.isCallExpression(cur))
890
+ cur = cur.expression;
891
+ else
892
+ break;
893
+ }
894
+ return t.isIdentifier(cur) ? cur : void 0;
895
+ }
896
+ var VALUE_CTORS = /* @__PURE__ */ new Set([
897
+ "Map",
898
+ "Set",
899
+ "Date",
900
+ "ArrayBuffer",
901
+ "Uint8Array",
902
+ "Int8Array",
903
+ "Uint8ClampedArray",
904
+ "Int16Array",
905
+ "Uint16Array",
906
+ "Int32Array",
907
+ "Uint32Array",
908
+ "Float32Array",
909
+ "Float64Array",
910
+ "BigInt64Array",
911
+ "BigUint64Array"
912
+ ]);
913
+ function embedsHostComputation(expr, ctx) {
914
+ const t = ctx.ts;
915
+ let bad = false;
916
+ const visit = (n) => {
917
+ if (bad)
918
+ return;
919
+ if (t.isCallExpression(n)) {
920
+ const root = rootIdentifier(n.expression, t);
921
+ if (root === void 0 || !resolvesToEastImport(root, ctx)) {
922
+ bad = true;
923
+ return;
924
+ }
925
+ } else if (t.isNewExpression(n)) {
926
+ const ctor = n.expression;
927
+ const ok = t.isIdentifier(ctor) && (VALUE_CTORS.has(ctor.text) || resolvesToEastImport(ctor, ctx));
928
+ if (!ok) {
929
+ bad = true;
930
+ return;
931
+ }
932
+ }
933
+ t.forEachChild(n, visit);
934
+ };
935
+ visit(expr);
936
+ return bad;
937
+ }
938
+ var MUTATORS = /* @__PURE__ */ new Set(["set", "add", "push", "unshift", "splice", "delete", "clear", "fill", "sort", "copyWithin", "pop", "shift"]);
939
+ function isAssignmentOp(kind, t) {
940
+ const k = t.SyntaxKind;
941
+ return kind === k.EqualsToken || kind === k.PlusEqualsToken || kind === k.MinusEqualsToken || kind === k.AsteriskEqualsToken || kind === k.SlashEqualsToken || kind === k.PercentEqualsToken || kind === k.AmpersandEqualsToken || kind === k.BarEqualsToken || kind === k.CaretEqualsToken || kind === k.LessThanLessThanEqualsToken || kind === k.GreaterThanGreaterThanEqualsToken || kind === k.GreaterThanGreaterThanGreaterThanEqualsToken || kind === k.AsteriskAsteriskEqualsToken || kind === k.QuestionQuestionEqualsToken || kind === k.BarBarEqualsToken || kind === k.AmpersandAmpersandEqualsToken;
942
+ }
943
+ function insideLoop(node, t) {
944
+ let cur = node.parent;
945
+ while (cur !== void 0) {
946
+ if (t.isForStatement(cur) || t.isForOfStatement(cur) || t.isForInStatement(cur) || t.isWhileStatement(cur) || t.isDoStatement(cur)) {
947
+ return true;
948
+ }
949
+ cur = cur.parent;
950
+ }
951
+ return false;
952
+ }
953
+ function isHostFilled(sym, ctx) {
954
+ const t = ctx.ts;
955
+ let filled = false;
956
+ const isSym = (n) => t.isIdentifier(n) && ctx.checker.getSymbolAtLocation(n) === sym;
957
+ const visit = (n) => {
958
+ if (filled)
959
+ return;
960
+ if (t.isCallExpression(n) && t.isPropertyAccessExpression(n.expression) && MUTATORS.has(n.expression.name.text) && isSym(n.expression.expression)) {
961
+ if (insideLoop(n, t) || n.arguments.some((a) => embedsHostComputation(a, ctx))) {
962
+ filled = true;
963
+ return;
964
+ }
965
+ }
966
+ if (t.isBinaryExpression(n) && isAssignmentOp(n.operatorToken.kind, t)) {
967
+ const root = rootIdentifier(n.left, t);
968
+ if (root !== void 0 && isSym(root) && (insideLoop(n, t) || embedsHostComputation(n.right, ctx))) {
969
+ filled = true;
970
+ return;
971
+ }
972
+ }
973
+ t.forEachChild(n, visit);
974
+ };
975
+ visit(ctx.sourceFile);
976
+ return filled;
977
+ }
978
+ var noCompileTimeSeedData = {
979
+ name: NAME14,
980
+ code: CODE14,
981
+ description: "Flag host-computed data passed as the seed (3rd arg) of e3.input \u2014 the default must be a small authored constant; load real data at runtime.",
982
+ check(node, ctx) {
983
+ const t = ctx.ts;
984
+ if (!t.isCallExpression(node) || !isE3InputCall(node, ctx))
985
+ return;
986
+ if (insideBlockScope(node, ctx))
987
+ return;
988
+ const seedArg = node.arguments[2];
989
+ if (seedArg === void 0)
990
+ return;
991
+ let expr = seedArg;
992
+ let sym;
993
+ if (t.isIdentifier(seedArg)) {
994
+ sym = ctx.checker.getSymbolAtLocation(seedArg);
995
+ const decl = sym?.valueDeclaration;
996
+ if (decl === void 0 || !t.isVariableDeclaration(decl) || decl.initializer === void 0)
997
+ return;
998
+ expr = decl.initializer;
999
+ }
1000
+ while (t.isAsExpression(expr) || t.isSatisfiesExpression(expr) || t.isParenthesizedExpression(expr)) {
1001
+ expr = expr.expression;
1002
+ }
1003
+ const hostComputed = embedsHostComputation(expr, ctx);
1004
+ const hostFilled = sym !== void 0 && isHostFilled(sym, ctx);
1005
+ if (!hostComputed && !hostFilled)
1006
+ return;
1007
+ const nameArg = node.arguments[0];
1008
+ const name = nameArg !== void 0 && t.isStringLiteralLike(nameArg) ? nameArg.text : "\u2026";
1009
+ const reason = hostFilled ? "this seed is an authored-empty collection then filled in place by host code (a `for`-loop / `.set(...)`)" : "this seed is assembled by host calls (`num(...)`, `BigInt(...)`, parsed config) at module-evaluation time";
1010
+ fire2(ctx, seedArg, `Host-computed data passed as the \`e3.input("${name}", \u2026)\` seed bakes a build-time snapshot into the deployed program \u2014 ${reason}. The default (3rd arg) must be a small AUTHORED CONSTANT (a literal, an empty/literal Map/Set/array/struct, or an East value \`variant\`/\`some\`/\`none\`/\`East.value\`) or omitted. Load real/bulk data at RUNTIME: put the bytes in a \`BlobType\` input and parse with \`blob.decodeCsv(...)\` inside an \`e3.task\`, read files in a task via a platform \`FileSystem.readFile\`, or use \`e3.record(...)\` + \`e3.mutation\` for set-once root state.`);
1011
+ }
1012
+ };
1013
+
1014
+ // ../east-diagnostics/dist/src/rules/no-host-in-east-block.js
1015
+ var NAME15 = "no-host-in-east-block";
1016
+ var CODE15 = 990020;
1017
+ function resolvesToEastImport2(id, ctx) {
1018
+ const t = ctx.ts;
1019
+ const sym = ctx.checker.getSymbolAtLocation(id);
1020
+ for (const d of sym?.declarations ?? []) {
1021
+ let n = d;
1022
+ if (t.isImportSpecifier(n))
1023
+ n = n.parent.parent.parent;
1024
+ else if (t.isNamespaceImport(n))
1025
+ n = n.parent.parent;
1026
+ else if (t.isImportClause(n))
1027
+ n = n.parent;
1028
+ else
1029
+ continue;
1030
+ if (t.isImportDeclaration(n) && t.isStringLiteral(n.moduleSpecifier) && n.moduleSpecifier.text.startsWith("@elaraai/")) {
1031
+ return true;
1032
+ }
1033
+ }
1034
+ return false;
1035
+ }
1036
+ function resolvesToInBlockEastBinding(id, ctx) {
1037
+ const t = ctx.ts;
1038
+ const sym = ctx.checker.getSymbolAtLocation(id);
1039
+ for (const d of sym?.declarations ?? []) {
1040
+ if (t.isFunctionDeclaration(d) && d.body !== void 0 && insideBlockScope(d, ctx))
1041
+ return true;
1042
+ if (t.isVariableDeclaration(d) && d.initializer !== void 0 && (t.isArrowFunction(d.initializer) || t.isFunctionExpression(d.initializer)) && insideBlockScope(d, ctx)) {
1043
+ return true;
1044
+ }
1045
+ if (t.isParameter(d)) {
1046
+ const fn = d.parent;
1047
+ if ((t.isArrowFunction(fn) || t.isFunctionExpression(fn) || t.isFunctionDeclaration(fn)) && insideBlockScope(fn, ctx)) {
1048
+ const first = fn.parameters[0];
1049
+ if (first === void 0 || !isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
1050
+ return true;
1051
+ }
1052
+ }
1053
+ }
1054
+ return false;
1055
+ }
1056
+ function isEastCall(call, ctx) {
1057
+ const t = ctx.ts;
1058
+ const f = call.expression;
1059
+ if (isEastExprType(ctx.checker.getTypeAtLocation(f)))
1060
+ return true;
1061
+ const root = chainRootReceiver(f, ctx);
1062
+ if (isBlockBuilderType(ctx.checker.getTypeAtLocation(root)))
1063
+ return true;
1064
+ if (t.isPropertyAccessExpression(f) && isEastExprType(ctx.checker.getTypeAtLocation(f.expression)))
1065
+ return true;
1066
+ if (t.isIdentifier(root) && resolvesToEastImport2(root, ctx))
1067
+ return true;
1068
+ if (t.isPropertyAccessExpression(f) && t.isIdentifier(root) && resolvesToInBlockEastBinding(root, ctx))
1069
+ return true;
1070
+ return false;
1071
+ }
1072
+ function isEast(expr, ctx) {
1073
+ return isEastExprType(ctx.checker.getTypeAtLocation(expr));
1074
+ }
1075
+ function insideJsx(node, t) {
1076
+ let cur = node.parent;
1077
+ while (cur !== void 0) {
1078
+ if (t.isJsxElement(cur) || t.isJsxSelfClosingElement(cur) || t.isJsxFragment(cur) || t.isJsxExpression(cur) || t.isJsxAttribute(cur)) {
1079
+ return true;
1080
+ }
1081
+ cur = cur.parent;
1082
+ }
1083
+ return false;
1084
+ }
1085
+ function isJsx(node, t) {
1086
+ return t.isJsxElement(node) || t.isJsxFragment(node) || t.isJsxSelfClosingElement(node) || t.isParenthesizedExpression(node) && isJsx(node.expression, t);
1087
+ }
1088
+ function returnExpressions(fn, t) {
1089
+ if (fn.body === void 0)
1090
+ return [];
1091
+ if (!t.isBlock(fn.body))
1092
+ return [fn.body];
1093
+ const out = [];
1094
+ const visit = (n) => {
1095
+ if (t.isFunctionDeclaration(n) || t.isFunctionExpression(n) || t.isArrowFunction(n))
1096
+ return;
1097
+ if (t.isReturnStatement(n) && n.expression !== void 0)
1098
+ out.push(n.expression);
1099
+ t.forEachChild(n, visit);
1100
+ };
1101
+ t.forEachChild(fn.body, visit);
1102
+ return out;
1103
+ }
1104
+ var REPORT = (ctx, target, messageText, fix) => {
1105
+ const sf = ctx.sourceFile;
1106
+ const start = target.getStart(sf);
1107
+ const length = target.getEnd() - start;
1108
+ ctx.report({
1109
+ ruleName: NAME15,
1110
+ code: CODE15,
1111
+ start,
1112
+ length,
1113
+ messageText,
1114
+ category: "warning",
1115
+ ...fix !== void 0 ? { fix: { description: fix.description, changes: [{ start, length, newText: fix.newText }] } } : {}
1116
+ });
1117
+ };
1118
+ var noHostInEastBlock = {
1119
+ name: NAME15,
1120
+ code: CODE15,
1121
+ description: "Flag host-language constructs (host calls, operators on East operands, JS control-flow, host string interpolation) inside an East block \u2014 express them in East.",
1122
+ check(node, ctx) {
1123
+ const t = ctx.ts;
1124
+ if (!insideBlockScope(node, ctx))
1125
+ return;
1126
+ if (insideJsx(node, t))
1127
+ return;
1128
+ {
1129
+ let fn;
1130
+ let reportNode;
1131
+ if (t.isFunctionDeclaration(node) && node.body !== void 0) {
1132
+ fn = node;
1133
+ reportNode = node.name ?? node;
1134
+ } else if (t.isVariableDeclaration(node) && node.initializer !== void 0 && (t.isArrowFunction(node.initializer) || t.isFunctionExpression(node.initializer))) {
1135
+ fn = node.initializer;
1136
+ reportNode = node.name;
1137
+ }
1138
+ if (fn !== void 0 && reportNode !== void 0) {
1139
+ const first = fn.parameters[0];
1140
+ if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
1141
+ return;
1142
+ if (returnExpressions(fn, t).some((r) => isJsx(r, t)))
1143
+ return;
1144
+ REPORT(ctx, reportNode, "TS closure/function declared inside an East block \u2014 an authoring-time macro (it can't be serialized or recursed and expands inline at each call). Make it a real `East.function` (`$.const(East.function(...))`) or inline it.");
1145
+ return;
1146
+ }
1147
+ }
1148
+ if (t.isForStatement(node) || t.isWhileStatement(node) || t.isForOfStatement(node)) {
1149
+ if (t.isForOfStatement(node) && isEast(node.expression, ctx))
1150
+ return;
1151
+ if (!bodyBuildsEastIr(node.statement, ctx))
1152
+ return;
1153
+ REPORT(ctx, node.getChildAt(0, ctx.sourceFile), "Host loop building East IR \u2014 bind the data with `$.const([...], ArrayType(...))` and use an East collection op (`data.map(($, x) => \u2026)`) or `$.for(data, ($, x) => \u2026)`.");
1154
+ return;
1155
+ }
1156
+ if (t.isIfStatement(node)) {
1157
+ const emits = bodyBuildsEastIr(node.thenStatement, ctx) || node.elseStatement !== void 0 && bodyBuildsEastIr(node.elseStatement, ctx);
1158
+ if (!emits)
1159
+ return;
1160
+ REPORT(ctx, node.getChildAt(0, ctx.sourceFile), "Host `if` building East IR \u2014 use East's `$.if(cond, \u2026)` so the branch is chosen at East runtime.");
1161
+ return;
1162
+ }
1163
+ if (t.isConditionalExpression(node)) {
1164
+ if (isEast(node.condition, ctx) && isEast(node.whenTrue, ctx) && isEast(node.whenFalse, ctx)) {
1165
+ const sf = ctx.sourceFile;
1166
+ REPORT(ctx, node, "Host `?:` selecting between East values \u2014 use `cond.ifElse(() => a, () => b)`.", {
1167
+ description: "Rewrite as cond.ifElse(...)",
1168
+ newText: `(${node.condition.getText(sf)}).ifElse(() => ${node.whenTrue.getText(sf)}, () => ${node.whenFalse.getText(sf)})`
1169
+ });
1170
+ }
1171
+ return;
1172
+ }
1173
+ if (t.isBinaryExpression(node)) {
1174
+ const op = node.operatorToken.kind;
1175
+ const k = t.SyntaxKind;
1176
+ const logical = op === k.AmpersandAmpersandToken || op === k.BarBarToken;
1177
+ const arith = op === k.PlusToken || op === k.MinusToken || op === k.AsteriskToken || op === k.SlashToken || op === k.PercentToken || op === k.EqualsEqualsEqualsToken || op === k.ExclamationEqualsEqualsToken || op === k.EqualsEqualsToken || op === k.LessThanToken || op === k.LessThanEqualsToken || op === k.GreaterThanToken || op === k.GreaterThanEqualsToken;
1178
+ if (logical && isEast(node.left, ctx) && isEast(node.right, ctx)) {
1179
+ REPORT(ctx, node, "Host `&&`/`||` on East booleans \u2014 use East's `.and(() => \u2026)` / `.or(() => \u2026)`.");
1180
+ } else if (arith && (isEast(node.left, ctx) || isEast(node.right, ctx))) {
1181
+ REPORT(ctx, node, "Host operator on an East value \u2014 use the East method (`.add`/`.subtract`/`.multiply`/`.divide`) or `East.equal`/`East.less`/`East.greater`.");
1182
+ }
1183
+ return;
1184
+ }
1185
+ if (t.isPrefixUnaryExpression(node) && (node.operator === t.SyntaxKind.MinusToken || node.operator === t.SyntaxKind.ExclamationToken)) {
1186
+ if (isEast(node.operand, ctx)) {
1187
+ REPORT(ctx, node, "Host unary operator on an East value \u2014 use `.negate()` / `East.not`.");
1188
+ }
1189
+ return;
1190
+ }
1191
+ if (t.isElementAccessExpression(node)) {
1192
+ if (isEast(node.expression, ctx))
1193
+ return;
1194
+ REPORT(ctx, node, "Host index access on a JS value inside an East block \u2014 model the data as an East collection and read it with `.get(...)` / East ops, not `[i]`.");
1195
+ return;
1196
+ }
1197
+ if (t.isTemplateExpression(node) && !(node.parent !== void 0 && t.isTaggedTemplateExpression(node.parent))) {
1198
+ REPORT(ctx, node, "Host string interpolation inside an East block \u2014 build the string in East with `East.str`\u2026`` (or `str`\u2026``).");
1199
+ return;
1200
+ }
1201
+ if (t.isCallExpression(node)) {
1202
+ if (isEastCall(node, ctx))
1203
+ return;
1204
+ const callee = node.expression;
1205
+ const KEY_ACCESSORS = /* @__PURE__ */ new Set(["get", "tryGet", "has", "insert", "insertOrUpdate", "update", "remove"]);
1206
+ REPORT(ctx, node, t.isPropertyAccessExpression(callee) && KEY_ACCESSORS.has(callee.name.text) ? "Host call inside an East block \u2014 make it a real `East.function` (`$.const(East.function(...))`) or inline it as East." : "Host call inside an East block \u2014 this is an authoring-time macro over East. Make it a real `East.function` (`$.const(East.function(...))`), inline it as East, or use the East stdlib.");
1207
+ }
1208
+ }
1209
+ };
1210
+
1211
+ // ../east-diagnostics/dist/src/rules/no-module-scope-east-macro.js
1212
+ var NAME16 = "no-module-scope-east-macro";
1213
+ var CODE16 = 990011;
1214
+ var VALUE_CONSTRUCTORS = /* @__PURE__ */ new Set(["variant", "some"]);
1215
+ function unparen(e, t) {
1216
+ let cur = e;
1217
+ while (t.isParenthesizedExpression(cur))
1218
+ cur = cur.expression;
1219
+ return cur;
1220
+ }
1221
+ function isJsx2(node, t) {
1222
+ return t.isJsxElement(node) || t.isJsxFragment(node) || t.isJsxSelfClosingElement(node) || t.isParenthesizedExpression(node) && isJsx2(node.expression, t);
1223
+ }
1224
+ function isHostTemplate(e, t) {
1225
+ return t.isTemplateExpression(unparen(e, t));
1226
+ }
1227
+ function isEastValueConstructor(expr, t) {
1228
+ if (t.isCallExpression(expr)) {
1229
+ const callee = expr.expression;
1230
+ if (t.isIdentifier(callee) && VALUE_CONSTRUCTORS.has(callee.text))
1231
+ return true;
1232
+ return t.isPropertyAccessExpression(callee) && t.isIdentifier(callee.expression) && callee.expression.text === "East" && callee.name.text === "value";
1233
+ }
1234
+ return t.isIdentifier(expr) && expr.text === "none";
1235
+ }
1236
+ function isEastBuilderCall(call, ctx) {
1237
+ const t = ctx.ts;
1238
+ const callee = call.expression;
1239
+ if (t.isIdentifier(callee) && VALUE_CONSTRUCTORS.has(callee.text))
1240
+ return true;
1241
+ const root = chainRootReceiver(callee, ctx);
1242
+ if (t.isIdentifier(root) && root.text === "East")
1243
+ return true;
1244
+ return isBlockBuilderType(ctx.checker.getTypeAtLocation(root));
1245
+ }
1246
+ function containsEastBuilder(expr, ctx) {
1247
+ const t = ctx.ts;
1248
+ let found = false;
1249
+ const visit = (n) => {
1250
+ if (found)
1251
+ return;
1252
+ if (t.isCallExpression(n) && isEastBuilderCall(n, ctx)) {
1253
+ found = true;
1254
+ return;
1255
+ }
1256
+ t.forEachChild(n, visit);
1257
+ };
1258
+ visit(expr);
1259
+ return found;
1260
+ }
1261
+ function returnBuildsEast(r, ctx) {
1262
+ const t = ctx.ts;
1263
+ if (isJsx2(r, t))
1264
+ return false;
1265
+ if (isEastValueConstructor(r, t))
1266
+ return true;
1267
+ if (isEastExprType(ctx.checker.getTypeAtLocation(r)))
1268
+ return true;
1269
+ const root = chainRootReceiver(r, ctx);
1270
+ const rootType = ctx.checker.getTypeAtLocation(root);
1271
+ if (isEastExprType(rootType) || isBlockBuilderType(rootType))
1272
+ return true;
1273
+ return containsEastBuilder(r, ctx);
1274
+ }
1275
+ function returnExpressions2(fn, t) {
1276
+ if (fn.body === void 0)
1277
+ return [];
1278
+ if (!t.isBlock(fn.body))
1279
+ return [fn.body];
1280
+ const out = [];
1281
+ const visit = (n) => {
1282
+ if (t.isFunctionDeclaration(n) || t.isFunctionExpression(n) || t.isArrowFunction(n))
1283
+ return;
1284
+ if (t.isReturnStatement(n) && n.expression !== void 0)
1285
+ out.push(n.expression);
1286
+ t.forEachChild(n, visit);
1287
+ };
1288
+ t.forEachChild(fn.body, visit);
1289
+ return out;
1290
+ }
1291
+ var noModuleScopeEastMacro = {
1292
+ name: NAME16,
1293
+ code: CODE16,
1294
+ description: "Flag a module-scope TS helper that builds East values/IR or a composite string key \u2014 make it a real East.function or model typed/nested East data.",
1295
+ check(node, ctx) {
1296
+ const t = ctx.ts;
1297
+ if (!importsEastPackage(ctx.sourceFile, t))
1298
+ return;
1299
+ let fn;
1300
+ let reportNode;
1301
+ if (t.isFunctionDeclaration(node) && node.body !== void 0) {
1302
+ fn = node;
1303
+ reportNode = node.name ?? node;
1304
+ } else if (t.isVariableDeclaration(node) && node.initializer !== void 0 && (t.isArrowFunction(node.initializer) || t.isFunctionExpression(node.initializer))) {
1305
+ fn = node.initializer;
1306
+ reportNode = node.name;
1307
+ }
1308
+ if (fn === void 0 || reportNode === void 0)
1309
+ return;
1310
+ if (insideBlockScope(fn, ctx))
1311
+ return;
1312
+ const first = fn.parameters[0];
1313
+ if (first !== void 0 && isBlockBuilderType(ctx.checker.getTypeAtLocation(first.name)))
1314
+ return;
1315
+ const rs = returnExpressions2(fn, t);
1316
+ if (rs.some((r) => isJsx2(r, t)))
1317
+ return;
1318
+ if (rs.length === 0)
1319
+ return;
1320
+ const everyBuildsEast = rs.every((r) => returnBuildsEast(r, ctx));
1321
+ const everyHostKey = rs.every((r) => isHostTemplate(r, t));
1322
+ if (!everyBuildsEast && !everyHostKey)
1323
+ return;
1324
+ const sf = ctx.sourceFile;
1325
+ const start = reportNode.getStart(sf);
1326
+ ctx.report({
1327
+ ruleName: NAME16,
1328
+ code: CODE16,
1329
+ start,
1330
+ length: reportNode.getEnd() - start,
1331
+ messageText: everyHostKey ? "This helper builds a composite string key from a host template literal \u2014 the signature of a string-keyed data model. Model the data with typed keys / nested East structures instead." : "This module-scope TS helper builds East values/IR \u2014 an authoring-time macro that expands inline and can't be serialized. Make it a real `East.function`, or inline it.",
1332
+ category: "warning"
1333
+ });
1334
+ }
1335
+ };
1336
+
745
1337
  // ../east-diagnostics/dist/src/rules/index.js
746
1338
  var allRules = [
1339
+ // East-side idiom hygiene (original set)
747
1340
  noRedundantEastCast,
748
1341
  preferExplicitEastType,
749
1342
  preferSomeNone,
@@ -754,9 +1347,15 @@ var allRules = [
754
1347
  noLetConstInExpression,
755
1348
  noUnexecutedEastExpression,
756
1349
  noReinlinedEastBinding,
757
- noEastDataBuilderHelper,
758
1350
  preferJsxOverFactoryCall,
759
- noUntrackedEastData
1351
+ noUntrackedEastData,
1352
+ // host-vs-East family: the general block rule + the module-scope macro rule,
1353
+ // plus the separate build-time-data concerns (ingestion primitives, and
1354
+ // host-computed e3.input seed data)
1355
+ noHostInEastBlock,
1356
+ noModuleScopeEastMacro,
1357
+ noCompileTimeDataInjection,
1358
+ noCompileTimeSeedData
760
1359
  ];
761
1360
 
762
1361
  // ../east-diagnostics/dist/src/run.js
@@ -783,7 +1382,7 @@ function runEastRules(tsModule, program, sourceFile, checker, options = {}, rule
783
1382
 
784
1383
  // ../east-diagnostics/dist/src/east-module.js
785
1384
  var import_node_module = require("node:module");
786
- var import_node_path = require("node:path");
1385
+ var import_node_path2 = require("node:path");
787
1386
  var import_node_url = require("node:url");
788
1387
  var cache = /* @__PURE__ */ new Map();
789
1388
  var pendingImports = /* @__PURE__ */ new Set();
@@ -804,7 +1403,7 @@ function getEastModule(projectDir) {
804
1403
  const cached = cache.get(projectDir);
805
1404
  if (cached !== void 0)
806
1405
  return cached ?? void 0;
807
- const require_ = (0, import_node_module.createRequire)((0, import_node_path.join)(projectDir, "_.js"));
1406
+ const require_ = (0, import_node_module.createRequire)((0, import_node_path2.join)(projectDir, "_.js"));
808
1407
  let entry;
809
1408
  try {
810
1409
  entry = require_.resolve("@elaraai/east");
@@ -1173,25 +1772,6 @@ var CATEGORY = {
1173
1772
  warning: "Warning",
1174
1773
  suggestion: "Suggestion"
1175
1774
  };
1176
- function isElaraaiPackageSrc(filePath) {
1177
- const file = (0, import_node_path2.resolve)(filePath);
1178
- let dir = (0, import_node_path2.dirname)(file);
1179
- for (; ; ) {
1180
- const candidate = (0, import_node_path2.join)(dir, "package.json");
1181
- if ((0, import_node_fs.existsSync)(candidate)) {
1182
- try {
1183
- const name = JSON.parse((0, import_node_fs.readFileSync)(candidate, "utf-8")).name;
1184
- return typeof name === "string" && name.startsWith("@elaraai/") && file.startsWith((0, import_node_path2.join)(dir, "src") + "/");
1185
- } catch {
1186
- return false;
1187
- }
1188
- }
1189
- const parent = (0, import_node_path2.dirname)(dir);
1190
- if (parent === dir)
1191
- return false;
1192
- dir = parent;
1193
- }
1194
- }
1195
1775
  function init(modules) {
1196
1776
  const t = modules.typescript;
1197
1777
  return {
@@ -1216,19 +1796,17 @@ function init(modules) {
1216
1796
  const rewritten = rewriteEastAssignability(t, program, sourceFile, d, east);
1217
1797
  return rewritten === void 0 ? d : { ...d, messageText: rewritten };
1218
1798
  });
1219
- if (!isElaraaiPackageSrc(fileName)) {
1220
- const ruleDiagnostics = runEastRules(t, program, sourceFile, program.getTypeChecker(), info.config?.disabled !== void 0 ? { disabled: info.config.disabled } : {});
1221
- for (const d of ruleDiagnostics) {
1222
- diagnostics.push({
1223
- file: sourceFile,
1224
- start: d.start,
1225
- length: d.length,
1226
- messageText: `${d.messageText} (${d.ruleName})`,
1227
- category: t.DiagnosticCategory[CATEGORY[d.category]],
1228
- code: d.code,
1229
- source: "east"
1230
- });
1231
- }
1799
+ const ruleDiagnostics = runEastRules(t, program, sourceFile, program.getTypeChecker(), info.config?.disabled !== void 0 ? { disabled: info.config.disabled } : {});
1800
+ for (const d of ruleDiagnostics) {
1801
+ diagnostics.push({
1802
+ file: sourceFile,
1803
+ start: d.start,
1804
+ length: d.length,
1805
+ messageText: `${d.messageText} (${d.ruleName})`,
1806
+ category: t.DiagnosticCategory[CATEGORY[d.category]],
1807
+ code: d.code,
1808
+ source: "east"
1809
+ });
1232
1810
  }
1233
1811
  return diagnostics;
1234
1812
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elaraai/tsserver-plugin-east",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "description": "TypeScript language service plugin for East — East idiom diagnostics and localized East type-diff error messages as native editor squiggles.",
6
6
  "main": "dist/index.cjs",
@@ -32,8 +32,8 @@
32
32
  "devDependencies": {
33
33
  "esbuild": "^0.27.3",
34
34
  "typescript": "~5.9.2",
35
- "@elaraai/east": "1.0.14",
36
- "@elaraai/east-diagnostics": "1.0.14"
35
+ "@elaraai/east": "1.0.15",
36
+ "@elaraai/east-diagnostics": "1.0.15"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "node scripts/build.mjs",