pasika 0.10.81 → 0.10.83

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.
@@ -386,6 +386,17 @@ function parseModule(file) {
386
386
  names.add(node.name.text);
387
387
  } else if (ts.isElementAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === namespace && ts.isStringLiteral(node.argumentExpression)) {
388
388
  names.add(node.argumentExpression.text);
389
+ } else if (ts.isVariableDeclaration(node) && ts.isObjectBindingPattern(node.name) && node.initializer && ts.isIdentifier(node.initializer) && node.initializer.text === namespace) {
390
+ for (const element of node.name.elements) {
391
+ if (element.dotDotDotToken) continue;
392
+ let importedName;
393
+ if (element.propertyName) {
394
+ importedName = propertyName(element.propertyName);
395
+ } else if (ts.isIdentifier(element.name)) {
396
+ importedName = element.name.text;
397
+ }
398
+ if (importedName) names.add(importedName);
399
+ }
389
400
  }
390
401
  ts.forEachChild(node, visit);
391
402
  };
@@ -1207,6 +1218,8 @@ function isNestedInside(expectedFolder, currentFolder, componentFile) {
1207
1218
  if (!sameFolder(currentFolder.slice(0, -1), expectedFolder)) return false;
1208
1219
  const folderName = currentFolder[currentFolder.length - 1];
1209
1220
  if (!folderName) return false;
1221
+ const componentName = path10.basename(componentFile, path10.extname(componentFile));
1222
+ if (componentName !== folderName) return false;
1210
1223
  return fs3.existsSync(path10.join(path10.dirname(componentFile), `${folderName}.tsx`));
1211
1224
  }
