@zachacious/protoc-gen-connect-vue 1.0.16 → 1.0.18

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/generator.js CHANGED
@@ -336805,52 +336805,45 @@ var templates = {
336805
336805
  rpc: fs.readFileSync(path.join(templateDir, "rpc.ts.mustache"), "utf-8"),
336806
336806
  index: fs.readFileSync(path.join(templateDir, "index.ts.mustache"), "utf-8")
336807
336807
  };
336808
- function findBestPaginationCandidate(msg, isRequest, depth = 0) {
336808
+ function findPaginationPath(msg, isRequest, depth = 0) {
336809
336809
  if (depth > 3)
336810
336810
  return null;
336811
- let best = null;
336811
+ const reqKeywords = [
336812
+ "pagetoken",
336813
+ "pagenumber",
336814
+ "nextpagetoken",
336815
+ "offset",
336816
+ "cursor"
336817
+ ];
336818
+ const resKeywords = ["nextpagetoken", "nextpage", "nextcursor"];
336819
+ const targets = isRequest ? reqKeywords : resKeywords;
336812
336820
  for (const f of msg.fields) {
336813
- let currentScore = 0;
336814
- const name = f.name.toLowerCase().replace(/_/g, "");
336815
- const reqKeywords = ["token", "page", "offset", "cursor", "start", "skip"];
336816
- const resKeywords = ["next", "token", "more", "hasmore", "cursor", "total"];
336817
- const targets = isRequest ? reqKeywords : resKeywords;
336818
- if (targets.some((t) => name.includes(t)))
336819
- currentScore += 10;
336820
- if (name.includes("pagetoken") || name.includes("nextpage"))
336821
- currentScore += 15;
336822
- const isString = f.fieldKind === "scalar" && f.scalar === 9;
336823
- const isNumber = f.fieldKind === "scalar" && [3, 4, 5, 13, 17, 18].includes(f.scalar);
336824
- if (isString || isNumber) {
336825
- currentScore += 5;
336826
- if (!best || currentScore > best.score) {
336827
- best = {
336828
- path: [f.name],
336829
- type: isString ? "string" : "number",
336830
- score: currentScore
336831
- };
336832
- }
336833
- }
336834
336821
  if (f.fieldKind === "message") {
336835
- const nested = findBestPaginationCandidate(f.message, isRequest, depth + 1);
336836
- if (nested) {
336837
- const nestedScore = nested.score + 12;
336838
- if (!best || nestedScore > best.score) {
336839
- best = {
336840
- path: [f.name, ...nested.path],
336841
- type: nested.type,
336842
- score: nestedScore
336843
- };
336844
- }
336822
+ const name = f.name.toLowerCase();
336823
+ if (name.includes("page") || name.includes("meta") || name.includes("paging")) {
336824
+ const sub = findPaginationPath(f.message, isRequest, depth + 1);
336825
+ if (sub)
336826
+ return [f.name, ...sub];
336845
336827
  }
336846
336828
  }
336847
336829
  }
336848
- return best;
336830
+ for (const f of msg.fields) {
336831
+ const normalized = f.name.toLowerCase().replace(/_/g, "");
336832
+ if (targets.some((t) => normalized.includes(t)))
336833
+ return [f.name];
336834
+ }
336835
+ return null;
336836
+ }
336837
+ function isRepeatedSafe(f) {
336838
+ if (f.fieldKind === "map")
336839
+ return false;
336840
+ return "repeated" in f && f.repeated === true;
336849
336841
  }
336850
336842
  function processService(service) {
336851
336843
  const importMap = new Map;
336852
336844
  const wktImports = new Set;
336853
336845
  const allMessages = new Set;
336846
+ const debugLog = [];
336854
336847
  function track(msg) {
336855
336848
  if (KNOWN_WKT.includes(msg.typeName)) {
336856
336849
  wktImports.add(msg.name);
@@ -336882,20 +336875,28 @@ function processService(service) {
336882
336875
  ];
336883
336876
  const isMutation = mutationVerbs.some((v) => name.startsWith(v));
336884
336877
  const isQuery = isUnary && !isMutation;
336885
- const reqCandidate = findBestPaginationCandidate(m.input, true);
336886
- const resCandidate = findBestPaginationCandidate(m.output, false);
336887
- const isPaginated = isQuery && reqCandidate && resCandidate && reqCandidate.score + resCandidate.score > 25;
336878
+ const reqPath = findPaginationPath(m.input, true);
336879
+ const resPath = findPaginationPath(m.output, false);
336880
+ const hasRepeatedList = m.output.fields.some((f) => isRepeatedSafe(f));
336881
+ const isPaginated = isQuery && hasRepeatedList && !!reqPath && !!resPath;
336882
+ debugLog.push(`Method: ${name}`);
336883
+ debugLog.push(` isUnary: ${isUnary}, isMutation: ${isMutation} -> isQuery: ${isQuery}`);
336884
+ debugLog.push(` reqPath: ${reqPath?.join(".")}`);
336885
+ debugLog.push(` resPath: ${resPath?.join(".")}`);
336886
+ debugLog.push(` hasRepeatedList: ${hasRepeatedList}`);
336887
+ debugLog.push(` FINAL: isPaginated = ${isPaginated}`);
336888
+ debugLog.push("---");
336888
336889
  return {
336889
336890
  functionName: name.charAt(0).toLowerCase() + name.slice(1),
336890
336891
  hookName: `use${name}`,
336892
+ infiniteHookName: `use${name}Infinite`,
336891
336893
  resource: name.replace(/^(Get|ListAll|List|Search|Create|Update|Delete|Remove|Patch|Post|Set|Add)/, "") || "Global",
336892
336894
  inputType: m.input.name,
336893
336895
  outputType: m.output.name,
336894
336896
  isQuery,
336895
336897
  isPaginated,
336896
- reqPath: reqCandidate?.path.join("."),
336897
- resPath: resCandidate?.path.join("."),
336898
- pageType: reqCandidate?.type || "string"
336898
+ reqPath: reqPath?.join("."),
336899
+ resPath: resPath?.join(".")
336899
336900
  };
336900
336901
  });
336901
336902
  return {
@@ -336907,12 +336908,14 @@ function processService(service) {
336907
336908
  externalImports: Array.from(importMap.entries()).map(([path2, types2]) => ({
336908
336909
  path: path2,
336909
336910
  types: Array.from(types2)
336910
- }))
336911
+ })),
336912
+ debugInfo: debugLog.join(`
336913
+ `)
336911
336914
  };
336912
336915
  }
