@ic-reactor/codegen 0.1.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 +543 -0
- package/dist/index.d.cts +237 -0
- package/dist/index.d.ts +237 -0
- package/dist/index.js +489 -0
- package/package.json +60 -0
- package/src/bindgen.ts +113 -0
- package/src/did.test.ts +102 -0
- package/src/did.ts +85 -0
- package/src/index.ts +51 -0
- package/src/naming.test.ts +59 -0
- package/src/naming.ts +83 -0
- package/src/templates/__snapshots__/infiniteQuery.test.ts.snap +44 -0
- package/src/templates/__snapshots__/mutation.test.ts.snap +59 -0
- package/src/templates/__snapshots__/query.test.ts.snap +64 -0
- package/src/templates/__snapshots__/reactor.test.ts.snap +163 -0
- package/src/templates/infiniteQuery.test.ts +42 -0
- package/src/templates/infiniteQuery.ts +74 -0
- package/src/templates/mutation.test.ts +43 -0
- package/src/templates/mutation.ts +51 -0
- package/src/templates/query.test.ts +44 -0
- package/src/templates/query.ts +71 -0
- package/src/templates/reactor.test.ts +78 -0
- package/src/templates/reactor.ts +290 -0
- package/src/types.ts +78 -0
package/src/did.test.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest"
|
|
2
|
+
import { extractMethods, formatMethodForDisplay } from "./did"
|
|
3
|
+
import type { MethodInfo } from "./types"
|
|
4
|
+
|
|
5
|
+
describe("DID Utilities", () => {
|
|
6
|
+
describe("extractMethods", () => {
|
|
7
|
+
it("extracts query methods", () => {
|
|
8
|
+
const didContent = `
|
|
9
|
+
type User = record { name : text; age : nat };
|
|
10
|
+
type Item = record { name : text; price : nat };
|
|
11
|
+
|
|
12
|
+
service : {
|
|
13
|
+
get_user: (nat) -> (opt User) query;
|
|
14
|
+
list_items: () -> (vec Item) query;
|
|
15
|
+
}`
|
|
16
|
+
const methods = extractMethods(didContent)
|
|
17
|
+
expect(methods).toHaveLength(2)
|
|
18
|
+
expect(methods[0]).toMatchObject({
|
|
19
|
+
name: "get_user",
|
|
20
|
+
type: "query",
|
|
21
|
+
hasArgs: true,
|
|
22
|
+
})
|
|
23
|
+
expect(methods[1]).toMatchObject({
|
|
24
|
+
name: "list_items",
|
|
25
|
+
type: "query",
|
|
26
|
+
hasArgs: false,
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("extracts mutation (update) methods", () => {
|
|
31
|
+
const didContent = `service : {
|
|
32
|
+
create_user: (User) -> (Result);
|
|
33
|
+
update_item: (nat, Item) -> (Result);
|
|
34
|
+
}`
|
|
35
|
+
const methods = extractMethods(didContent)
|
|
36
|
+
expect(methods).toHaveLength(2)
|
|
37
|
+
expect(methods[0]).toMatchObject({
|
|
38
|
+
name: "create_user",
|
|
39
|
+
type: "mutation",
|
|
40
|
+
hasArgs: true,
|
|
41
|
+
})
|
|
42
|
+
expect(methods[1]).toMatchObject({
|
|
43
|
+
name: "update_item",
|
|
44
|
+
type: "mutation",
|
|
45
|
+
hasArgs: true,
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("handles composite_query as query", () => {
|
|
50
|
+
const didContent = `service : {
|
|
51
|
+
search: (text) -> (vec Item) composite_query;
|
|
52
|
+
}`
|
|
53
|
+
const methods = extractMethods(didContent)
|
|
54
|
+
expect(methods[0].type).toBe("query")
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it("ignores comments", () => {
|
|
58
|
+
const didContent = `service : {
|
|
59
|
+
// This is a comment
|
|
60
|
+
get_data: () -> (text) query;
|
|
61
|
+
/* create_data: (text) -> (); */
|
|
62
|
+
}`
|
|
63
|
+
const methods = extractMethods(didContent)
|
|
64
|
+
expect(methods).toHaveLength(1)
|
|
65
|
+
expect(methods[0].name).toBe("get_data")
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it("extracts argument and return types correctly", () => {
|
|
69
|
+
const didContent = `service : {
|
|
70
|
+
weird_method: (record { foo: text; bar: nat }) -> (variant { Ok: null; Err: text }) query;
|
|
71
|
+
}`
|
|
72
|
+
const methods = extractMethods(didContent)
|
|
73
|
+
expect(methods[0].name).toBe("weird_method")
|
|
74
|
+
expect(methods[0].argsDescription).toContain(
|
|
75
|
+
"record { foo: text; bar: nat }"
|
|
76
|
+
)
|
|
77
|
+
expect(methods[0].returnDescription).toContain(
|
|
78
|
+
"variant { Ok: null; Err: text }"
|
|
79
|
+
)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
describe("formatMethodForDisplay", () => {
|
|
84
|
+
it("formats query method with args", () => {
|
|
85
|
+
const method: MethodInfo = {
|
|
86
|
+
name: "search",
|
|
87
|
+
type: "query",
|
|
88
|
+
hasArgs: true,
|
|
89
|
+
}
|
|
90
|
+
expect(formatMethodForDisplay(method)).toBe("search (query, with args)")
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it("formats update method without args", () => {
|
|
94
|
+
const method: MethodInfo = {
|
|
95
|
+
name: "init",
|
|
96
|
+
type: "mutation",
|
|
97
|
+
hasArgs: false,
|
|
98
|
+
}
|
|
99
|
+
expect(formatMethodForDisplay(method)).toBe("init (update, no args)")
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
})
|
package/src/did.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DID file parser
|
|
3
|
+
*
|
|
4
|
+
* Extracts method information from Candid interface definition files.
|
|
5
|
+
* Based on the CLI's parser implementation (with comment stripping).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "node:fs"
|
|
9
|
+
import type { MethodInfo } from "./types.js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Parse a .did file and extract method information
|
|
13
|
+
*/
|
|
14
|
+
export function parseDIDFile(didFilePath: string): MethodInfo[] {
|
|
15
|
+
if (!fs.existsSync(didFilePath)) {
|
|
16
|
+
throw new Error(`DID file not found: ${didFilePath}`)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const content = fs.readFileSync(didFilePath, "utf-8")
|
|
20
|
+
return extractMethods(content)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Extract methods from DID content
|
|
25
|
+
*
|
|
26
|
+
* Handles formats like:
|
|
27
|
+
* - `name : (args) -> (result)`
|
|
28
|
+
* - `name : (args) -> (result) query`
|
|
29
|
+
* - `name : (args) -> (result) composite_query`
|
|
30
|
+
* - `name : func (args) -> (result)`
|
|
31
|
+
*/
|
|
32
|
+
export function extractMethods(didContent: string): MethodInfo[] {
|
|
33
|
+
const methods: MethodInfo[] = []
|
|
34
|
+
|
|
35
|
+
// Remove comments
|
|
36
|
+
const cleanContent = didContent
|
|
37
|
+
.replace(/\/\/.*$/gm, "") // Single line comments
|
|
38
|
+
.replace(/\/\*[\s\S]*?\*\//g, "") // Multi-line comments
|
|
39
|
+
|
|
40
|
+
// Match method definitions
|
|
41
|
+
// Pattern: name : [func] (args) -> (result) [query|composite_query]
|
|
42
|
+
const methodRegex =
|
|
43
|
+
/([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*(?:func\s*)?\(([^)]*)\)\s*->\s*\(([^)]*)\)\s*(query|composite_query)?/g
|
|
44
|
+
|
|
45
|
+
let match
|
|
46
|
+
while ((match = methodRegex.exec(cleanContent)) !== null) {
|
|
47
|
+
const name = match[1]
|
|
48
|
+
const args = match[2].trim()
|
|
49
|
+
const returnType = match[3].trim()
|
|
50
|
+
const queryAnnotation = match[4]
|
|
51
|
+
|
|
52
|
+
// Determine if it's a query or mutation
|
|
53
|
+
const isQuery =
|
|
54
|
+
queryAnnotation === "query" || queryAnnotation === "composite_query"
|
|
55
|
+
|
|
56
|
+
methods.push({
|
|
57
|
+
name,
|
|
58
|
+
type: isQuery ? "query" : "mutation",
|
|
59
|
+
hasArgs: args.length > 0 && args !== "",
|
|
60
|
+
argsDescription: args || undefined,
|
|
61
|
+
returnDescription: returnType || undefined,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return methods
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get methods by type
|
|
70
|
+
*/
|
|
71
|
+
export function getMethodsByType(
|
|
72
|
+
methods: MethodInfo[],
|
|
73
|
+
type: "query" | "mutation"
|
|
74
|
+
): MethodInfo[] {
|
|
75
|
+
return methods.filter((m) => m.type === type)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Format method info for display
|
|
80
|
+
*/
|
|
81
|
+
export function formatMethodForDisplay(method: MethodInfo): string {
|
|
82
|
+
const typeLabel = method.type === "query" ? "query" : "update"
|
|
83
|
+
const argsLabel = method.hasArgs ? "with args" : "no args"
|
|
84
|
+
return `${method.name} (${typeLabel}, ${argsLabel})`
|
|
85
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ic-reactor/codegen
|
|
3
|
+
*
|
|
4
|
+
* Shared code generation utilities for IC Reactor.
|
|
5
|
+
* Used by both @ic-reactor/vite-plugin and @ic-reactor/cli.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Types
|
|
9
|
+
export type {
|
|
10
|
+
MethodInfo,
|
|
11
|
+
CanisterConfig,
|
|
12
|
+
HookType,
|
|
13
|
+
GeneratorOptions,
|
|
14
|
+
ReactorGeneratorOptions,
|
|
15
|
+
} from "./types.js"
|
|
16
|
+
|
|
17
|
+
// Naming utilities
|
|
18
|
+
export {
|
|
19
|
+
toPascalCase,
|
|
20
|
+
toCamelCase,
|
|
21
|
+
getHookFileName,
|
|
22
|
+
getHookExportName,
|
|
23
|
+
getReactHookName,
|
|
24
|
+
getReactorName,
|
|
25
|
+
getServiceTypeName,
|
|
26
|
+
} from "./naming.js"
|
|
27
|
+
|
|
28
|
+
// DID parsing
|
|
29
|
+
export {
|
|
30
|
+
parseDIDFile,
|
|
31
|
+
extractMethods,
|
|
32
|
+
getMethodsByType,
|
|
33
|
+
formatMethodForDisplay,
|
|
34
|
+
} from "./did.js"
|
|
35
|
+
|
|
36
|
+
// Bindgen utilities
|
|
37
|
+
export {
|
|
38
|
+
generateDeclarations,
|
|
39
|
+
declarationsExist,
|
|
40
|
+
saveCandidFile,
|
|
41
|
+
} from "./bindgen.js"
|
|
42
|
+
export type { BindgenOptions, BindgenResult } from "./bindgen.js"
|
|
43
|
+
|
|
44
|
+
// Template generators
|
|
45
|
+
export { generateReactorFile } from "./templates/reactor.js"
|
|
46
|
+
export { generateQueryHook } from "./templates/query.js"
|
|
47
|
+
export type { QueryHookOptions } from "./templates/query.js"
|
|
48
|
+
export { generateMutationHook } from "./templates/mutation.js"
|
|
49
|
+
export type { MutationHookOptions } from "./templates/mutation.js"
|
|
50
|
+
export { generateInfiniteQueryHook } from "./templates/infiniteQuery.js"
|
|
51
|
+
export type { InfiniteQueryHookOptions } from "./templates/infiniteQuery.js"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest"
|
|
2
|
+
import {
|
|
3
|
+
toPascalCase,
|
|
4
|
+
toCamelCase,
|
|
5
|
+
getHookFileName,
|
|
6
|
+
getHookExportName,
|
|
7
|
+
getReactHookName,
|
|
8
|
+
getReactorName,
|
|
9
|
+
getServiceTypeName,
|
|
10
|
+
} from "./naming"
|
|
11
|
+
|
|
12
|
+
describe("Naming Utilities", () => {
|
|
13
|
+
describe("Base Conversions", () => {
|
|
14
|
+
it("converts to PascalCase", () => {
|
|
15
|
+
expect(toPascalCase("get_user")).toBe("GetUser")
|
|
16
|
+
expect(toPascalCase("my-canister")).toBe("MyCanister")
|
|
17
|
+
expect(toPascalCase("list_items_v2")).toBe("ListItemsV2")
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it("converts to camelCase", () => {
|
|
21
|
+
expect(toCamelCase("get_user")).toBe("getUser")
|
|
22
|
+
expect(toCamelCase("my-canister")).toBe("myCanister")
|
|
23
|
+
expect(toCamelCase("ListItems")).toBe("listItems")
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe("Domain-Specific Naming", () => {
|
|
28
|
+
it("generates hook file names", () => {
|
|
29
|
+
expect(getHookFileName("get_user", "query")).toBe("getUserQuery.ts")
|
|
30
|
+
expect(getHookFileName("update_item", "mutation")).toBe(
|
|
31
|
+
"updateItemMutation.ts"
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it("generates hook export names", () => {
|
|
36
|
+
expect(getHookExportName("get_user", "query")).toBe("getUserQuery")
|
|
37
|
+
expect(getHookExportName("update_item", "mutation")).toBe(
|
|
38
|
+
"updateItemMutation"
|
|
39
|
+
)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it("generates React hook names", () => {
|
|
43
|
+
expect(getReactHookName("get_user", "query")).toBe("useGetUserQuery")
|
|
44
|
+
expect(getReactHookName("update_item", "mutation")).toBe(
|
|
45
|
+
"useUpdateItemMutation"
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("generates reactor names", () => {
|
|
50
|
+
expect(getReactorName("backend")).toBe("backendReactor")
|
|
51
|
+
expect(getReactorName("my-canister")).toBe("myCanisterReactor")
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it("generates service type names", () => {
|
|
55
|
+
expect(getServiceTypeName("backend")).toBe("BackendService")
|
|
56
|
+
expect(getServiceTypeName("my-canister")).toBe("MyCanisterService")
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
})
|
package/src/naming.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naming utilities for code generation
|
|
3
|
+
*
|
|
4
|
+
* Uses the `change-case` library for base transformations,
|
|
5
|
+
* with domain-specific helpers for IC Reactor patterns.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { camelCase, pascalCase } from "change-case"
|
|
9
|
+
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// BASE CASE CONVERSIONS
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Convert string to PascalCase
|
|
16
|
+
* @example toPascalCase("get_message") → "GetMessage"
|
|
17
|
+
* @example toPascalCase("my-canister") → "MyCanister"
|
|
18
|
+
*/
|
|
19
|
+
export function toPascalCase(str: string): string {
|
|
20
|
+
return pascalCase(str)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Convert string to camelCase
|
|
25
|
+
* @example toCamelCase("get_message") → "getMessage"
|
|
26
|
+
* @example toCamelCase("my-canister") → "myCanister"
|
|
27
|
+
*/
|
|
28
|
+
export function toCamelCase(str: string): string {
|
|
29
|
+
return camelCase(str)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
+
// DOMAIN-SPECIFIC NAMING
|
|
34
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Generate hook file name
|
|
38
|
+
* @example getHookFileName("get_message", "query") → "getMessageQuery.ts"
|
|
39
|
+
*/
|
|
40
|
+
export function getHookFileName(methodName: string, hookType: string): string {
|
|
41
|
+
const camelMethod = toCamelCase(methodName)
|
|
42
|
+
const pascalType = toPascalCase(hookType)
|
|
43
|
+
return `${camelMethod}${pascalType}.ts`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate hook export name
|
|
48
|
+
* @example getHookExportName("get_message", "query") → "getMessageQuery"
|
|
49
|
+
*/
|
|
50
|
+
export function getHookExportName(
|
|
51
|
+
methodName: string,
|
|
52
|
+
hookType: string
|
|
53
|
+
): string {
|
|
54
|
+
const camelMethod = toCamelCase(methodName)
|
|
55
|
+
const pascalType = toPascalCase(hookType)
|
|
56
|
+
return `${camelMethod}${pascalType}`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Generate React hook name (with use prefix)
|
|
61
|
+
* @example getReactHookName("get_message", "query") → "useGetMessageQuery"
|
|
62
|
+
*/
|
|
63
|
+
export function getReactHookName(methodName: string, hookType: string): string {
|
|
64
|
+
const pascalMethod = toPascalCase(methodName)
|
|
65
|
+
const pascalType = toPascalCase(hookType)
|
|
66
|
+
return `use${pascalMethod}${pascalType}`
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Generate reactor variable name
|
|
71
|
+
* @example getReactorName("backend") → "backendReactor"
|
|
72
|
+
*/
|
|
73
|
+
export function getReactorName(canisterName: string): string {
|
|
74
|
+
return `${toCamelCase(canisterName)}Reactor`
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Generate service type name
|
|
79
|
+
* @example getServiceTypeName("backend") → "BackendService"
|
|
80
|
+
*/
|
|
81
|
+
export function getServiceTypeName(canisterName: string): string {
|
|
82
|
+
return `${toPascalCase(canisterName)}Service`
|
|
83
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Infinite Query Hook Generation > generates infinite query hook correctly 1`] = `
|
|
4
|
+
"/**
|
|
5
|
+
* Infinite Query: list_items
|
|
6
|
+
*
|
|
7
|
+
* Auto-generated by @ic-reactor/codegen
|
|
8
|
+
*
|
|
9
|
+
* ⚠️ CUSTOMIZATION REQUIRED: Configure getArgs and getNextPageParam below.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { data, fetchNextPage, hasNextPage } = listItemsInfiniteQuery.useInfiniteQuery()
|
|
13
|
+
* const allItems = data?.pages.flatMap(page => page.items) ?? []
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { createInfiniteQuery } from "@ic-reactor/react"
|
|
17
|
+
import { myCanisterReactor, type MyCanisterService } from "../reactor"
|
|
18
|
+
|
|
19
|
+
/** Define your pagination cursor type */
|
|
20
|
+
type PageCursor = number
|
|
21
|
+
|
|
22
|
+
export const listItemsInfiniteQuery = createInfiniteQuery(myCanisterReactor, {
|
|
23
|
+
functionName: "list_items",
|
|
24
|
+
|
|
25
|
+
initialPageParam: 0 as PageCursor,
|
|
26
|
+
|
|
27
|
+
/** Convert page param to method arguments — customize for your API */
|
|
28
|
+
getArgs: (pageParam: PageCursor) => {
|
|
29
|
+
return [{ offset: pageParam, limit: 10 }] as Parameters<MyCanisterService["list_items"]>
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
/** Extract next page param — return undefined when no more pages */
|
|
33
|
+
getNextPageParam: (lastPage, allPages, lastPageParam) => {
|
|
34
|
+
// Example: offset-based
|
|
35
|
+
// if (lastPage.items.length < 10) return undefined
|
|
36
|
+
// return lastPageParam + 10
|
|
37
|
+
return undefined
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
/** React hook for paginated list_items */
|
|
42
|
+
export const useListItemsInfiniteQuery = listItemsInfiniteQuery.useInfiniteQuery
|
|
43
|
+
"
|
|
44
|
+
`;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Mutation Hook Generation > generates hook correctly for mutation with args 1`] = `
|
|
4
|
+
"/**
|
|
5
|
+
* Mutation: create_item
|
|
6
|
+
*
|
|
7
|
+
* Auto-generated by @ic-reactor/codegen
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const { mutate, isPending } = createItemMutation.useMutation()
|
|
11
|
+
* mutate([arg1, arg2])
|
|
12
|
+
*
|
|
13
|
+
* // Direct execution (outside React)
|
|
14
|
+
* const result = await createItemMutation.execute([arg1, arg2])
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createMutation } from "@ic-reactor/react"
|
|
18
|
+
import { myCanisterReactor } from "../reactor"
|
|
19
|
+
|
|
20
|
+
export const createItemMutation = createMutation(myCanisterReactor, {
|
|
21
|
+
functionName: "create_item",
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
/** React hook for create_item */
|
|
25
|
+
export const useCreateItemMutation = createItemMutation.useMutation
|
|
26
|
+
|
|
27
|
+
/** Execute create_item directly (outside React) */
|
|
28
|
+
export const executeCreateItem = createItemMutation.execute
|
|
29
|
+
"
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
exports[`Mutation Hook Generation > generates hook correctly for mutation without args 1`] = `
|
|
33
|
+
"/**
|
|
34
|
+
* Mutation: init_system
|
|
35
|
+
*
|
|
36
|
+
* Auto-generated by @ic-reactor/codegen
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* const { mutate, isPending } = initSystemMutation.useMutation()
|
|
40
|
+
* mutate([])
|
|
41
|
+
*
|
|
42
|
+
* // Direct execution (outside React)
|
|
43
|
+
* const result = await initSystemMutation.execute([])
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
import { createMutation } from "@ic-reactor/react"
|
|
47
|
+
import { myCanisterReactor } from "../reactor"
|
|
48
|
+
|
|
49
|
+
export const initSystemMutation = createMutation(myCanisterReactor, {
|
|
50
|
+
functionName: "init_system",
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
/** React hook for init_system */
|
|
54
|
+
export const useInitSystemMutation = initSystemMutation.useMutation
|
|
55
|
+
|
|
56
|
+
/** Execute init_system directly (outside React) */
|
|
57
|
+
export const executeInitSystem = initSystemMutation.execute
|
|
58
|
+
"
|
|
59
|
+
`;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Query Hook Generation > generates hook for query with arguments (factory) 1`] = `
|
|
4
|
+
"/**
|
|
5
|
+
* Query Factory: get_user
|
|
6
|
+
*
|
|
7
|
+
* Auto-generated by @ic-reactor/codegen
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const { data } = getUserQuery([arg1, arg2]).useQuery()
|
|
11
|
+
* const data = await getUserQuery([arg1, arg2]).fetch()
|
|
12
|
+
* getUserQuery([arg1, arg2]).invalidate()
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { createQueryFactory } from "@ic-reactor/react"
|
|
16
|
+
import { myCanisterReactor } from "../reactor"
|
|
17
|
+
|
|
18
|
+
export const getUserQuery = createQueryFactory(myCanisterReactor, {
|
|
19
|
+
functionName: "get_user",
|
|
20
|
+
})
|
|
21
|
+
"
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
exports[`Query Hook Generation > generates hook for query without arguments (static) 1`] = `
|
|
25
|
+
"/**
|
|
26
|
+
* Query: list_items
|
|
27
|
+
*
|
|
28
|
+
* Auto-generated by @ic-reactor/codegen
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const { data } = listItemsQuery.useQuery()
|
|
32
|
+
* const data = await listItemsQuery.fetch()
|
|
33
|
+
* listItemsQuery.invalidate()
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { createQuery } from "@ic-reactor/react"
|
|
37
|
+
import { myCanisterReactor } from "../reactor"
|
|
38
|
+
|
|
39
|
+
export const listItemsQuery = createQuery(myCanisterReactor, {
|
|
40
|
+
functionName: "list_items",
|
|
41
|
+
})
|
|
42
|
+
"
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
exports[`Query Hook Generation > generates suspense hooks correctly 1`] = `
|
|
46
|
+
"/**
|
|
47
|
+
* Query Factory: get_user
|
|
48
|
+
*
|
|
49
|
+
* Auto-generated by @ic-reactor/codegen
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const { data } = getUserSuspenseQuery([arg1, arg2]).useSuspenseQuery()
|
|
53
|
+
* const data = await getUserSuspenseQuery([arg1, arg2]).fetch()
|
|
54
|
+
* getUserSuspenseQuery([arg1, arg2]).invalidate()
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
import { createSuspenseQueryFactory } from "@ic-reactor/react"
|
|
58
|
+
import { myCanisterReactor } from "../reactor"
|
|
59
|
+
|
|
60
|
+
export const getUserSuspenseQuery = createSuspenseQueryFactory(myCanisterReactor, {
|
|
61
|
+
functionName: "get_user",
|
|
62
|
+
})
|
|
63
|
+
"
|
|
64
|
+
`;
|