pasika 0.10.45 → 0.10.47

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.
@@ -3485,14 +3485,11 @@ function relativeSpecifier(filename, resolvedPath) {
3485
3485
  function aliasSpecifier(sourceRoot, resolvedPath) {
3486
3486
  return `@/${(sourceSegments(sourceRoot, resolvedPath) ?? []).join("/")}`;
3487
3487
  }
3488
- function segmentCount(specifier) {
3489
- return specifier.replace(/^@\//, "").split("/").filter((segment) => segment !== "." && segment !== "").length;
3488
+ function parentTraversalCount(specifier) {
3489
+ return specifier.split("/").filter((segment) => segment === "..").length;
3490
3490
  }
3491
- function describeSegments(count) {
3492
- return `${String(count)} segment${count === 1 ? "" : "s"}`;
3493
- }
3494
- function prefersRelative(sourceRoot, filename, resolvedPath) {
3495
- return segmentCount(relativeSpecifier(filename, resolvedPath)) <= segmentCount(aliasSpecifier(sourceRoot, resolvedPath));
3491
+ function prefersRelative(filename, resolvedPath) {
3492
+ return parentTraversalCount(relativeSpecifier(filename, resolvedPath)) <= 1;
3496
3493
  }
3497
3494
  var importBoundariesRule = {
3498
3495
  meta: {
@@ -3536,23 +3533,17 @@ var importBoundariesRule = {
3536
3533
  }
3537
3534
  const relativeForm = relativeSpecifier(filename, resolvedPath);
3538
3535
  const aliasForm = aliasSpecifier(sourceRoot, resolvedPath);
3539
- const relativeSegments = segmentCount(relativeForm);
3540
- const aliasSegments = segmentCount(aliasForm);
3541
- function describeChoice(preferred, preferredSegments, other, otherSegments) {
3542
- const tie = preferredSegments === otherSegments ? ", and a tie goes to the relative path" : "";
3543
- return `Use "${preferred}" (${describeSegments(preferredSegments)}) instead of "${other}" (${describeSegments(otherSegments)})${tie}.`;
3544
- }
3545
- if (prefersRelative(sourceRoot, filename, resolvedPath) && importPath.startsWith("@/")) {
3536
+ if (prefersRelative(filename, resolvedPath) && importPath.startsWith("@/")) {
3546
3537
  context.report({
3547
3538
  node: source,
3548
- message: describeChoice(relativeForm, relativeSegments, aliasForm, aliasSegments)
3539
+ message: `Use "${relativeForm}" instead of "${aliasForm}".`
3549
3540
  });
3550
3541
  return;
3551
3542
  }
3552
- if (!prefersRelative(sourceRoot, filename, resolvedPath) && importPath.startsWith(".")) {
3543
+ if (!prefersRelative(filename, resolvedPath) && importPath.startsWith(".")) {
3553
3544
  context.report({
3554
3545
  node: source,
3555
- message: describeChoice(aliasForm, aliasSegments, relativeForm, relativeSegments)
3546
+ message: `Use "${aliasForm}" instead of "${relativeForm}".`
3556
3547
  });
3557
3548
  }
3558
3549
  }
@@ -5184,19 +5175,82 @@ function isEnumLiteralType(node) {
5184
5175
  function isEnumLiteralUnion(node) {
5185
5176
  return node?.type === "TSUnionType" && (node.types?.length ?? 0) >= 2 && (node.types ?? []).every(isEnumLiteralType);
5186
5177
  }
5178
+ function isZodCall(node, method) {
5179
+ const { callee } = node;
5180
+ return callee?.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "z" && callee.property.type === "Identifier" && callee.property.name === method;
5181
+ }
5182
+ function propertyName2(property) {
5183
+ if (property.computed) return void 0;
5184
+ if (property.key.type === "Identifier") return property.key.name;
5185
+ if (property.key.type === "Literal" && typeof property.key.value === "string") return property.key.value;
5186
+ return void 0;
5187
+ }
5188
+ function rawZodDiscriminantLiteral(schemaCall, discriminator) {
5189
+ if (!isZodCall(schemaCall, "object")) return void 0;
5190
+ const shape = schemaCall.arguments[0];
5191
+ if (shape?.type !== "ObjectExpression") return void 0;
5192
+ for (const property of shape.properties) {
5193
+ if (property.type !== "Property" || propertyName2(property) !== discriminator) continue;
5194
+ if (property.value.type !== "CallExpression" || !isZodCall(property.value, "literal")) return void 0;
5195
+ const literal = property.value.arguments[0];
5196
+ if (literal?.type === "Literal" && (typeof literal.value === "string" || typeof literal.value === "number")) {
5197
+ return literal;
5198
+ }
5199
+ return void 0;
5200
+ }
5201
+ return void 0;
5202
+ }
5187
5203
  var preferEnumRule = {
5188
5204
  meta: {
5189
5205
  schema: [],
5190
5206
  type: "problem",
5191
5207
  docs: {
5192
- description: "Require fixed sets of named string/number values to be TypeScript enums instead of `as const` objects, literal-union aliases, or inline literal-union property types."
5208
+ description: "Require fixed sets of named string/number values to be TypeScript enums, including Zod discriminated-union discriminator values."
5193
5209
  }
5194
5210
  },
5195
5211
  create(context) {
5196
5212
  const filename = path40.resolve(context.filename);
5197
5213
  const sourceRoot = sourceRootOf(context);
5198
5214
  if (!filename.startsWith(sourceRoot + path40.sep)) return {};
5215
+ const objectSchemas = /* @__PURE__ */ new Map();
5216
+ const discriminatedUnions = [];
5217
+ const reportedDiscriminants = /* @__PURE__ */ new Set();
5199
5218
  return {
5219
+ VariableDeclarator(node) {
5220
+ const { id, init } = node;
5221
+ if (id?.type !== "Identifier" || init?.type !== "CallExpression" || !isZodCall(init, "object")) return;
5222
+ objectSchemas.set(id.name, init);
5223
+ },
5224
+ CallExpression(node) {
5225
+ if (isZodCall(node, "discriminatedUnion")) {
5226
+ discriminatedUnions.push(node);
5227
+ }
5228
+ },
5229
+ "Program:exit"() {
5230
+ for (const unionCall of discriminatedUnions) {
5231
+ const [discriminatorArg, optionsArg] = unionCall.arguments ?? [];
5232
+ if (discriminatorArg?.type !== "Literal" || typeof discriminatorArg.value !== "string" || optionsArg?.type !== "ArrayExpression") {
5233
+ continue;
5234
+ }
5235
+ for (const option of optionsArg.elements) {
5236
+ if (!option || option.type === "SpreadElement") continue;
5237
+ let schemaCall;
5238
+ if (option.type === "Identifier") {
5239
+ schemaCall = objectSchemas.get(option.name);
5240
+ } else if (option.type === "CallExpression" && isZodCall(option, "object")) {
5241
+ schemaCall = option;
5242
+ }
5243
+ if (!schemaCall) continue;
5244
+ const literal = rawZodDiscriminantLiteral(schemaCall, discriminatorArg.value);
5245
+ if (!literal || reportedDiscriminants.has(literal)) continue;
5246
+ reportedDiscriminants.add(literal);
5247
+ context.report({
5248
+ node: literal,
5249
+ message: "A Zod discriminated-union discriminator literal must use a TypeScript enum member. See docs/next-codebase-guide/rules/constants-rule.md"
5250
+ });
5251
+ }
5252
+ }
5253
+ },
5200
5254
  TSAsExpression(node) {
5201
5255
  if (!isConstAssertion(node)) return;
5202
5256
  const expression = node.expression;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.45",
3
+ "version": "0.10.47",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",