{"id":25553758,"url":"https://github.com/docusign/extension-app-data-io-reference-implementation","last_synced_at":"2026-03-02T10:31:01.423Z","repository":{"id":249198472,"uuid":"830646070","full_name":"docusign/extension-app-data-io-reference-implementation","owner":"docusign","description":"Extension App for Data IO Reference Implementation for the Docusign IAM Platform","archived":false,"fork":false,"pushed_at":"2025-03-12T16:35:50.000Z","size":247,"stargazers_count":1,"open_issues_count":0,"forks_count":4,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-11T22:43:08.722Z","etag":null,"topics":["apps","data","extension"],"latest_commit_sha":null,"homepage":"https://developers.docusign.com/extension-apps/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docusign.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-18T17:20:38.000Z","updated_at":"2025-03-12T16:35:55.000Z","dependencies_parsed_at":"2024-07-19T07:31:08.313Z","dependency_job_id":"a5127bd7-319d-4399-ad9c-9fbc17e62e71","html_url":"https://github.com/docusign/extension-app-data-io-reference-implementation","commit_stats":null,"previous_names":["docusign/extension-app-data-io-reference-implementation"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fextension-app-data-io-reference-implementation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fextension-app-data-io-reference-implementation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fextension-app-data-io-reference-implementation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fextension-app-data-io-reference-implementation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docusign","download_url":"https://codeload.github.com/docusign/extension-app-data-io-reference-implementation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248492989,"owners_count":21113159,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apps","data","extension"],"created_at":"2025-02-20T12:01:31.780Z","updated_at":"2025-09-11T04:33:03.242Z","avatar_url":"https://github.com/docusign.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Data IO Extension App Reference Implementation\n## Introduction\nThis reference implementation models the implementation of data input and output functionalities in an [extension app](https://developers.docusign.com/extension-apps/).\n\nTo test a read-only data IO extension app, modify one of the `ReadOnlyManifest.json` files.\n\nTo test a data IO extension app with both read and write capabilities, modify one of the `ReadWriteManifest.json` files.\n\n## Authentication\nThis reference implementation supports two [authentication](https://developers.docusign.com/extension-apps/build-an-extension-app/it-infrastructure/authorization/) flows:\n* [Authorization Code Grant](https://developers.docusign.com/extension-apps/build-an-extension-app/it-infrastructure/authorization/#authorization-code-grant) – required for public extension apps\n* [Client Credentials Grant](https://developers.docusign.com/extension-apps/build-an-extension-app/it-infrastructure/authorization/#client-credentials-grant) – available to private extension apps. See [Choosing private distribution instead of public](https://developers.docusign.com/extension-apps/extension-apps-101/choosing-private-distribution/)\n\n*Private extension apps can use either authentication method, but public extension apps must use Authorization Code Grant.*\n\n```bash\nmanifests/\n  ├── authorizationCode/\n  │   ├── ReadOnlyManifest.json\n  │   └── ReadWriteManifest.json\n  ├── clientCredentials/\n  │   ├── ReadOnlyManifest.json\n  │   └── ReadWriteManifest.json\n  └── hosted/\n      ├── authorizationCode.ReadOnlyManifest.json\n      └── authorizationCode.ReadWriteManifest.json\n      └── clientCredentials.ReadOnlyManifest.json\n      └── clientCredentials.ReadWriteManifest.json\n```\n## Hosted Version (no setup required)\nYou can use the hosted version of this reference implementation by directly uploading the appropriate manifest file located in the [manifests/hosted/](manifests/hosted) folder to the Docusign Developer Console. See [Upload your manifest and create the data IO app](#3-upload-your-manifest-and-create-the-data-io-app).\n\n**Note:** The provided manifests include `clientId` and `clientSecret` values used in the sample authentication connection. These do not authenticate to a real system, but the hosted reference implementation requires these exact values.\n\n## Choose your setup: local or cloud deployment\nIf you want to run the app locally using Node.js and ngrok, follow the [Local setup instructions](#local-setup-instructions) below.\n\nIf you want to deploy the app to the cloud using Docker and Terraform, see [Deploying an extension app to the cloud with Terraform](terraform/README.md). This includes cloud-specific setup instructions for the following cloud providers:\n- [Amazon Web Services](https://aws.amazon.com/)\n- [Microsoft Azure](https://azure.microsoft.com/)\n- [Google Cloud Platform](https://cloud.google.com/)\n\n## Local setup instructions\n\n### Video Walkthrough\n[![Reference implementation videos](https://img.youtube.com/vi/_4p7GWK5aoA/0.jpg)](https://youtube.com/playlist?list=PLXpRTgmbu4orBQrYWPAXa4EBXv0IGGzID\u0026feature=shared)\n\n### 1. Clone the repository\nRun the following command to clone the repository: \n```bash\ngit clone https://github.com/docusign/extension-app-data-io-reference-implementation.git\n```\n\n### 2. Generate secret values\n- If you already have values for `JWT_SECRET_KEY`, `OAUTH_CLIENT_ID`, `OAUTH_CLIENT_SECRET`, and `AUTHORIZATION_CODE`, you may skip this step.\n\nThe easiest way to generate a secret value is to run the following command:\n```bash\nnode -e \"console.log(require('crypto').randomBytes(64).toString('hex'));\"\n```\n\nYou will need values for `JWT_SECRET_KEY`, `OAUTH_CLIENT_ID`, `OAUTH_CLIENT_SECRET`, and `AUTHORIZATION_CODE`.\n\n### 3. Set the environment variables for the cloned repository\n- If you're running this in a development environment, create a copy of `example.development.env` and save it as `development.env`.\n- If you're running this in a production environment, create a copy of `example.production.env` and save it as `production.env`.\n- Replace `JWT_SECRET_KEY`, `OAUTH_CLIENT_ID`, `OAUTH_CLIENT_SECRET`, and `AUTHORIZATION_CODE` in `development.env` or `production.env` with your generated values. These values will be used to configure the sample proxy's mock authentication server. \n- Set the `clientId` value in the manifest file to the same value as `OAUTH_CLIENT_ID`.\n- Set the `clientSecret` value in the manifest file to the same value as `OAUTH_CLIENT_SECRET`.\n### 4. [Install and configure Node.js and npm on your machine.](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)\n### 5. Install dependencies\nRun the following command to install the necessary dependencies:\n```bash\nnpm install\n```\n### 6. Running the proxy server\n#### Development mode:\nStart the proxy server in development mode by running the command:\n```bash\nnpm run dev\n```\n\nThis will create a local server on the port in the `development.env` file (port 3000 by default) that listens for local changes that trigger a rebuild.\n\n#### Production mode:\nStart the proxy server in production mode by running the following commands:\n```bash\nnpm run build\nnpm run start\n```\n\nThis will start a production build on the port in the `production.env` file (port 3000 by default). \n## Setting up ngrok\n### 1. [Install and configure ngrok for your machine.](https://ngrok.com/docs/getting-started/)\n### 2. Start ngrok\nRun the following command to create a public accessible tunnel to your localhost:\n\n```bash\nngrok http \u003cPORT\u003e\n```\n\nReplace `\u003cPORT\u003e` with the port number in the `development.env` or `production.env` file.\n\n### 3. Save the forwarding address\nCopy the `Forwarding` address from the response. You’ll need this address in your manifest file.\n\n```bash\nngrok                                                    \n\nSend your ngrok traffic logs to Datadog: https://ngrok.com/blog-post/datadog-log\n\nSession Status                online\nAccount                       email@domain.com (Plan: Free)\nUpdate                        update available (version 3.3.1, Ctrl-U to update)\nVersion                       3.3.0\nRegion                        United States (us)\nLatency                       60ms\nWeb Interface                 http://127.0.0.1:4040\nForwarding                    https://bbd7-12-202-171-35.ngrok-free.app -\u003e http:\n\nConnections                   ttl     opn     rt1     rt5     p50     p90\n                              0       0       0.00    0.00    0.00    0.00\n```\n\nIn this example, the `Forwarding` address to copy is `https://bbd7-12-202-171-35.ngrok-free.app`.\n## Create an extension app\n### 1. Prepare your app manifest\nReplace `\u003cPROXY_BASE_URL\u003e` in your manifest file with the ngrok forwarding address in the following sections:\n- `connections.params.customConfig.profile.url`\n- `connections.params.customConfig.tokenUrl`\n- `connections.params.customConfig.authorizationUrl`\n- `actions.params.uri`\n    * Replace this value for all of the actions.\n\n### 2. Navigate to the [Developer Console](https://devconsole.docusign.com/apps)\nLog in with your Docusign developer credentials and create a new app.\n\n### 3. Upload your manifest and create the data IO app\nTo [create your extension app](https://developers.docusign.com/extension-apps/build-an-extension-app/create/), open the [Developer Console](https://devconsole.docusign.com/apps) and select **+New App.** In the app manifest editor that opens, upload your manifest file or paste into the editor itself; then select Validate. Once the editor validates your manifest, select **Create App.** \n\n### 4. Test the extension app\nThis reference implementation uses mock data to simulate how data can be verified against a database. [Test your extension](https://developers.docusign.com/extension-apps/build-an-extension-app/test/) using the sample data in [fileDB.ts](https://github.com/docusign/extension-app-data-io-reference-implementation/blob/main/src/db/fileDB.ts). Extension app tests include [integration tests](https://developers.docusign.com/extension-apps/build-an-extension-app/test/integration-tests/) (connection tests and extension tests), [functional tests](https://developers.docusign.com/extension-apps/build-an-extension-app/test/functional-tests/), and [App Center preview](https://developers.docusign.com/extension-apps/build-an-extension-app/test/app-center-preview/). \n\n\n### Extension tests\nThe Developer Console offers five extension tests to verify that a data IO extension app can connect to and exchange data with third-party APIs (or an API proxy that in turn connects with those APIs). \n\n**Note:** These instructions only apply if you use the [mock data](https://github.com/docusign/extension-app-data-io-reference-implementation/blob/main/src/db/fileDB.ts) in the reference implementation. If you use your own database, you’ll need to construct your requests based on your own schema. Queries for extension tests in the Developer Console are built using [IQuery](https://developers.docusign.com/extension-apps/extension-app-reference/extension-contracts/custom-query-language/) structure. \n\n\n#### CreateRecord extension test\nTo begin the extension test process, run the CreateRecord test using the sample query below. The test should return a response containing the record ID.\n\n```json\n{\n  \"typeName\": \"Account\",\n  \"idempotencyKey\": \"NOT_USED_CURRENTLY\",\n  \"data\": {\n    \"Name\": \"Test Account\",\n    \"ShippingLatitude\": 10,\n    \"PushCount\": 6      \n  }\n}\n```\n\n![CreateRecord Test](https://github.com/user-attachments/assets/f962d007-2cab-49ce-a032-472cd214478d)\n\n\nAll record types are located in the `/src/db/` folder of this repository.\n\n![db folder](https://github.com/user-attachments/assets/06449adc-057e-44c8-a76e-8406b29ae13e)\n\n\nOpen the `Account.json` file in the `/src/db/` folder and check that the records were created.\n\n![Account.json](https://github.com/user-attachments/assets/37cca0e3-9113-4e01-a710-514b16763dbe)\n\n\n#### SearchRecords extension test\nThis query searches the records that have been created. You don’t have to use the same sample values used here; the search should work with a valid attribute in `Account.json`.\n\nOpen the SearchRecords test and create a new query based on the `Account.json` file:\n\n- The `from` attribute maps to the value of `typeName` in the CreateRecord query; in this case, `Account`.\n- The `data` array from the CreateRecord query maps to the `attributesToSelect` array; in this case, `Name`.\n- The `name` property of the `leftOperand` object should be the value of `Name`; in this case, `Test Account`.\n- The `operator` value should be `EQUALS`.\n- The `name` property of the `rightOperand` object should be the same as what's in `attributesToSelect` array; in this case, `Name`.\n\nThe query below has been updated based on the directions above. You can copy and paste this into the SearchRecords test input box.\n\n```json\n{\n    \"query\": {\n        \"$class\": \"com.docusign.connected.data.queries@1.0.0.Query\",\n        \"attributesToSelect\": [\n            \"Name\"\n        ],\n        \"from\": \"Account\",\n        \"queryFilter\": {\n            \"$class\": \"com.docusign.connected.data.queries@1.0.0.QueryFilter\",\n            \"operation\": {\n                \"$class\": \"com.docusign.connected.data.queries@1.0.0.ComparisonOperation\",\n                \"leftOperand\": {\n                    \"$class\": \"com.docusign.connected.data.queries@1.0.0.Operand\",\n                    \"name\": \"Test Account\",\n                    \"type\": \"STRING\",\n                    \"isLiteral\": true\n                },\n                \"operator\": \"EQUALS\",\n                \"rightOperand\": {\n                    \"$class\": \"com.docusign.connected.data.queries@1.0.0.Operand\",\n                    \"name\": \"Name\",\n                    \"type\": \"INTEGER\",\n                    \"isLiteral\": false\n                }\n            }\n        }\n    },\n    \"pagination\": {\n        \"limit\": 10,\n        \"skip\": 10\n    }\n}\n```\n\nRunning the test will return the record you queried.\n\n![new search records](https://github.com/user-attachments/assets/4e6e26e2-040b-43a1-b20c-f69c84bcf765)\n\n\n\n\n#### PatchRecord extension test\nThe `recordId` property in the sample input maps to an `Id` in the `Account.json` file. Any valid record ID can be used in this field.\n\nIn the `data` array, include any attributes and values to be added to the record. In this query, a new property will be added, and the original data in the record will be updated.\n\n```bash\n{\n  \"recordId\": \"2\",\n  \"typeName\": \"Account\",\n  \"idempotencyKey\": \"NOT_USED_CURRENTLY\",\n  \"data\": {\n    \"Name\": \"updatedTestAccount\",\n    \"ShippingLatitude\": 11,\n    \"PushCount\": 7,\n    \"MasterRecordId\": \"ABCD\"\n  }\n}\n```\n\nRunning the test should return the response `\"success\": true`.\n\n![PatchRecord test](https://github.com/user-attachments/assets/e445b06b-6790-475a-8434-c0eea1e003b3)\n\n\nRerun the SearchRecords extension test to search for the new patched values. \n\n**Input query:**\n\n```json\n{\n    \"query\": {\n        \"$class\": \"com.docusign.connected.data.queries@1.0.0.Query\",\n        \"attributesToSelect\": [\n            \"Name\"\n        ],\n        \"from\": \"Account\",\n        \"queryFilter\": {\n            \"$class\": \"com.docusign.connected.data.queries@1.0.0.QueryFilter\",\n            \"operation\": {\n                \"$class\": \"com.docusign.connected.data.queries@1.0.0.ComparisonOperation\",\n                \"leftOperand\": {\n                    \"$class\": \"com.docusign.connected.data.queries@1.0.0.Operand\",\n                    \"name\": \"updatedTestAccount\",\n                    \"type\": \"STRING\",\n                    \"isLiteral\": true\n                },\n                \"operator\": \"EQUALS\",\n                \"rightOperand\": {\n                    \"$class\": \"com.docusign.connected.data.queries@1.0.0.Operand\",\n                    \"name\": \"Name\",\n                    \"type\": \"INTEGER\",\n                    \"isLiteral\": false\n                }\n            }\n        }\n    },\n    \"pagination\": {\n        \"limit\": 10,\n        \"skip\": 10\n    }\n}\n```\n\n**Results:**\n\n![Results of SearchRecords after PatchRecord](https://github.com/user-attachments/assets/70dbce23-0c9d-4150-ab25-c853e92d695f)\n\n\nAlternatively, the `Account.json` file will contain the updated records. \n\n![Account.json after PatchRecord test](https://github.com/user-attachments/assets/ace8276b-2d36-4171-a598-2450e6d9b5fe)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocusign%2Fextension-app-data-io-reference-implementation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocusign%2Fextension-app-data-io-reference-implementation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocusign%2Fextension-app-data-io-reference-implementation/lists"}