@fatagnus/convex-sync-check 0.1.3 → 0.3.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.
@@ -9,11 +9,45 @@ var BUILTIN_INTERNAL = /* @__PURE__ */ new Set([
9
9
  ]);
10
10
  var SKIP_DIRS = /* @__PURE__ */ new Set(["_generated", "node_modules"]);
11
11
  var SKIP_FILE_PATTERNS = [/\.test\.ts$/, /\.spec\.ts$/];
12
+ var BASE_VISIBILITY = {
13
+ query: "public",
14
+ mutation: "public",
15
+ action: "public",
16
+ internalQuery: "internal",
17
+ internalMutation: "internal",
18
+ internalAction: "internal"
19
+ };
20
+ function detectWrappers(files) {
21
+ const detected = {};
22
+ const customFnPattern = /(?:export\s+)?const\s+(\w+)\s*=\s*custom(?:Query|Mutation|Action)\s*\(\s*(query|mutation|action|internalQuery|internalMutation|internalAction)\b/g;
23
+ for (const file of files) {
24
+ const content = readFileSync(file, "utf-8");
25
+ let match;
26
+ customFnPattern.lastIndex = 0;
27
+ while ((match = customFnPattern.exec(content)) !== null) {
28
+ const wrapperName = match[1];
29
+ const baseFn = match[2];
30
+ if (BUILTIN_PUBLIC.has(wrapperName) || BUILTIN_INTERNAL.has(wrapperName)) {
31
+ continue;
32
+ }
33
+ const visibility = BASE_VISIBILITY[baseFn];
34
+ if (visibility) {
35
+ detected[wrapperName] = visibility;
36
+ }
37
+ }
38
+ }
39
+ return detected;
40
+ }
12
41
  function scanBackend(convexDir, functionWrappers) {
13
42
  const files = collectTsFiles(convexDir);
14
43
  const defs = [];
44
+ const autoDetected = detectWrappers(files);
15
45
  const allPublic = new Set(BUILTIN_PUBLIC);
16
46
  const allInternal = new Set(BUILTIN_INTERNAL);
47
+ for (const [name, visibility] of Object.entries(autoDetected)) {
48
+ if (visibility === "public") allPublic.add(name);
49
+ else allInternal.add(name);
50
+ }
17
51
  if (functionWrappers) {
18
52
  for (const [name, visibility] of Object.entries(functionWrappers)) {
19
53
  if (visibility === "public") allPublic.add(name);
@@ -186,10 +220,19 @@ function analyze(defs, refs) {
186
220
  }
187
221
 
188
222
  // src/index.ts
223
+ function globToRegex(pattern) {
224
+ const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
225
+ return new RegExp(`^${escaped}$`);
226
+ }
227
+ function matchesAnyPattern(apiPath, patterns) {
228
+ return patterns.some((p) => globToRegex(p).test(apiPath));
229
+ }
189
230
  function checkConvexSync(options) {
190
231
  const defs = scanBackend(options.convexDir, options.functionWrappers);
191
232
  const refs = scanFrontend(options.frontendDirs);
192
- const { errors, warnings, passed } = analyze(defs, refs);
233
+ const { errors, warnings } = analyze(defs, refs);
234
+ const ignorePatterns = options.ignore ?? [];
235
+ const filteredErrors = ignorePatterns.length > 0 ? errors.filter((e) => !matchesAnyPattern(e.apiPath, ignorePatterns)) : errors;
193
236
  const publicFunctions = defs.filter((d) => !d.isInternal).length;
194
237
  const internalFunctions = defs.filter((d) => d.isInternal).length;
195
238
  const uniqueRefs = new Set(refs.map((r) => r.apiPath));
@@ -211,9 +254,9 @@ function checkConvexSync(options) {
211
254
  frontendRefs: uniqueRefs.size,
212
255
  backendModules: uniqueModules.size
213
256
  },
214
- errors,
257
+ errors: filteredErrors,
215
258
  warnings: filteredWarnings,
216
- passed
259
+ passed: filteredErrors.length === 0
217
260
  };
218
261
  }
219
262
 
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  checkConvexSync
3
- } from "./chunk-HARLMPMI.js";
3
+ } from "./chunk-OJYCE5NZ.js";
4
4
 
5
5
  // src/cli.ts
6
6
  import { parseArgs } from "util";
@@ -252,15 +252,22 @@ async function main() {
252
252
  ...config.functionWrappers
253
253
  };
254
254
  const suppressWarnings = args.noWarnings ? ["UNREFERENCED"] : config.suppressWarnings;
255
+ const cliIgnore = args.ignore ? args.ignore.split(",").map((s) => s.trim()) : [];
256
+ const configIgnore = config.ignore ?? [];
257
+ const ignore = [...cliIgnore, ...configIgnore];
255
258
  if (args.verbose) {
256
259
  console.log(`Scanning backend: ${convexDir}`);
257
260
  console.log(`Scanning frontend: ${frontendDirs.join(", ")}`);
261
+ if (ignore.length > 0) {
262
+ console.log(`Ignoring ${ignore.length} pattern(s)`);
263
+ }
258
264
  }
259
265
  const result = checkConvexSync({
260
266
  convexDir,
261
267
  frontendDirs,
262
268
  functionWrappers: Object.keys(functionWrappers).length > 0 ? functionWrappers : void 0,
263
269
  suppressWarnings,
270
+ ignore: ignore.length > 0 ? ignore : void 0,
264
271
  verbose: args.verbose
265
272
  });
266
273
  result.project = layout.project;
package/dist/index.d.ts CHANGED
@@ -37,10 +37,7 @@ interface CheckOptions {
37
37
  convexDir?: string;
38
38
  frontendDirs?: string[];
39
39
  functionWrappers?: Record<string, "public" | "internal">;
40
- ignore?: {
41
- backend?: string[];
42
- frontend?: string[];
43
- };
40
+ ignore?: string[];
44
41
  suppressWarnings?: WarningType[];
45
42
  deployed?: boolean;
46
43
  verbose?: boolean;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  checkConvexSync
3
- } from "./chunk-HARLMPMI.js";
3
+ } from "./chunk-OJYCE5NZ.js";
4
4
  export {
5
5
  checkConvexSync
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fatagnus/convex-sync-check",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "description": "Zero-config CLI to check Convex frontend/backend function sync",
5
5
  "type": "module",
6
6
  "bin": {