@bamboocss/parser 1.22.0 → 1.24.0

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
@@ -65,6 +65,7 @@ function classifyProject(ctx, resultMap) {
65
65
  const { item, kind, filepath, localMaps } = opts;
66
66
  if (!item.box || _bamboocss_extractor.box.isUnresolvable(item.box)) return;
67
67
  if (!item.data) return;
68
+ if (item.type === "cva-call") return;
68
69
  const componentReportItem = {
69
70
  componentIndex: String(componentIndex++),
70
71
  componentName: item.name,
@@ -674,6 +675,7 @@ var ParserResult = class {
674
675
  all = [];
675
676
  css = /* @__PURE__ */ new Set();
676
677
  cva = /* @__PURE__ */ new Set();
678
+ cvaCall = /* @__PURE__ */ new Set();
677
679
  sva = /* @__PURE__ */ new Set();
678
680
  token = /* @__PURE__ */ new Set();
679
681
  viewTransition = /* @__PURE__ */ new Set();
@@ -727,6 +729,20 @@ var ParserResult = class {
727
729
  const encoder = this.encoder;
728
730
  result.data.forEach((data) => encoder.processAtomicRecipe(data));
729
731
  }
732
+ /**
733
+ * A call of a locally-bound inline recipe -- `const badge = cva(...)`, then `badge({...})`.
734
+ *
735
+ * Recorded, not encoded. The rules already exist: `setCva` emitted them from the config,
736
+ * and a recipe's classes are named semantically from that config rather than from this
737
+ * call. What this adds is *visibility* -- the call site becomes something the fold can see
738
+ * and report on, where before it was indistinguishable from code nobody had parsed.
739
+ */
740
+ setCvaCall(name, result) {
741
+ this.cvaCall.add(this.append(Object.assign({
742
+ type: "cva-call",
743
+ name
744
+ }, result)));
745
+ }
730
746
  setSva(result) {
731
747
  this.sva.add(this.append(Object.assign({ type: "sva" }, result)));
732
748
  this.reportUnresolvedRecipe(result);
@@ -794,6 +810,7 @@ var ParserResult = class {
794
810
  result.css.forEach((item) => this.css.add(this.append(item)));
795
811
  result.cva.forEach((item) => this.cva.add(this.append(item)));
796
812
  result.sva.forEach((item) => this.sva.add(this.append(item)));
813
+ result.cvaCall.forEach((item) => this.cvaCall.add(this.append(item)));
797
814
  result.token.forEach((item) => this.token.add(this.append(item)));
798
815
  result.viewTransition.forEach((item) => this.viewTransition.add(this.append(item)));
799
816
  result.recipe.forEach((items, name) => {
@@ -815,6 +832,7 @@ var ParserResult = class {
815
832
  css: Array.from(this.css),
816
833
  cva: Array.from(this.cva),
817
834
  sva: Array.from(this.sva),
835
+ cvaCall: Array.from(this.cvaCall),
818
836
  token: Array.from(this.token),
819
837
  viewTransition: Array.from(this.viewTransition),
820
838
  recipe: Object.fromEntries(Array.from(this.recipe.entries()).map(([key, value]) => [key, Array.from(value)])),
@@ -850,6 +868,20 @@ function createParser(context) {
850
868
  _bamboocss_logger.logger.debug("ast:import", !file.isEmpty() ? `Found import { ${file.toString()} } in ${filePath}` : `No import found in ${filePath}`);
851
869
  const parserResult = new ParserResult(context, encoder);
852
870
  if (file.isEmpty() && !jsx.isEnabled) return parserResult;
871
+ if (file.importsRecipeFactory()) for (const statement of sourceFile.compilerNode.statements) {
872
+ if (!ts_morph.ts.isVariableStatement(statement)) continue;
873
+ if (!(statement.declarationList.flags & ts_morph.ts.NodeFlags.Const)) continue;
874
+ for (const declaration of statement.declarationList.declarations) {
875
+ const initializer = declaration.initializer;
876
+ if (!initializer || !ts_morph.ts.isCallExpression(initializer)) continue;
877
+ const callee = initializer.expression;
878
+ if (!ts_morph.ts.isIdentifier(callee) || !ts_morph.ts.isIdentifier(declaration.name)) continue;
879
+ const imported = file.getName(callee.text);
880
+ if (imported !== "cva" && imported !== "sva") continue;
881
+ if (!file.matchFn(callee.text)) continue;
882
+ file.addLocalRecipe(declaration.name.text);
883
+ }
884
+ }
853
885
  (0, _bamboocss_extractor.extract)({
854
886
  ast: sourceFile,
855
887
  tokens: context.tokens ? {
@@ -899,53 +931,64 @@ function createParser(context) {
899
931
  kind: result.kind,
900
932
  alias
901
933
  } : { kind: result.kind });
902
- if (result.kind === "function") (0, ts_pattern.match)(name).when(imports.matchers.css.match, (name) => {
903
- result.queryList.forEach((query) => {
904
- if (query.kind === "call-expression") if (query.box.value.length > 1) parserResult.set(name, {
905
- name,
906
- box: query.box,
907
- data: query.box.value.reduce((acc, value) => [...acc, ...combineResult((0, _bamboocss_extractor.unbox)(value))], [])
934
+ if (result.kind === "function") {
935
+ if (file.isLocalRecipe(alias) && !file.match(alias)) {
936
+ result.queryList.forEach((query) => {
937
+ if (query.kind === "call-expression") parserResult.setCvaCall(alias, {
938
+ name: alias,
939
+ box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
940
+ data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
941
+ });
908
942
  });
909
- else parserResult.set(name, {
910
- name,
911
- box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
912
- data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
943
+ return;
944
+ }
945
+ (0, ts_pattern.match)(name).when(imports.matchers.css.match, (name) => {
946
+ result.queryList.forEach((query) => {
947
+ if (query.kind === "call-expression") if (query.box.value.length > 1) parserResult.set(name, {
948
+ name,
949
+ box: query.box,
950
+ data: query.box.value.reduce((acc, value) => [...acc, ...combineResult((0, _bamboocss_extractor.unbox)(value))], [])
951
+ });
952
+ else parserResult.set(name, {
953
+ name,
954
+ box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
955
+ data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
956
+ });
913
957
  });
914
- });
915
- }).when(imports.matchers.tokens.match, (name) => {
916
- result.queryList.forEach((query) => {
917
- if (query.kind === "call-expression") parserResult.setToken({
918
- name,
919
- box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
920
- data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
958
+ }).when(imports.matchers.tokens.match, (name) => {
959
+ result.queryList.forEach((query) => {
960
+ if (query.kind === "call-expression") parserResult.setToken({
961
+ name,
962
+ box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
963
+ data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
964
+ });
921
965
  });
922
- });
923
- }).when(file.isValidPattern, (name) => {
924
- result.queryList.forEach((query) => {
925
- if (query.kind === "call-expression") parserResult.setPattern(name, {
926
- name,
927
- box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
928
- data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
966
+ }).when(file.isValidPattern, (name) => {
967
+ result.queryList.forEach((query) => {
968
+ if (query.kind === "call-expression") parserResult.setPattern(name, {
969
+ name,
970
+ box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
971
+ data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
972
+ });
929
973
  });
930
- });
931
- }).when(file.isValidRecipe, (name) => {
932
- result.queryList.forEach((query) => {
933
- if (query.kind === "call-expression") parserResult.setRecipe(name, {
934
- name,
935
- box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
936
- data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
974
+ }).when(file.isValidRecipe, (name) => {
975
+ result.queryList.forEach((query) => {
976
+ if (query.kind === "call-expression") parserResult.setRecipe(name, {
977
+ name,
978
+ box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
979
+ data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
980
+ });
937
981
  });
938
- });
939
- }).when(file.isViewTransitionFn, (name) => {
940
- result.queryList.forEach((query) => {
941
- if (query.kind === "call-expression") parserResult.setViewTransition({
942
- name,
943
- box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
944
- data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
982
+ }).when(file.isViewTransitionFn, (name) => {
983
+ result.queryList.forEach((query) => {
984
+ if (query.kind === "call-expression") parserResult.setViewTransition({
985
+ name,
986
+ box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
987
+ data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
988
+ });
945
989
  });
946
- });
947
- }).otherwise(() => {});
948
- else if (jsx.isEnabled && result.kind === "component") result.queryList.forEach((query) => {
990
+ }).otherwise(() => {});
991
+ } else if (jsx.isEnabled && result.kind === "component") result.queryList.forEach((query) => {
949
992
  const data = combineResult((0, _bamboocss_extractor.unbox)(query.box));
950
993
  for (const tag of [name, alias]) {
951
994
  if (!jsx.isJsxTagRecipe(tag)) continue;
package/dist/index.d.cts CHANGED
@@ -173,6 +173,7 @@ declare class ParserResult implements ParserResultInterface {
173
173
  all: ResultItem[];
174
174
  css: Set<ResultItem>;
175
175
  cva: Set<ResultItem>;
176
+ cvaCall: Set<ResultItem>;
176
177
  sva: Set<ResultItem>;
177
178
  token: Set<ResultItem>;
178
179
  viewTransition: Set<ResultItem>;
@@ -192,6 +193,15 @@ declare class ParserResult implements ParserResultInterface {
192
193
  set(name: 'cva' | 'css' | 'sva' | 'token', result: ResultItem): void;
193
194
  setCss(result: ResultItem): void;
194
195
  setCva(result: ResultItem): void;
196
+ /**
197
+ * A call of a locally-bound inline recipe -- `const badge = cva(...)`, then `badge({...})`.
198
+ *
199
+ * Recorded, not encoded. The rules already exist: `setCva` emitted them from the config,
200
+ * and a recipe's classes are named semantically from that config rather than from this
201
+ * call. What this adds is *visibility* -- the call site becomes something the fold can see
202
+ * and report on, where before it was indistinguishable from code nobody had parsed.
203
+ */
204
+ setCvaCall(name: string, result: ResultItem): void;
195
205
  setSva(result: ResultItem): void;
196
206
  /**
197
207
  * Record a recipe config the build could not fully read.
@@ -218,6 +228,7 @@ declare class ParserResult implements ParserResultInterface {
218
228
  css: ResultItem[];
219
229
  cva: ResultItem[];
220
230
  sva: ResultItem[];
231
+ cvaCall: ResultItem[];
221
232
  token: ResultItem[];
222
233
  viewTransition: ResultItem[];
223
234
  recipe: {
package/dist/index.d.mts CHANGED
@@ -173,6 +173,7 @@ declare class ParserResult implements ParserResultInterface {
173
173
  all: ResultItem[];
174
174
  css: Set<ResultItem>;
175
175
  cva: Set<ResultItem>;
176
+ cvaCall: Set<ResultItem>;
176
177
  sva: Set<ResultItem>;
177
178
  token: Set<ResultItem>;
178
179
  viewTransition: Set<ResultItem>;
@@ -192,6 +193,15 @@ declare class ParserResult implements ParserResultInterface {
192
193
  set(name: 'cva' | 'css' | 'sva' | 'token', result: ResultItem): void;
193
194
  setCss(result: ResultItem): void;
194
195
  setCva(result: ResultItem): void;
196
+ /**
197
+ * A call of a locally-bound inline recipe -- `const badge = cva(...)`, then `badge({...})`.
198
+ *
199
+ * Recorded, not encoded. The rules already exist: `setCva` emitted them from the config,
200
+ * and a recipe's classes are named semantically from that config rather than from this
201
+ * call. What this adds is *visibility* -- the call site becomes something the fold can see
202
+ * and report on, where before it was indistinguishable from code nobody had parsed.
203
+ */
204
+ setCvaCall(name: string, result: ResultItem): void;
195
205
  setSva(result: ResultItem): void;
196
206
  /**
197
207
  * Record a recipe config the build could not fully read.
@@ -218,6 +228,7 @@ declare class ParserResult implements ParserResultInterface {
218
228
  css: ResultItem[];
219
229
  cva: ResultItem[];
220
230
  sva: ResultItem[];
231
+ cvaCall: ResultItem[];
221
232
  token: ResultItem[];
222
233
  viewTransition: ResultItem[];
223
234
  recipe: {
package/dist/index.mjs CHANGED
@@ -64,6 +64,7 @@ function classifyProject(ctx, resultMap) {
64
64
  const { item, kind, filepath, localMaps } = opts;
65
65
  if (!item.box || box.isUnresolvable(item.box)) return;
66
66
  if (!item.data) return;
67
+ if (item.type === "cva-call") return;
67
68
  const componentReportItem = {
68
69
  componentIndex: String(componentIndex++),
69
70
  componentName: item.name,
@@ -673,6 +674,7 @@ var ParserResult = class {
673
674
  all = [];
674
675
  css = /* @__PURE__ */ new Set();
675
676
  cva = /* @__PURE__ */ new Set();
677
+ cvaCall = /* @__PURE__ */ new Set();
676
678
  sva = /* @__PURE__ */ new Set();
677
679
  token = /* @__PURE__ */ new Set();
678
680
  viewTransition = /* @__PURE__ */ new Set();
@@ -726,6 +728,20 @@ var ParserResult = class {
726
728
  const encoder = this.encoder;
727
729
  result.data.forEach((data) => encoder.processAtomicRecipe(data));
728
730
  }
731
+ /**
732
+ * A call of a locally-bound inline recipe -- `const badge = cva(...)`, then `badge({...})`.
733
+ *
734
+ * Recorded, not encoded. The rules already exist: `setCva` emitted them from the config,
735
+ * and a recipe's classes are named semantically from that config rather than from this
736
+ * call. What this adds is *visibility* -- the call site becomes something the fold can see
737
+ * and report on, where before it was indistinguishable from code nobody had parsed.
738
+ */
739
+ setCvaCall(name, result) {
740
+ this.cvaCall.add(this.append(Object.assign({
741
+ type: "cva-call",
742
+ name
743
+ }, result)));
744
+ }
729
745
  setSva(result) {
730
746
  this.sva.add(this.append(Object.assign({ type: "sva" }, result)));
731
747
  this.reportUnresolvedRecipe(result);
@@ -793,6 +809,7 @@ var ParserResult = class {
793
809
  result.css.forEach((item) => this.css.add(this.append(item)));
794
810
  result.cva.forEach((item) => this.cva.add(this.append(item)));
795
811
  result.sva.forEach((item) => this.sva.add(this.append(item)));
812
+ result.cvaCall.forEach((item) => this.cvaCall.add(this.append(item)));
796
813
  result.token.forEach((item) => this.token.add(this.append(item)));
797
814
  result.viewTransition.forEach((item) => this.viewTransition.add(this.append(item)));
798
815
  result.recipe.forEach((items, name) => {
@@ -814,6 +831,7 @@ var ParserResult = class {
814
831
  css: Array.from(this.css),
815
832
  cva: Array.from(this.cva),
816
833
  sva: Array.from(this.sva),
834
+ cvaCall: Array.from(this.cvaCall),
817
835
  token: Array.from(this.token),
818
836
  viewTransition: Array.from(this.viewTransition),
819
837
  recipe: Object.fromEntries(Array.from(this.recipe.entries()).map(([key, value]) => [key, Array.from(value)])),
@@ -849,6 +867,20 @@ function createParser(context) {
849
867
  logger.debug("ast:import", !file.isEmpty() ? `Found import { ${file.toString()} } in ${filePath}` : `No import found in ${filePath}`);
850
868
  const parserResult = new ParserResult(context, encoder);
851
869
  if (file.isEmpty() && !jsx.isEnabled) return parserResult;
870
+ if (file.importsRecipeFactory()) for (const statement of sourceFile.compilerNode.statements) {
871
+ if (!ts.isVariableStatement(statement)) continue;
872
+ if (!(statement.declarationList.flags & ts.NodeFlags.Const)) continue;
873
+ for (const declaration of statement.declarationList.declarations) {
874
+ const initializer = declaration.initializer;
875
+ if (!initializer || !ts.isCallExpression(initializer)) continue;
876
+ const callee = initializer.expression;
877
+ if (!ts.isIdentifier(callee) || !ts.isIdentifier(declaration.name)) continue;
878
+ const imported = file.getName(callee.text);
879
+ if (imported !== "cva" && imported !== "sva") continue;
880
+ if (!file.matchFn(callee.text)) continue;
881
+ file.addLocalRecipe(declaration.name.text);
882
+ }
883
+ }
852
884
  extract({
853
885
  ast: sourceFile,
854
886
  tokens: context.tokens ? {
@@ -898,53 +930,64 @@ function createParser(context) {
898
930
  kind: result.kind,
899
931
  alias
900
932
  } : { kind: result.kind });
901
- if (result.kind === "function") match(name).when(imports.matchers.css.match, (name) => {
902
- result.queryList.forEach((query) => {
903
- if (query.kind === "call-expression") if (query.box.value.length > 1) parserResult.set(name, {
904
- name,
905
- box: query.box,
906
- data: query.box.value.reduce((acc, value) => [...acc, ...combineResult(unbox(value))], [])
933
+ if (result.kind === "function") {
934
+ if (file.isLocalRecipe(alias) && !file.match(alias)) {
935
+ result.queryList.forEach((query) => {
936
+ if (query.kind === "call-expression") parserResult.setCvaCall(alias, {
937
+ name: alias,
938
+ box: query.box.value[0] ?? box.fallback(query.box),
939
+ data: combineResult(unbox(query.box.value[0]))
940
+ });
907
941
  });
908
- else parserResult.set(name, {
909
- name,
910
- box: query.box.value[0] ?? box.fallback(query.box),
911
- data: combineResult(unbox(query.box.value[0]))
942
+ return;
943
+ }
944
+ match(name).when(imports.matchers.css.match, (name) => {
945
+ result.queryList.forEach((query) => {
946
+ if (query.kind === "call-expression") if (query.box.value.length > 1) parserResult.set(name, {
947
+ name,
948
+ box: query.box,
949
+ data: query.box.value.reduce((acc, value) => [...acc, ...combineResult(unbox(value))], [])
950
+ });
951
+ else parserResult.set(name, {
952
+ name,
953
+ box: query.box.value[0] ?? box.fallback(query.box),
954
+ data: combineResult(unbox(query.box.value[0]))
955
+ });
912
956
  });
913
- });
914
- }).when(imports.matchers.tokens.match, (name) => {
915
- result.queryList.forEach((query) => {
916
- if (query.kind === "call-expression") parserResult.setToken({
917
- name,
918
- box: query.box.value[0] ?? box.fallback(query.box),
919
- data: combineResult(unbox(query.box.value[0]))
957
+ }).when(imports.matchers.tokens.match, (name) => {
958
+ result.queryList.forEach((query) => {
959
+ if (query.kind === "call-expression") parserResult.setToken({
960
+ name,
961
+ box: query.box.value[0] ?? box.fallback(query.box),
962
+ data: combineResult(unbox(query.box.value[0]))
963
+ });
920
964
  });
921
- });
922
- }).when(file.isValidPattern, (name) => {
923
- result.queryList.forEach((query) => {
924
- if (query.kind === "call-expression") parserResult.setPattern(name, {
925
- name,
926
- box: query.box.value[0] ?? box.fallback(query.box),
927
- data: combineResult(unbox(query.box.value[0]))
965
+ }).when(file.isValidPattern, (name) => {
966
+ result.queryList.forEach((query) => {
967
+ if (query.kind === "call-expression") parserResult.setPattern(name, {
968
+ name,
969
+ box: query.box.value[0] ?? box.fallback(query.box),
970
+ data: combineResult(unbox(query.box.value[0]))
971
+ });
928
972
  });
929
- });
930
- }).when(file.isValidRecipe, (name) => {
931
- result.queryList.forEach((query) => {
932
- if (query.kind === "call-expression") parserResult.setRecipe(name, {
933
- name,
934
- box: query.box.value[0] ?? box.fallback(query.box),
935
- data: combineResult(unbox(query.box.value[0]))
973
+ }).when(file.isValidRecipe, (name) => {
974
+ result.queryList.forEach((query) => {
975
+ if (query.kind === "call-expression") parserResult.setRecipe(name, {
976
+ name,
977
+ box: query.box.value[0] ?? box.fallback(query.box),
978
+ data: combineResult(unbox(query.box.value[0]))
979
+ });
936
980
  });
937
- });
938
- }).when(file.isViewTransitionFn, (name) => {
939
- result.queryList.forEach((query) => {
940
- if (query.kind === "call-expression") parserResult.setViewTransition({
941
- name,
942
- box: query.box.value[0] ?? box.fallback(query.box),
943
- data: combineResult(unbox(query.box.value[0]))
981
+ }).when(file.isViewTransitionFn, (name) => {
982
+ result.queryList.forEach((query) => {
983
+ if (query.kind === "call-expression") parserResult.setViewTransition({
984
+ name,
985
+ box: query.box.value[0] ?? box.fallback(query.box),
986
+ data: combineResult(unbox(query.box.value[0]))
987
+ });
944
988
  });
945
- });
946
- }).otherwise(() => {});
947
- else if (jsx.isEnabled && result.kind === "component") result.queryList.forEach((query) => {
989
+ }).otherwise(() => {});
990
+ } else if (jsx.isEnabled && result.kind === "component") result.queryList.forEach((query) => {
948
991
  const data = combineResult(unbox(query.box));
949
992
  for (const tag of [name, alias]) {
950
993
  if (!jsx.isJsxTagRecipe(tag)) continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bamboocss/parser",
3
- "version": "1.22.0",
3
+ "version": "1.24.0",
4
4
  "description": "The static parser for bamboo css",
5
5
  "homepage": "https://bamboocss.com",
6
6
  "license": "MIT",
@@ -34,17 +34,17 @@
34
34
  "dependencies": {
35
35
  "ts-morph": "28.0.0",
36
36
  "ts-pattern": "5.9.0",
37
- "@bamboocss/config": "^1.22.0",
38
- "@bamboocss/core": "^1.22.0",
39
- "@bamboocss/extractor": "1.22.0",
40
- "@bamboocss/logger": "1.22.0",
41
- "@bamboocss/shared": "1.22.0",
42
- "@bamboocss/types": "1.22.0"
37
+ "@bamboocss/config": "^1.24.0",
38
+ "@bamboocss/core": "^1.24.0",
39
+ "@bamboocss/extractor": "1.24.0",
40
+ "@bamboocss/logger": "1.24.0",
41
+ "@bamboocss/shared": "1.24.0",
42
+ "@bamboocss/types": "1.24.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@bamboocss/generator": "1.22.0",
46
- "@bamboocss/plugin-svelte": "1.22.0",
47
- "@bamboocss/plugin-vue": "1.22.0"
45
+ "@bamboocss/generator": "1.24.0",
46
+ "@bamboocss/plugin-svelte": "1.24.0",
47
+ "@bamboocss/plugin-vue": "1.24.0"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsdown src/index.ts --format=esm,cjs --dts",