@bamboocss/extractor 1.16.1 → 1.17.1

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/dist/index.cjs CHANGED
@@ -310,6 +310,38 @@ const box = {
310
310
  const TsEvalError = Symbol("EvalError");
311
311
  const cacheMap$2 = /* @__PURE__ */ new WeakMap();
312
312
  /**
313
+ * Whether a call reaches a function declared outside this project.
314
+ *
315
+ * Passing a type checker lets the evaluator resolve an identifier to its declaration in
316
+ * another module, which is what makes a call to an imported helper resolvable at all — a
317
+ * style helper in a neighbouring file used to come back unresolvable, and for a recipe that
318
+ * is not a partial loss but a different config, a different hash, and an element with no
319
+ * styles.
320
+ *
321
+ * It also means evaluating whatever it resolves to, so the project boundary is where that
322
+ * stops. A dependency's code is not ours to run at build time, however pure it looks, and
323
+ * declining leaves exactly the behaviour that shipped before the checker was passed.
324
+ */
325
+ const resolvesWithinProject = (node) => {
326
+ if (!ts_morph.Node.isCallExpression(node)) return false;
327
+ const symbol = node.getExpression().getSymbol();
328
+ if (!symbol) return false;
329
+ const declarations = (symbol.getAliasedSymbol() ?? symbol).getDeclarations();
330
+ if (!declarations.length) return false;
331
+ return !declarations.some((declaration) => declaration.getSourceFile().isInNodeModules());
332
+ };
333
+ /** One per project. `getTypeChecker()` is cheap, but this runs per evaluated call. */
334
+ const typeCheckers = /* @__PURE__ */ new WeakMap();
335
+ const typeCheckerFor = (node) => {
336
+ const project = node.getProject();
337
+ let checker = typeCheckers.get(project);
338
+ if (!checker) {
339
+ checker = project.getTypeChecker().compilerObject;
340
+ typeCheckers.set(project, checker);
341
+ }
342
+ return checker;
343
+ };
344
+ /**
313
345
  * Evaluates a node with strict policies restrictions
314
346
  * @see https://github.com/wessberg/ts-evaluator#setting-up-policies
315
347
  */
@@ -318,6 +350,7 @@ const evaluateNode = (node, stack, ctx) => {
318
350
  if (ctx.canEval && !ctx.canEval?.(node, stack)) return;
319
351
  if (cacheMap$2.has(node)) return cacheMap$2.get(node);
320
352
  const result = (0, ts_evaluator.evaluate)({
353
+ ...resolvesWithinProject(node) ? { typeChecker: typeCheckerFor(node) } : {},
321
354
  policy: {
322
355
  deterministic: true,
323
356
  network: false,
@@ -1902,3 +1935,4 @@ exports.isBoxNode = isBoxNode;
1902
1935
  exports.maybeBoxNode = maybeBoxNode;
1903
1936
  exports.maybeIdentifierValue = maybeIdentifierValue;
1904
1937
  exports.unbox = unbox;
1938
+ exports.unwrapExpression = unwrapExpression;
package/dist/index.d.cts CHANGED
@@ -302,6 +302,9 @@ declare const maybeIdentifierValue: (identifier: Identifier, _stack: Node[], ctx
302
302
  type MatchProp = (prop: MatchFnPropArgs | MatchPropArgs) => boolean;
303
303
  declare const extractJsxSpreadAttributeValues: (node: JsxSpreadAttribute, ctx: BoxContext, matchProp: MatchProp) => MaybeBoxNodeReturn;
304
304
  //#endregion
305
+ //#region src/utils.d.ts
306
+ declare const unwrapExpression: (node: Node) => Node;
307
+ //#endregion
305
308
  //#region src/unbox.d.ts
306
309
  type BoxNodeType = BoxNode | BoxNode[] | undefined;
307
310
  type CacheMap = WeakMap<BoxNode, Unboxed>;
@@ -321,4 +324,4 @@ interface Unboxed {
321
324
  }
322
325
  declare const unbox: (node: BoxNodeType, ctx?: Pick<UnboxContext, "cache">) => Unboxed;
323
326
  //#endregion
324
- export { type BoxContext, type BoxNode, BoxNodeArray, BoxNodeConditional, BoxNodeEmptyInitializer, BoxNodeLiteral, BoxNodeMap, BoxNodeObject, BoxNodeUnresolvable, type EvaluateOptions, type ExtractOptions, type ExtractResultByName, type ExtractResultItem, type ExtractedComponentInstance, type ExtractedComponentResult, type ExtractedFunctionInstance, type ExtractedFunctionResult, type NodeRange, type PrimitiveType, type Unboxed, box, clearBoxNodeCache, extract, extractCallExpressionArguments, extractJsxAttribute, extractJsxElementProps, extractJsxSpreadAttributeValues, findIdentifierValueDeclaration, isBoxNode, maybeBoxNode, maybeIdentifierValue, unbox };
327
+ export { type BoxContext, type BoxNode, BoxNodeArray, BoxNodeConditional, BoxNodeEmptyInitializer, BoxNodeLiteral, BoxNodeMap, BoxNodeObject, BoxNodeUnresolvable, type EvaluateOptions, type ExtractOptions, type ExtractResultByName, type ExtractResultItem, type ExtractedComponentInstance, type ExtractedComponentResult, type ExtractedFunctionInstance, type ExtractedFunctionResult, type NodeRange, type PrimitiveType, type Unboxed, box, clearBoxNodeCache, extract, extractCallExpressionArguments, extractJsxAttribute, extractJsxElementProps, extractJsxSpreadAttributeValues, findIdentifierValueDeclaration, isBoxNode, maybeBoxNode, maybeIdentifierValue, unbox, unwrapExpression };
package/dist/index.d.mts CHANGED
@@ -302,6 +302,9 @@ declare const maybeIdentifierValue: (identifier: Identifier, _stack: Node[], ctx
302
302
  type MatchProp = (prop: MatchFnPropArgs | MatchPropArgs) => boolean;
303
303
  declare const extractJsxSpreadAttributeValues: (node: JsxSpreadAttribute, ctx: BoxContext, matchProp: MatchProp) => MaybeBoxNodeReturn;
304
304
  //#endregion
305
+ //#region src/utils.d.ts
306
+ declare const unwrapExpression: (node: Node) => Node;
307
+ //#endregion
305
308
  //#region src/unbox.d.ts
306
309
  type BoxNodeType = BoxNode | BoxNode[] | undefined;
307
310
  type CacheMap = WeakMap<BoxNode, Unboxed>;
@@ -321,4 +324,4 @@ interface Unboxed {
321
324
  }
322
325
  declare const unbox: (node: BoxNodeType, ctx?: Pick<UnboxContext, "cache">) => Unboxed;
323
326
  //#endregion
324
- export { type BoxContext, type BoxNode, BoxNodeArray, BoxNodeConditional, BoxNodeEmptyInitializer, BoxNodeLiteral, BoxNodeMap, BoxNodeObject, BoxNodeUnresolvable, type EvaluateOptions, type ExtractOptions, type ExtractResultByName, type ExtractResultItem, type ExtractedComponentInstance, type ExtractedComponentResult, type ExtractedFunctionInstance, type ExtractedFunctionResult, type NodeRange, type PrimitiveType, type Unboxed, box, clearBoxNodeCache, extract, extractCallExpressionArguments, extractJsxAttribute, extractJsxElementProps, extractJsxSpreadAttributeValues, findIdentifierValueDeclaration, isBoxNode, maybeBoxNode, maybeIdentifierValue, unbox };
327
+ export { type BoxContext, type BoxNode, BoxNodeArray, BoxNodeConditional, BoxNodeEmptyInitializer, BoxNodeLiteral, BoxNodeMap, BoxNodeObject, BoxNodeUnresolvable, type EvaluateOptions, type ExtractOptions, type ExtractResultByName, type ExtractResultItem, type ExtractedComponentInstance, type ExtractedComponentResult, type ExtractedFunctionInstance, type ExtractedFunctionResult, type NodeRange, type PrimitiveType, type Unboxed, box, clearBoxNodeCache, extract, extractCallExpressionArguments, extractJsxAttribute, extractJsxElementProps, extractJsxSpreadAttributeValues, findIdentifierValueDeclaration, isBoxNode, maybeBoxNode, maybeIdentifierValue, unbox, unwrapExpression };
package/dist/index.mjs CHANGED
@@ -309,6 +309,38 @@ const box = {
309
309
  const TsEvalError = Symbol("EvalError");
310
310
  const cacheMap$2 = /* @__PURE__ */ new WeakMap();
311
311
  /**
312
+ * Whether a call reaches a function declared outside this project.
313
+ *
314
+ * Passing a type checker lets the evaluator resolve an identifier to its declaration in
315
+ * another module, which is what makes a call to an imported helper resolvable at all — a
316
+ * style helper in a neighbouring file used to come back unresolvable, and for a recipe that
317
+ * is not a partial loss but a different config, a different hash, and an element with no
318
+ * styles.
319
+ *
320
+ * It also means evaluating whatever it resolves to, so the project boundary is where that
321
+ * stops. A dependency's code is not ours to run at build time, however pure it looks, and
322
+ * declining leaves exactly the behaviour that shipped before the checker was passed.
323
+ */
324
+ const resolvesWithinProject = (node) => {
325
+ if (!Node.isCallExpression(node)) return false;
326
+ const symbol = node.getExpression().getSymbol();
327
+ if (!symbol) return false;
328
+ const declarations = (symbol.getAliasedSymbol() ?? symbol).getDeclarations();
329
+ if (!declarations.length) return false;
330
+ return !declarations.some((declaration) => declaration.getSourceFile().isInNodeModules());
331
+ };
332
+ /** One per project. `getTypeChecker()` is cheap, but this runs per evaluated call. */
333
+ const typeCheckers = /* @__PURE__ */ new WeakMap();
334
+ const typeCheckerFor = (node) => {
335
+ const project = node.getProject();
336
+ let checker = typeCheckers.get(project);
337
+ if (!checker) {
338
+ checker = project.getTypeChecker().compilerObject;
339
+ typeCheckers.set(project, checker);
340
+ }
341
+ return checker;
342
+ };
343
+ /**
312
344
  * Evaluates a node with strict policies restrictions
313
345
  * @see https://github.com/wessberg/ts-evaluator#setting-up-policies
314
346
  */
@@ -317,6 +349,7 @@ const evaluateNode = (node, stack, ctx) => {
317
349
  if (ctx.canEval && !ctx.canEval?.(node, stack)) return;
318
350
  if (cacheMap$2.has(node)) return cacheMap$2.get(node);
319
351
  const result = evaluate({
352
+ ...resolvesWithinProject(node) ? { typeChecker: typeCheckerFor(node) } : {},
320
353
  policy: {
321
354
  deterministic: true,
322
355
  network: false,
@@ -1882,4 +1915,4 @@ const unbox = (node, ctx) => {
1882
1915
  return result;
1883
1916
  };
1884
1917
  //#endregion
1885
- export { BoxNodeArray, BoxNodeConditional, BoxNodeEmptyInitializer, BoxNodeLiteral, BoxNodeMap, BoxNodeObject, BoxNodeUnresolvable, box, clearBoxNodeCache, extract, extractCallExpressionArguments, extractJsxAttribute, extractJsxElementProps, extractJsxSpreadAttributeValues, findIdentifierValueDeclaration, isBoxNode, maybeBoxNode, maybeIdentifierValue, unbox };
1918
+ export { BoxNodeArray, BoxNodeConditional, BoxNodeEmptyInitializer, BoxNodeLiteral, BoxNodeMap, BoxNodeObject, BoxNodeUnresolvable, box, clearBoxNodeCache, extract, extractCallExpressionArguments, extractJsxAttribute, extractJsxElementProps, extractJsxSpreadAttributeValues, findIdentifierValueDeclaration, isBoxNode, maybeBoxNode, maybeIdentifierValue, unbox, unwrapExpression };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bamboocss/extractor",
3
- "version": "1.16.1",
3
+ "version": "1.17.1",
4
4
  "description": "The css extractor for css bamboo",
5
5
  "homepage": "https://bamboocss.com",
6
6
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "ts-evaluator": "1.2.0",
37
37
  "ts-morph": "28.0.0",
38
- "@bamboocss/shared": "1.16.1"
38
+ "@bamboocss/shared": "1.17.1"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsdown src/index.ts --format=cjs,esm --shims --dts",