From 295b02f5faf294263f4e525645ca4d7a20b7fe48 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 17 Jul 2023 12:51:42 -0500 Subject: [PATCH 1/4] added custom bindgen uri option to codegen command --- packages/cli/lang/en.json | 2 + packages/cli/lang/es.json | 2 + packages/cli/src/commands/codegen.ts | 8 ++- packages/cli/src/lib/codegen/CodeGenerator.ts | 3 ++ packages/cli/src/lib/option-parsers/uri.ts | 17 ++++++ packages/cli/src/lib/project/AppProject.ts | 5 +- packages/cli/src/lib/project/PluginProject.ts | 5 +- .../cli/src/lib/project/PolywrapProject.ts | 3 +- packages/cli/src/lib/project/Project.ts | 1 + packages/schema/bind/src/index.ts | 11 +++- yarn.lock | 53 +++++++++++++++---- 11 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 packages/cli/src/lib/option-parsers/uri.ts diff --git a/packages/cli/lang/en.json b/packages/cli/lang/en.json index 4f1ebb374a..5d2ec6b6ad 100644 --- a/packages/cli/lang/en.json +++ b/packages/cli/lang/en.json @@ -92,7 +92,9 @@ "commands_codegen_options_m": "Path to the Polywrap manifest file (default: {default})", "commands_codegen_options_o": "Output directory for custom generated types (default: 'types/')", "commands_codegen_options_o_path": "path", + "commands_codegen_options_b": "Uri for custom bindgen wrap (must implement wrap-abi-bindgen interface; see https://github.com/polywrap/wrap-abi-bindgen)", "commands_codegen_success": "Types were generated successfully", + "commands_codegen_invalid_uri": "Invalid WRAP URI format: {uri}.", "commands_codegen_project_load_error": "Failed to load project, please make sure {manifestPath} is a valid Project manifest", "commands_codegen_options_publish": "Output path for the built schema and manifest (default: {default})", "commands_create_description": "Create New Projects", diff --git a/packages/cli/lang/es.json b/packages/cli/lang/es.json index 4f1ebb374a..5d2ec6b6ad 100644 --- a/packages/cli/lang/es.json +++ b/packages/cli/lang/es.json @@ -92,7 +92,9 @@ "commands_codegen_options_m": "Path to the Polywrap manifest file (default: {default})", "commands_codegen_options_o": "Output directory for custom generated types (default: 'types/')", "commands_codegen_options_o_path": "path", + "commands_codegen_options_b": "Uri for custom bindgen wrap (must implement wrap-abi-bindgen interface; see https://github.com/polywrap/wrap-abi-bindgen)", "commands_codegen_success": "Types were generated successfully", + "commands_codegen_invalid_uri": "Invalid WRAP URI format: {uri}.", "commands_codegen_project_load_error": "Failed to load project, please make sure {manifestPath} is a valid Project manifest", "commands_codegen_options_publish": "Output path for the built schema and manifest (default: {default})", "commands_create_description": "Create New Projects", diff --git a/packages/cli/src/commands/codegen.ts b/packages/cli/src/commands/codegen.ts index 3968cdbf65..e2d4e739f6 100644 --- a/packages/cli/src/commands/codegen.ts +++ b/packages/cli/src/commands/codegen.ts @@ -18,6 +18,7 @@ import { import { ScriptCodegenerator } from "../lib/codegen/ScriptCodeGenerator"; import { DEFAULT_CODEGEN_DIR } from "../lib/defaults"; import { watchProject } from "../lib/watchProject"; +import { parseUriOption } from "../lib/option-parsers/uri"; import { PolywrapClient } from "@polywrap/client-js"; @@ -27,6 +28,7 @@ const defaultManifestStr = defaultPolywrapManifestFiles.join(" | "); export interface CodegenCommandOptions extends BaseCommandOptions { manifestFile: string; codegenDir: string | false; + bindgen: string | false; script: string | false; clientConfig: string | false; wrapperEnvs: string | false; @@ -51,6 +53,7 @@ export const codegen: Command = { default: DEFAULT_CODEGEN_DIR, })}` ) + .option(`-b, --bindgen `, `${intlMsg.commands_codegen_options_b()}`) .option( `-s, --script <${pathStr}>`, `${intlMsg.commands_codegen_options_s()}` @@ -77,6 +80,7 @@ export const codegen: Command = { defaultProjectManifestFiles ), codegenDir: parseDirOptionNoDefault(options.codegenDir), + bindgen: options.bindgen || false, script: parseCodegenScriptOption(options.script), clientConfig: options.clientConfig || false, wrapperEnvs: options.wrapperEnvs || false, @@ -95,6 +99,7 @@ async function run(options: Required) { clientConfig, wrapperEnvs, codegenDir, + bindgen, script, verbose, quiet, @@ -102,7 +107,7 @@ async function run(options: Required) { watch, } = options; const logger = createLogger({ verbose, quiet, logFile }); - + const bindgenUri = parseUriOption(bindgen); const envs = await parseWrapperEnvsOption(wrapperEnvs); const configBuilder = await parseClientConfigOption(clientConfig); @@ -142,6 +147,7 @@ async function run(options: Required) { codegenDirAbs: codegenDir || undefined, schemaComposer, project, + bindgenUri, }); const execute = async (): Promise => { diff --git a/packages/cli/src/lib/codegen/CodeGenerator.ts b/packages/cli/src/lib/codegen/CodeGenerator.ts index 46a16e8bf8..1aee32cde4 100644 --- a/packages/cli/src/lib/codegen/CodeGenerator.ts +++ b/packages/cli/src/lib/codegen/CodeGenerator.ts @@ -21,11 +21,13 @@ import { CodegenOverrides, tryGetCodegenOverrides } from "./CodegenOverrides"; import path from "path"; import { BindLanguage } from "@polywrap/schema-bind"; import { writeDirectorySync } from "@polywrap/os-js"; +import { Uri } from "@polywrap/core-js"; export interface CodeGeneratorConfig { project: Project; schemaComposer: SchemaComposer; codegenDirAbs?: string; + bindgenUri?: Uri; } export class CodeGenerator { @@ -89,6 +91,7 @@ export class CodeGenerator { const binding = await this._config.project.generateSchemaBindings( abi, codegenDir, + this._config.bindgenUri?.toString(), bindConfig ); diff --git a/packages/cli/src/lib/option-parsers/uri.ts b/packages/cli/src/lib/option-parsers/uri.ts new file mode 100644 index 0000000000..2986d34d4a --- /dev/null +++ b/packages/cli/src/lib/option-parsers/uri.ts @@ -0,0 +1,17 @@ +import { intlMsg } from "../intl"; + +import { Uri } from "@polywrap/core-js"; + +export function parseUriOption( + uri: string | undefined | false +): Uri | undefined { + if (uri) { + try { + return Uri.from(uri); + } catch { + console.error(intlMsg.commands_codegen_invalid_uri({ uri })); + process.exit(1); + } + } + return undefined; +} diff --git a/packages/cli/src/lib/project/AppProject.ts b/packages/cli/src/lib/project/AppProject.ts index 371786057a..1e6dd30efe 100644 --- a/packages/cli/src/lib/project/AppProject.ts +++ b/packages/cli/src/lib/project/AppProject.ts @@ -113,7 +113,8 @@ export class AppProject extends Project { public async generateSchemaBindings( abi: WrapAbi, - generationSubPath?: string + generationSubPath?: string, + bindgenUri?: string ): Promise { const bindLanguage = appManifestLanguageToBindLanguage( await this.getManifestLanguage() @@ -128,7 +129,7 @@ export class AppProject extends Project { }, outputDirAbs: await this.getGenerationDirectory(generationSubPath), }; - return bindSchema(options); + return bindSchema(options, bindgenUri); } private _getGenerationDirectory( diff --git a/packages/cli/src/lib/project/PluginProject.ts b/packages/cli/src/lib/project/PluginProject.ts index 9da9a5d046..583f5d9046 100644 --- a/packages/cli/src/lib/project/PluginProject.ts +++ b/packages/cli/src/lib/project/PluginProject.ts @@ -117,7 +117,8 @@ export class PluginProject extends Project { public async generateSchemaBindings( abi: WrapAbi, - generationSubPath?: string + generationSubPath?: string, + bindgenUri?: string ): Promise { const moduleDirectory = await this.getGenerationDirectory( generationSubPath @@ -141,7 +142,7 @@ export class PluginProject extends Project { outputDirAbs: moduleDirectory, }; - return bindSchema(options); + return bindSchema(options, bindgenUri); } private _getGenerationDirectory( diff --git a/packages/cli/src/lib/project/PolywrapProject.ts b/packages/cli/src/lib/project/PolywrapProject.ts index bd0f3ef337..a15688aa8e 100644 --- a/packages/cli/src/lib/project/PolywrapProject.ts +++ b/packages/cli/src/lib/project/PolywrapProject.ts @@ -153,6 +153,7 @@ export class PolywrapProject extends Project { public async generateSchemaBindings( abi: WrapAbi, generationSubPath?: string, + bindgenUri?: string, bindConfig?: Record ): Promise { const codegenDirectory = await this.getGenerationDirectory( @@ -178,7 +179,7 @@ export class PolywrapProject extends Project { config: bindConfig, }; - return bindSchema(options); + return bindSchema(options, bindgenUri); } /// Polywrap Build Manifest (polywrap.build.yaml) diff --git a/packages/cli/src/lib/project/Project.ts b/packages/cli/src/lib/project/Project.ts index 03cc4b7b24..8fc8903153 100644 --- a/packages/cli/src/lib/project/Project.ts +++ b/packages/cli/src/lib/project/Project.ts @@ -73,6 +73,7 @@ export abstract class Project { public abstract generateSchemaBindings( abi: Abi, generationSubPath?: string, + bindgenUri?: string, bindConfig?: Record ): Promise; diff --git a/packages/schema/bind/src/index.ts b/packages/schema/bind/src/index.ts index 422198454a..8826be6c4c 100644 --- a/packages/schema/bind/src/index.ts +++ b/packages/schema/bind/src/index.ts @@ -1,5 +1,6 @@ import { BindOptions, BindOutput } from "./types"; import { getGenerateBindingFn } from "./bindings"; +import * as WrapBindgen from "./bindings/wrap-bindgen"; import Mustache from "mustache"; @@ -9,6 +10,12 @@ Mustache.escape = (value) => value; export * from "./types"; export * from "./bindings"; -export async function bindSchema(options: BindOptions): Promise { - return await getGenerateBindingFn(options.bindLanguage)(options); +export async function bindSchema( + options: BindOptions, + uri?: string +): Promise { + if (uri) { + return WrapBindgen.getGenerateBindingFn(uri)(options); + } + return getGenerateBindingFn(options.bindLanguage)(options); } diff --git a/yarn.lock b/yarn.lock index 2415cf732f..23fd596643 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3232,6 +3232,18 @@ array.prototype.reduce@^1.0.5: es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -3661,9 +3673,9 @@ camelcase@^6.0.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001503: - version "1.0.30001515" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz#418aefeed9d024cd3129bfae0ccc782d4cb8f12b" - integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== + version "1.0.30001516" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz#621b1be7d85a8843ee7d210fd9d87b52e3daab3a" + integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== capture-exit@^2.0.0: version "2.0.0" @@ -4438,9 +4450,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.4.431: - version "1.4.460" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.460.tgz#f360a5059c039c4a5fb4dfa99680ad8129dd9f84" - integrity sha512-kKiHnbrHME7z8E6AYaw0ehyxY5+hdaRmeUbjBO22LZMdqTYCO29EvF0T1cQ3pJ1RN5fyMcHl1Lmcsdt9WWJpJQ== + version "1.4.461" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.461.tgz#6b14af66042732bf883ab63a4d82cac8f35eb252" + integrity sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ== elliptic@6.5.4: version "6.5.4" @@ -4514,11 +4526,12 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: - version "1.21.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.3.tgz#8aaa0ffc080e8a6fef6ace72631dc1ec5d47bf94" - integrity sha512-ZU4miiY1j3sGPFLJ34VJXEqhpmL+HGByCinGHv4HC+Fxl2fI2Z4yR6tl0mORnDr6PA8eihWo4LmSWDbvhALckg== + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-set-tostringtag "^2.0.1" @@ -4545,10 +4558,13 @@ es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" safe-regex-test "^1.0.0" string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" @@ -9732,6 +9748,25 @@ type@^2.7.2: resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-byte-offset@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" From a294dff2b3d9ca5e3a1af6213f2a7384c828d400 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 17 Jul 2023 12:54:50 -0500 Subject: [PATCH 2/4] added custom bindgen uri option to build command --- packages/cli/src/commands/build.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts index c13365018e..5b457c3766 100644 --- a/packages/cli/src/commands/build.ts +++ b/packages/cli/src/commands/build.ts @@ -28,6 +28,7 @@ import { } from "../lib/build-strategies"; import { DEFAULT_CODEGEN_DIR } from "../lib/defaults"; import { watchProject } from "../lib/watchProject"; +import { parseUriOption } from "../lib/option-parsers/uri"; import { PolywrapClient } from "@polywrap/client-js"; import { PolywrapManifest } from "@polywrap/polywrap-manifest-types-js"; @@ -46,6 +47,7 @@ const supportedProjectTypes = [ export interface BuildCommandOptions extends BaseCommandOptions { manifestFile: string; outputDir: string; + bindgen: string | false; clientConfig: string | false; wrapperEnvs: string | false; noCodegen: boolean; @@ -72,6 +74,7 @@ export const build: Command = { default: defaultOutputDir, })}` ) + .option(`-b, --bindgen `, `${intlMsg.commands_codegen_options_b()}`) .option( `-c, --client-config <${intlMsg.commands_common_options_configPath()}>`, `${intlMsg.commands_common_options_config()}` @@ -112,6 +115,7 @@ export const build: Command = { clientConfig: options.clientConfig || false, wrapperEnvs: options.wrapperEnvs || false, outputDir: parseDirOption(options.outputDir, defaultOutputDir), + bindgen: options.bindgen || false, noCodegen: !options.codegen || false, codegenDir: parseDirOptionNoDefault(options.codegenDir), strategy: options.strategy || defaultStrategy, @@ -167,6 +171,7 @@ async function run(options: Required) { clientConfig, wrapperEnvs, outputDir, + bindgen, strategy, noCodegen, codegenDir, @@ -176,7 +181,7 @@ async function run(options: Required) { } = options; const logger = createLogger({ verbose, quiet, logFile }); - + const bindgenUri = parseUriOption(bindgen); const envs = await parseWrapperEnvsOption(wrapperEnvs); const configBuilder = await parseClientConfigOption(clientConfig); @@ -243,6 +248,7 @@ async function run(options: Required) { project, schemaComposer, codegenDirAbs: codegenDir || undefined, + bindgenUri, }); const codegenSuccess = await codeGenerator.generate(); From 0977ff5e1013a721c658046faf5f10fb02250309 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 17 Jul 2023 13:29:30 -0500 Subject: [PATCH 3/4] added custom bindgen uri test --- .../cli/src/__tests__/e2e/p2/codegen.spec.ts | 19 +++++++++++++++++++ yarn.lock | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts b/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts index 060b9611d4..0fdafdfb2d 100644 --- a/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts +++ b/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts @@ -188,4 +188,23 @@ describe("e2e tests for codegen command", () => { rimraf.sync(`${getTestCaseDir(1)}/types`); }); + + it("Should successfully generate types with custom bindgen wrap", async () => { + rimraf.sync(`${getTestCaseDir(0)}/types`); + + const { exitCode: code, stdout: output, stderr: error } = await Commands.codegen({ + bindgen: "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/wrap-rust" + }, { + cwd: getTestCaseDir(0), + cli: polywrapCli, + }); + + expect(code).toEqual(0); + expect(error).toBe(""); + expect(clearStyle(output)).toContain( + `🔥 Types were generated successfully 🔥` + ); + + rimraf.sync(`${getTestCaseDir(0)}/types`); + }); }); diff --git a/yarn.lock b/yarn.lock index 23fd596643..039c66d460 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4450,9 +4450,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.4.431: - version "1.4.461" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.461.tgz#6b14af66042732bf883ab63a4d82cac8f35eb252" - integrity sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ== + version "1.4.462" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.462.tgz#4faf5072bb5f55269d35ca9dc7475e7bf91b1ac3" + integrity sha512-ux2LqN9JKRBDKXMT+78jtiBLPiXf+rLtYlsrOg5Qn7uv6Cbg7+9JyIalE3wcqkOdB2wPCUYNWAuL7suKRMHe9w== elliptic@6.5.4: version "6.5.4" From 8efe03b6b3e6de4e3c5506916c5d35c2183405dd Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 17 Jul 2023 13:36:55 -0500 Subject: [PATCH 4/4] updated codegen help test --- packages/cli/src/__tests__/e2e/p2/codegen.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts b/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts index 0fdafdfb2d..ba388daa40 100644 --- a/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts +++ b/packages/cli/src/__tests__/e2e/p2/codegen.spec.ts @@ -16,6 +16,9 @@ Options: (default: polywrap.yaml | polywrap.yml) -g, --codegen-dir Output directory for the generated code (default: ./src/wrap) + -b, --bindgen Uri for custom bindgen wrap (must + implement wrap-abi-bindgen interface; see + https://github.com/polywrap/wrap-abi-bindgen) -s, --script Path to a custom generation script (JavaScript | TypeScript) -c, --client-config Add custom configuration to the