diff --git a/src/metagen/src/client_py/static/client.py b/src/metagen/src/client_py/static/client.py index d77766eb4..d3131ef62 100644 --- a/src/metagen/src/client_py/static/client.py +++ b/src/metagen/src/client_py/static/client.py @@ -192,11 +192,13 @@ def selection_to_nodes( SelectionT = typing.TypeVar("SelectionT") -@dc.dataclass class File: - content: bytes - name: str - mimetype: typing.Optional[str] = None + def __init__( + self, content: bytes, name: str, mimetype: typing.Optional[str] = None + ): + self.content = content + self.name = name + self.mimetype = mimetype # @@ -613,11 +615,21 @@ def build_req( if len(files) > 0: form_data = MultiPartForm() form_data.add_field("operations", body) + file_map = {} map = {} - for idx, (path, file) in enumerate(files.items()): - map[idx] = ["variables" + path] - form_data.add_file(f"{idx}", file) + for path, file in files.items(): + array = file_map.get(file) + variable = "variables" + path + if array is not None: + array.append(variable) + else: + file_map[file] = [variable] + + for idx, (file, variables) in enumerate(file_map.items()): + key = str(idx) + map[key] = variables + form_data.add_file(key, file) form_data.add_field("map", json.dumps(map)) headers.update({"Content-type": form_data.get_content_type()}) diff --git a/tests/metagen/metagen_test.ts b/tests/metagen/metagen_test.ts index 9f6751f6e..3104218d1 100644 --- a/tests/metagen/metagen_test.ts +++ b/tests/metagen/metagen_test.ts @@ -656,26 +656,28 @@ Meta.test( assertEquals(res.code, 0); const expectedSchemaU1 = zod.object({ - upload: zod.boolean(), + upload: zod.literal(true), + }); + const expectedSchemaU2 = zod.object({ + uploadFirst: zod.literal(true), + uploadSecond: zod.literal(true), }); const expectedSchemaUn = zod.object({ - uploadMany: zod.boolean(), + uploadMany: zod.literal(true), }); - const expectedSchema = zod.tuple([ - expectedSchemaU1, - // expectedSchemaU1, - expectedSchemaUn, - expectedSchemaU1, - expectedSchemaUn, - ]); - const cases = [ { name: "client_rs_upload", skip: false, command: $`cargo run`.cwd(join(scriptsPath, "rs_upload")), - expected: expectedSchema, + expected: zod.tuple([ + expectedSchemaU1, + // expectedSchemaU1, + expectedSchemaUn, + expectedSchemaU1, + expectedSchemaUn, + ]), }, { name: "client_py_upload", @@ -683,7 +685,11 @@ Meta.test( command: $`bash -c "python main.py"`.cwd( join(scriptsPath, "py_upload"), ), - expected: zod.tuple([expectedSchemaU1, expectedSchemaUn]), + expected: zod.tuple([ + expectedSchemaU1, + expectedSchemaUn, + expectedSchemaU2, + ]), }, { name: "client_ts_upload", @@ -691,7 +697,11 @@ Meta.test( command: $`bash -c "deno run -A main.ts"`.cwd( join(scriptsPath, "ts_upload"), ), - expected: zod.tuple([expectedSchemaU1, expectedSchemaUn]), + expected: zod.tuple([ + expectedSchemaU1, + expectedSchemaUn, + expectedSchemaU2, + ]), }, ]; diff --git a/tests/metagen/typegraphs/sample/py/client.py b/tests/metagen/typegraphs/sample/py/client.py index b45cd8cb4..c1d09cedf 100644 --- a/tests/metagen/typegraphs/sample/py/client.py +++ b/tests/metagen/typegraphs/sample/py/client.py @@ -195,11 +195,13 @@ def selection_to_nodes( SelectionT = typing.TypeVar("SelectionT") -@dc.dataclass class File: - content: bytes - name: str - mimetype: typing.Optional[str] = None + def __init__( + self, content: bytes, name: str, mimetype: typing.Optional[str] = None + ): + self.content = content + self.name = name + self.mimetype = mimetype # @@ -616,11 +618,21 @@ def build_req( if len(files) > 0: form_data = MultiPartForm() form_data.add_field("operations", body) + file_map = {} map = {} - for idx, (path, file) in enumerate(files.items()): - map[idx] = ["variables" + path] - form_data.add_file(f"{idx}", file) + for path, file in files.items(): + array = file_map.get(file) + variable = "variables" + path + if array is not None: + array.append(variable) + else: + file_map[file] = [variable] + + for idx, (file, variables) in enumerate(file_map.items()): + key = str(idx) + map[key] = variables + form_data.add_file(key, file) form_data.add_field("map", json.dumps(map)) headers.update({"Content-type": form_data.get_content_type()}) diff --git a/tests/metagen/typegraphs/sample/py_upload/client.py b/tests/metagen/typegraphs/sample/py_upload/client.py index ec62c7a73..ff3873dfe 100644 --- a/tests/metagen/typegraphs/sample/py_upload/client.py +++ b/tests/metagen/typegraphs/sample/py_upload/client.py @@ -195,11 +195,13 @@ def selection_to_nodes( SelectionT = typing.TypeVar("SelectionT") -@dc.dataclass class File: - content: bytes - name: str - mimetype: typing.Optional[str] = None + def __init__( + self, content: bytes, name: str, mimetype: typing.Optional[str] = None + ): + self.content = content + self.name = name + self.mimetype = mimetype # @@ -616,11 +618,21 @@ def build_req( if len(files) > 0: form_data = MultiPartForm() form_data.add_field("operations", body) + file_map = {} map = {} - for idx, (path, file) in enumerate(files.items()): - map[idx] = ["variables" + path] - form_data.add_file(f"{idx}", file) + for path, file in files.items(): + array = file_map.get(file) + variable = "variables" + path + if array is not None: + array.append(variable) + else: + file_map[file] = [variable] + + for idx, (file, variables) in enumerate(file_map.items()): + key = str(idx) + map[key] = variables + form_data.add_file(key, file) form_data.add_field("map", json.dumps(map)) headers.update({"Content-type": form_data.get_content_type()}) diff --git a/tests/metagen/typegraphs/sample/py_upload/main.py b/tests/metagen/typegraphs/sample/py_upload/main.py index 6282d3321..9f0700f9f 100644 --- a/tests/metagen/typegraphs/sample/py_upload/main.py +++ b/tests/metagen/typegraphs/sample/py_upload/main.py @@ -36,4 +36,13 @@ } ) -print(json.dumps([res1, res2])) +file = File(b"Hello", "reusable.txt") + +res3 = gql.mutation( + { + "uploadFirst": api.upload({"file": file, "path": "python/first.txt"}), + "uploadSecond": api.upload({"file": file, "path": "python/second.txt"}), + } +) + +print(json.dumps([res1, res2, res3])) diff --git a/tests/metagen/typegraphs/sample/ts_upload/main.ts b/tests/metagen/typegraphs/sample/ts_upload/main.ts index e14d24856..5f20b59b6 100644 --- a/tests/metagen/typegraphs/sample/ts_upload/main.ts +++ b/tests/metagen/typegraphs/sample/ts_upload/main.ts @@ -24,4 +24,11 @@ const res2 = await gql.mutation({ }), }); -console.log(JSON.stringify([res1, res2])); +const file = new File(["Hello"], "reusable.txt", { type: "text/plain" }); + +const res3 = await gql.mutation({ + uploadFirst: qg.upload({ file, path: "deno/first.txt" }), + uploadSecond: qg.upload({ file, path: "deno/second.txt" }), +}); + +console.log(JSON.stringify([res1, res2, res3]));