1212
1225
  var componentPlacementRule = {
@@ -2926,7 +2939,13 @@ function parentComponentName(dirPath, folderName) {
2926
2939
  if (!fs4.existsSync(componentFile)) return void 0;
2927
2940
  try {
2928
2941
  const exports = parseModule(componentFile).exports;
2929
- return exports.find((moduleExport) => moduleExport.kind === "component")?.name;
2942
+ const classifiedComponent = exports.find((moduleExport) => moduleExport.kind === "component")?.name;
2943
+ if (classifiedComponent) return classifiedComponent;
2944
+ const normalizedFolderName = folderName.replaceAll("-", "").toLowerCase();
2945
+ const ownerExport = exports.find(
2946
+ (moduleExport) => isPascalCase4(moduleExport.name) && moduleExport.name.toLowerCase() === normalizedFolderName
2947
+ );
2948
+ return ownerExport?.name;
2930
2949
  } catch {
2931
2950
  return void 0;
2932
2951
  }
@@ -2976,7 +2995,7 @@ var enforceBarrelExportsRule = {
2976
2995
  if (nonParentExports.length > 0) {
2977
2996
  context.report({
2978
2997
  loc: { line: 1, column: 0 },
2979
- message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${parentName}" may be re-exported. See docs/next-codebase-guide/rules/folder-nesting-rule.md`
2998
+ message: `index.ts must not re-export nested internals: ${nonParentExports.join(", ")}. Only "${parentName}" may be re-exported. See docs/next-codebase-guide/rules/folder-nesting-rule.md`
2980
2999
  });
2981
3000
  }
2982
3001
  }
@@ -3801,6 +3820,24 @@ function sourceSegments(sourceRoot, absolutePath) {
3801
3820
  }
3802
3821
  return relativePath.split(path31.sep);
3803
3822
  }
3823
+ function isWithin(root, candidate) {
3824
+ const relativePath = path31.relative(root, candidate);
3825
+ return relativePath === "" || !relativePath.startsWith("..") && !path31.isAbsolute(relativePath);
3826
+ }
3827
+ function componentFolderAncestors(targetFile, sourceRoot) {
3828
+ const folders = [];
3829
+ let current = path31.dirname(targetFile);
3830
+ while (current !== sourceRoot && isWithin(sourceRoot, current)) {
3831
+ const folderName = path31.basename(current);
3832
+ if (hasComponentOwner(current, folderName) && hasExactEntry(current, "index.ts")) {
3833
+ folders.push(current);
3834
+ }
3835
+ const parent = path31.dirname(current);
3836
+ if (parent === current) break;
3837
+ current = parent;
3838
+ }
3839
+ return folders;
3840
+ }
3804
3841
  function relativeSpecifier(filename, resolvedPath) {
3805
3842
  const relativePath = path31.relative(path31.dirname(filename), resolvedPath).split(path31.sep).join("/");
3806
3843
  return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
@@ -3830,6 +3867,26 @@ var importBoundariesRule = {
3830
3867
  return;
3831
3868
  }
3832
3869
  const importPath = source.value;
3870
+ const resolvedModule = resolveSpecifier(filename, importPath, sourceRoot);
3871
+ if (resolvedModule) {
3872
+ for (const componentFolder of componentFolderAncestors(resolvedModule, sourceRoot)) {
3873
+ if (isWithin(componentFolder, filename)) continue;
3874
+ const componentEntry = path31.join(componentFolder, "index.ts");
3875
+ if (path31.resolve(resolvedModule) === path31.resolve(componentEntry)) continue;
3876
+ const entrySpecifier = prefersRelative(filename, componentFolder) ? relativeSpecifier(filename, componentFolder) : aliasSpecifier(sourceRoot, componentFolder);
3877
+ const folderLabel = `src/${path31.relative(sourceRoot, componentFolder).split(path31.sep).join("/")}/`;
3878
+ const message = [
3879
+ `Do not import "${importPath}" across the ${folderLabel} component boundary;`,
3880
+ `outside consumers may import only "${entrySpecifier}".`,
3881
+ "Move nested internals to their CCF when they need reuse."
3882
+ ].join(" ");
3883
+ context.report({
3884
+ node: source,
3885
+ message
3886
+ });
3887
+ return;
3888
+ }
3889
+ }
3833
3890
  const resolvedPath = resolveSourceImport(sourceRoot, filename, importPath);
3834
3891
  if (!resolvedPath) {
3835
3892
  return;
@@ -5044,7 +5101,7 @@ var ownershipIndexCache = /* @__PURE__ */ new WeakMap();
5044
5101
  function normalizePath(value) {
5045
5102
  return value.replaceAll("\\", "/").toLowerCase();
5046
5103
  }
5047
- function isWithin(root, file) {
5104
+ function isWithin2(root, file) {
5048
5105
  const relative = path39.relative(root, file);
5049
5106
  return relative === "" || !relative.startsWith("..") && !path39.isAbsolute(relative);
5050
5107
  }
@@ -5186,7 +5243,7 @@ var ContractOwnershipIndex = class {
5186
5243
  const normalized = normalizePath(fileName);
5187
5244
  if (/\/typescript\/lib\/lib\.[^/]+\.d\.ts$/u.test(normalized)) return "platform";
5188
5245
  if (normalized.includes("/node_modules/")) return "third-party";
5189
- if (isWithin(this.cwd, path39.resolve(fileName))) return "first-party";
5246
+ if (isWithin2(this.cwd, path39.resolve(fileName))) return "first-party";
5190
5247
  return "unknown";
5191
5248
  }
5192
5249
  schemaOwnership(declaration) {
@@ -5200,7 +5257,7 @@ var ContractOwnershipIndex = class {
5200
5257
  }
5201
5258
  indexApiContracts() {
5202
5259
  for (const sourceFile of this.program.getSourceFiles()) {
5203
- if (sourceFile.isDeclarationFile || !isWithin(this.cwd, path39.resolve(sourceFile.fileName))) continue;
5260
+ if (sourceFile.isDeclarationFile || !isWithin2(this.cwd, path39.resolve(sourceFile.fileName))) continue;
5204
5261
  const visit = (node) => {
5205
5262
  if (ts7.isCallExpression(node) && this.isDefineApiContractCall(node)) this.indexApiContractCall(node);
5206
5263
  ts7.forEachChild(node, visit);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.81",
3
+ "version": "0.10.83",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",