336913
336916
  var plugin = createEcmaScriptPlugin({
336914
336917
  name: "protoc-gen-connect-vue",
336915
- version: "v1.4.0",
336918
+ version: "v1.9.0",
336916
336919
  generateTs: (schema) => {
336917
336920
  const service = schema.files.flatMap((f) => f.services)[0];
336918
336921
  if (!service)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zachacious/protoc-gen-connect-vue",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "Smart TanStack Query & ConnectRPC SDK generator for Vue.js",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,9 +58,17 @@ export const useApi = () => {
58
58
  {{#rpcs}}
59
59
  {{functionName}},
60
60
  {{hookName}},
61
+ {{#isPaginated}}
62
+ {{infiniteHookName}},
63
+ {{/isPaginated}}
61
64
  {{/rpcs}}
62
65
  isGlobalLoading,
63
66
  queryKeys,
64
67
  createEmpty
65
68
  };
66
- };
69
+ };
70
+
71
+ /*
72
+ --- GENERATOR DEBUG INFO ---
73
+ {{{debugInfo}}}
74
+ */
@@ -7,14 +7,29 @@ const {{functionName}} = async (req: {{inputType}}): Promise<APIResponse<{{outpu
7
7
  return res;
8
8
  };
9
9
 
10
+ {{#isQuery}}
10
11
  /**
11
- * Hook: {{hookName}}
12
+ * Standard Hook: {{hookName}}
12
13
  */
13
14
  const {{hookName}} = (
14
- {{#isQuery}}input: any, options: any = {}{{/isQuery}}
15
- {{^isQuery}}options: any = {}{{/isQuery}}
15
+ input: any,
16
+ options: any = {}
17
+ ) => {
18
+ return useQuery({
19
+ queryKey: queryKeys.{{functionName}}(input),
20
+ queryFn: () => client.value.{{functionName}}(unref(input)),
21
+ ...options,
22
+ });
23
+ };
24
+
25
+ {{#isPaginated}}
26
+ /**
27
+ * Infinite Hook: {{infiniteHookName}}
28
+ */
29
+ const {{infiniteHookName}} = (
30
+ input: any,
31
+ options: any = {}
16
32
  ) => {
17
- {{#isPaginated}}
18
33
  return useInfiniteQuery({
19
34
  queryKey: queryKeys.{{functionName}}(input),
20
35
  queryFn: async ({ pageParam }) => {
@@ -29,31 +44,28 @@ const {{hookName}} = (
29
44
  curr[path[path.length - 1]] = pageParam;
30
45
  return client.value.{{functionName}}(req);
31
46
  },
32
- initialPageParam: options.initialPageParam ?? ( "{{pageType}}" === "string" ? "" : 1 ),
47
+ initialPageParam: options.initialPageParam ?? "",
33
48
  getNextPageParam: (lastPage: any) => {
34
49
  const path = "{{resPath}}".split('.');
35
50
  const val = path.reduce((o, i) => o?.[i], lastPage);
36
-
37
- // If the discovered path is an object (like PageResponse), look for standard keys
38
51
  if (typeof val === 'object' && val !== null) {
39
- return val.nextPageToken || val.nextPage || val.pageToken || undefined;
52
+ return val.nextPageToken || val.nextPage || undefined;
40
53
  }
41
54
  return val || undefined;
42
55
  },
43
56
  ...options,
44
57
  });
45
- {{/isPaginated}}
46
-
47
- {{^isPaginated}}
48
- {{#isQuery}}
49
- return useQuery({
50
- queryKey: queryKeys.{{functionName}}(input),
51
- queryFn: () => client.value.{{functionName}}(unref(input)),
52
- ...options,
53
- });
54
- {{/isQuery}}
55
-
56
- {{^isQuery}}
58
+ };
59
+ {{/isPaginated}}
60
+ {{/isQuery}}
61
+
62
+ {{^isQuery}}
63
+ /**
64
+ * Mutation Hook: {{hookName}}
65
+ */
66
+ const {{hookName}} = (
67
+ options: any = {}
68
+ ) => {
57
69
  return useMutation({
58
70
  mutationFn: (req: {{inputType}}) => client.value.{{functionName}}(req),
59
71
  onSuccess: async (data, variables, context) => {
@@ -62,6 +74,5 @@ const {{hookName}} = (
62
74
  },
63
75
  ...options,
64
76
  });
65
- {{/isQuery}}
66
- {{/isPaginated}}
67
- };
77
+ };
78
+ {{/isQuery}}