{"id":21832024,"url":"https://github.com/neo4j-devtools/graph-app-starter","last_synced_at":"2025-03-21T13:33:16.124Z","repository":{"id":42108252,"uuid":"109478598","full_name":"neo4j-devtools/graph-app-starter","owner":"neo4j-devtools","description":"Resources to get started building Neo4j Desktop Graph Apps","archived":false,"fork":false,"pushed_at":"2023-04-01T06:33:09.000Z","size":4251,"stargazers_count":20,"open_issues_count":101,"forks_count":18,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-01-26T09:21:44.890Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neo4j-devtools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-11-04T08:19:45.000Z","updated_at":"2021-05-02T11:03:40.000Z","dependencies_parsed_at":"2023-01-25T23:31:11.303Z","dependency_job_id":"9f9cc860-c359-4f70-acc3-861590c2037e","html_url":"https://github.com/neo4j-devtools/graph-app-starter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-devtools%2Fgraph-app-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-devtools%2Fgraph-app-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-devtools%2Fgraph-app-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-devtools%2Fgraph-app-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neo4j-devtools","download_url":"https://codeload.github.com/neo4j-devtools/graph-app-starter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244806210,"owners_count":20513400,"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":[],"created_at":"2024-11-27T19:17:21.664Z","updated_at":"2025-03-21T13:33:16.083Z","avatar_url":"https://github.com/neo4j-devtools.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Neo4j Desktop Graph App API\n\nTo give a 3rd party applications the possibility to know,\nwhat active graph is and where it is contained, we provide a context.\n\nFirst of all, context expose to the apps all data, that could be viable for them to operate -\nconfigurations, projects, graphs.\n\nContext itself is an immutable structure which is generated on demand,\nbut all context changes are interceptable, so the apps could react to context changes immediately.\n\nCheck out [Changelog](CHANGELOG.md) to follow API changes.\n\nWe provide a Neo4j Desktop Canary channel with nightly builds of Neo4j Desktop so developers can verify that their graph application works in the coming release.  \nSee https://neo4j.com/download-center/ -\u003e Neo4j Desktop -\u003e Pre-releases.\n\n## Development mode\n\nNeo4j Desktop have `Development mode`.\n\nTo enable it, open `Settings` pane in Sidebar and toggle switch in `Developer tools` section.\n\n### Development mode settings\n\nWhen development mode is enabled, additional app is added to the list of other apps: `Development App`.\n\nDeveloper needs to setup entry point and application root directory for Graph App in settings.\n\nSettings:\n\n- Entry Point\n  - Supported formats:\n    - File: load `.html` file directly from filesystem\n      - Example: `file:///Users/me/work/graph-app/index.html`\n    - HTTP: load arbitrary `URL`\n      - Example: `http://localhost:3000`\n- Root Path\n  - Example: `/Users/me/work/graph-app`\n\n**Note:** settings are not saved between Neo4j Desktop restarts.\n\n![Developer Tools](images/developmentMode.png)\n\n## Example\n\nAvailable examples:\n\n- [Simple application created with create-react-app-graphql](examples/basic-create-react-app-graphql)\n- [Simple application executing Java](examples/basic-java-executor)\n\n#### Quickstart example\n\nTo prepare the graphQL connection, you'll need a set of libraries, we recommend using these\n\n```\nyarn add apollo-client apollo-link apollo-link-http apollo-link-ws\n```\n\nFor managing both subscriptions and queries, passing custom headers, you'll need these\n\n```\nyarn add apollo-link-context apollo-utilities\n```\n\nThe following code shows how to initialize the connection to the graphql server\n\n```ecmascript 6\n// All the necessary information is available in the url, as searchParams\nconst url = new URL(window.location.href);\n// Url of a graphQL endpoint\nconst apiEndpoint = url.searchParams.get('neo4jDesktopApiUrl');\n\n// Parse API endpoint URL to get scheme-less\nconst apiEndpointUrl = new URL(apiEndpoint)\nconst apiEndpointNoScheme = `${apiEndpointUrl.host}${\n    apiEndpointUrl.pathname ? apiEndpointUrl.pathname : ''\n}`\n\n// A Desktop generated token to verify the provided appId\nconst apiClientId = url.searchParams.get('neo4jDesktopGraphAppClientId');\n\n// http link to execute graphQL queries\nconst httpLink = createHttpLink({\n        uri: apiEndpoint,\n});\n\n// websocket link to be able to subscribe to the Desktop events\nconst wsLink = new WebSocketLink({\n    uri: `ws://${apiEndpointNoScheme}`,\n    options: {\n        reconnect: true,\n        connectionParams: {\n            ClientId: apiClientId\n        }\n    }\n});\n\n// link needed to inject custom headers to every query,\n// so that Neo4j Desktop could identify the graph app and give as much data as it can\nconst authLink = setContext((_, {headers}) =\u003e {\n    return {\n        headers: {\n            ...headers,\n            ClientId: apiClientId\n        }\n    }\n});\n\n// general link, used to choose a correct endpoint between the operation types\nconst link = split(\n    // split based on operation type\n    ({query}) =\u003e {\n        const {kind, operation} = getMainDefinition(query);\n        return kind === 'OperationDefinition' \u0026\u0026 operation === 'subscription';\n    },\n    wsLink,\n    authLink.concat(httpLink),\n);\n\n// at this point client is ready to use\nconst client = new ApolloClient({\n    link: link,\n    cache: new InMemoryCache()\n});\n\n```\n\nAfter the client has been initialized, you can execute queries and start subscriptions to the Desktop GraphQL server.\nThe format of the output data is almost the same as it was before, when contextAPI was in place.\n\n```js\nclient.query({\n    query: /* your query */\n}).then(({data}) =\u003e {\n    // do something with data here\n});\n\nconst observable = client.subscribe({\n    query: /* subscribe query */\n});\nobservable.subscribe(({data}) =\u003e {\n    // do something with data here, this callback will be triggered every time Desktop has its data changed\n});\n```\n\nExtended example you can find [here](examples/basic-create-react-app)\n\nAlso the fallback API is still being injected into the graph apps, so that you could still use the API in the old way.\n\n**Note** that fallback API is deprecated and will be removed in a future Neo4j Desktop release (the exact date is not known yet, wait for the announcement).\n\n```js\n/**\n * If application can run in multiple environments, detect that we are in Desktop.\n */\nif (window.neo4jDesktopApi) {\n  // API will be available in global `window` variable `neo4jDesktopApi`.\n\n  // Listen for context changes\n  neo4jDesktopApi.onContextUpdate((event, newContext, oldContext) =\u003e {\n    if (event.type === \"...\") {\n      // do something if event is of specific type\n    }\n\n    // check context changes and apply them\n  });\n\n  // Get current context.\n  // Should be used if application requires current context when it starts.\n  neo4jDesktopApi.getContext().then(context =\u003e {\n    // initialize application with context\n  });\n}\n```\n\n## Distribution\n\n### Structure\n\nGraph applications should be distributed as a valid [npm package file](https://docs.npmjs.com/files/package.json),\nwhere `dist` folder contains a default app entry point `index.html`.\n\n### Installation\n\nTo install a self updating graph application, you enter a link to a npm style repository for the graph application.  \nExample for neo4j-browser: `http://neo.jfrog.io/neo/api/npm/npm/neo4j-browser`.  \nThis application will self update on every release (see below for how to display release notes).\n\nor\n\nPack and upload a `.tgz` file (following the structure explained above) and enter the URL to it in the graph application sidebar. This will be downloaded once and never updated.\n\nor\n\nHost a web application yourself and \"install\" it by inserting the URL to it in the graph application sidebar.\n\n### Neo4j Desktop API version support\n\nManifest file `manifest.json` should be placed in `/dist` folder and contain information about the Graph App. Including Neo4j Desktop API version that is used.\n_Note:_ You can either specify explicit `apiVersion` or semver range.\n\nThe fallback is using the `package.json` file if no manifest file is found.\n\nExample:\n\n```json\n{\n  \"name\": \"my-graph-app\",\n  \"version\": \"1.0.0\",\n  \"description\": \"(desktop)-[:LOVES]-\u003e(apps)\",\n  \"homepage\": \"http://neo4j.com\",\n  \"neo4jDesktop\": {\n    \"apiVersion\": \"^1.2.0\"\n  }\n}\n```\n\n### Graph application metadata\n\n**For packages graph applications**\n\nNeo4j Desktop scans `manifest.json` for the fields `neo4jDesktop`, `name`, `description`, `icons`, and `homepage` to show the values of these fields\non the UI.  \nTo customize the look of the graph app inside Neo4j Desktop - include an icon to the distribution and add `icons`\nproperty to the `manifest.json`.\n\n_Note:_ The paths should be relative to the location of the manifest file where they are specified:\n\n- If they are specified in `package.json`, their src should be relative to the graph app root.\n- If they are specified in `dist/manifest.json` their src should be relative to the `dist/` folder.\n\nIcon type could be any image type, or inline data URI.\nExample:\n\n```json\n{\n  \"name\": \"my-graph-app\",\n  \"description\": \"(desktop)-[:LOVES]-\u003e(apps)\",\n  \"icons\": [\n    {\n      \"src\": \"./my-image.png\",\n      \"type\": \"png\"\n    },\n    {\n      \"src\": \"./my-vector-image.svg\",\n      \"type\": \"svg\"\n    },\n    {\n      \"src\": \"data:image/svg+xml;base64,[data]\",\n      \"type\": \"data\"\n    }\n  ],\n  \"homepage\": \"http://neo4j.com\"\n}\n```\n\n**For online/hosted graph applications**\n\nNeo4j Desktop looks for a `manifest.json` in the web root and look for a `\u003cname\u003e` tag to derive graph app name. The icon will be fetched from the `\u003clink rel=\"icon\"\u003e` tag if it exists.\n\nThe fallback is using the documents `\u003ctitle\u003e` tag if no manifest file is found.\n\n### Graph application release notes on updates\n\nInclude `release-notes.md` on the same level as `package.json` to have Neo4j Desktop display your applications release notes when it's updated.\n\n**Notes:**\n\n- Ensure that `neo4jDesktop.apiVersion` is properly configured.\n- Ensure that package have proper structure.\n\n## Requesting permissions\n\nIf a graph application needs to use a privileged API (such as bundled Java or Node.js script execution), the app has to check and request the appropriate permission. Declare that your app needs a permission by listing the permission in the app manifest and then request that the user approve each permission at runtime.\n\n### Declare permissions in the manifest\n\nTo declare that your app needs a permission, put a `permissions` field in your app `manifest.json`\n\nExample:\n\n```json\n{\n  \"name\": \"my-graph-app\",\n  \"permissions\": [\"backgroundProcess\", \"allGraphs\", \"activeGraph\"]\n}\n```\n\nCurrently available permissions:\n\n| Permission        | Description                                                                                     |\n| ----------------- | ----------------------------------------------------------------------------------------------- |\n| activeGraph       | Gives access to the active Graph data.\u003cbr\u003e This is a default permission granted on app install. |\n| allGraphs         | Gives access to all the configured Graphs.                                                      |\n| backgroundProcess | Gives access to `executeJava` and `executeNode` API.                                            |\n\n**Explain why the app needs permissions**\n\nTo help the user understand why your app needs a permission, add usage description to the list of permissions in form of map-like object:\n\n```json\n{\n  \"name\": \"my-graph-app\",\n  \"permissions\": [\n    \"activeGraph\",\n    {\n      \"backgroundProcess\": \"Allow background processes to see output of demo Java class\",\n      \"allGraphs\": \"Another usage description here\"\n    }\n  ]\n}\n```\n\n### Check for permission\n\nTo check if you have a permission, call the `checkPermission()` method.\n\n```js\nwindow.neo4jDesktopApi.checkPermission(\"backgroundProcess\").then(granted =\u003e {\n  if (!granted) {\n    // Permission is not granted.\n  }\n});\n```\n\n### Request the permission\n\nIf your app doesn't already have the permission it needs, call `requestPermission()` method to request the appropriate permission from user. Only permissions declared in app manifest can be requested.\n\n```js\nwindow.neo4jDesktopApi.requestPermission(\"backgroundProcess\").then(granted =\u003e {\n  if (granted) {\n    // Permission granted.\n  } else {\n    // Permission denied.\n  }\n});\n```\n\nIf the permission has not been already granted, the system dialog box is shown:\n\n![Permission Request](images/requestPermission.png)\n\n## Plugin dependencies\n\nA graph application may specify database plugins required for the graph app to work. It is applicable for any locally installed and on-premise graph apps.\nTo specify the dependencies, add `pluginDependencies` section to `manifest.json` file.\n\nFor example:\n\n```json\n{\n  \"name\": \"my-graph-app\",\n  \"pluginDependencies\": [\n    \"org.neo4j.procedure/apoc\",\n    \"org.neo4j/graph-algorithms-algo\",\n    \"org.neo4j/neo4j-graphql\"\n  ]\n}\n```\n\nA dependency format is Maven coordinates of a plugin: `groupdId/artifactId`. A compatible plugin version is resolved at runtime. Neo4j Desktop automatically installs the required plugins to all the databases in a project having the graph application enabled.\n\n## Technical details\n\n#### Application data location\n\n| OS                  | Location                                    |\n| ------------------- | ------------------------------------------- |\n| macOS               | ~/Library/Application Support/Neo4j Desktop |\n| Windows pre 1.0.19  | %APPDATA%/Neo4j Desktop                     |\n| Windows post 1.0.19 | %USERPROFILE%/.Neo4jDesktop                 |\n| Linux               | ~/.config/Neo4j Desktop                     |\n\n## Reference\n\n_Note:_ API is under development and it can be changed, based on user feedback.\n\n_Note:_ API definition is presented using TypeScript syntax.\n\n```typescript\nexport interface DesktopApi {\n  /**\n   * API version.\n   */\n  version: string;\n\n  /**\n   * Asynchronously get current context.\n   */\n  getContext: () =\u003e Promise\u003cContext\u003e;\n\n  /**\n   * Register callback to receive context updates when events are happening.\n   */\n  onContextUpdate: (\n    callback: (event: Event, newContext: Context, oldContext: Context) =\u003e void\n  ) =\u003e void;\n\n  /**\n   *  Execute any jar, bundled inside you app package or given path. Will return wrapped process with API provided\n   */\n  executeJava: (parameters: JavaParameters) =\u003e Promise\u003cProcess\u003e;\n\n  /**\n   *  Execute any node script, bundled inside you app package or given path.\n   *  Will return wrapped process with API provided\n   */\n  executeNode: (\n    filePath: string,\n    args: [string],\n    options: ExecOptions\n  ) =\u003e Promise\u003cProcess\u003e;\n\n  /**\n   * Requests a permission from user.\n   * Only permissions declared in `manifest.json` can be requested.\n   *\n   * Permissions types:\n   *\n   * activeGraph         access active Graph data\n   * allGraphs           access to all the configured Graphs\n   * backgroundProcess   execute background Java and Node.js processes\n   *\n   * @param permission\n   * @return true if permission is granted\n   */\n  requestPermission: (permission: PermissionType) =\u003e Promise\u003cboolean\u003e;\n\n  /**\n   * Check if a permission is granted.\n   * @param permission\n   */\n  checkPermission: (permission: PermissionType) =\u003e Promise\u003cboolean\u003e;\n\n  /**\n   * Asynchronously get kerberos ticket for given service principal\n   * Service principal can be found in context\n   */\n  getKerberosTicket: (\n    servicePrincipal: string\n  ) =\u003e Promise\u003cKerberosTicketResult\u003e;\n\n  /**\n   * Register callback to receive arguments updates\n   * paramsString - pures string with params. ex.: cmd=play\u0026args=music\n   * params - parsed params Map ([key: string]: string | null)\n   *\n   * How to call graph-app with param - neo4j://GraphAppName?cmd=play\u0026args=music\n   */\n  onArgumentsChange: (\n    callback: (paramsString: string, params: ParamsMap) =\u003e void\n  ) =\u003e void;\n\n  getJwtToken: (dbId: string) =\u003e Promise\u003cJWTTokenResult\u003e;\n}\n\nexport interface ParamsMap {\n  [key: string]: string | null;\n}\n\nexport type PermissionType = \"activeGraph\" | \"allGraphs\" | \"backgroundProcess\";\n\n//---------------\n// Java\n//---------------\n\nexport type JavaParameters =\n  /**\n   * Specify class or jar that should be executed.\n   * Path to a .jar file can either be relative to App Path or absolute.\n   * Example: 'Main'\n   * Example: './test.jar'\n   */\n  { [x in \"class\" | \"jar\"]: string } \u0026 {\n    /**\n     * JVM arguments.\n     * Example: ['-DmyProperty=value', '-Xdebug']\n     */\n    options: string[];\n\n    /**\n     * Jar's that will be added to classpath.\n     * Example: ['./test.jar', '/opt/lib/test.jar']\n     */\n    classpath: string[];\n\n    /**\n     * Argument passed to a main.\n     * Example: ['one', 'two', 'three']\n     */\n    arguments: string[];\n  };\n\ntype ProcessStatus = \"RUNNING\" | \"STOPPED\" | \"KILLED\";\n\ninterface Process {\n  /**\n   * Stop the process tree gracefully, if fails - kill the process tree forcefully\n   */\n  stop(): Promise\u003cboolean\u003e;\n\n  /**\n   * Get the actual status of the process\n   */\n  status(): Promise\u003cProcessStatus\u003e;\n\n  /**\n   * Get the list of PIDs for whole process tree\n   */\n  getProcessTreeIds(): Promise\u003cnumber[]\u003e;\n\n  /**\n   * Listen to process-related errors (e.g. not being able to start)\n   */\n  onError(listener: (error: Error) =\u003e void): void;\n\n  /**\n   * Listen to process exit event. Provides the status which was assigned the last.\n   */\n  onExit(listener: (status: ProcessStatus) =\u003e void): void;\n\n  /**\n   * Attach to the stdout stream\n   */\n  addOutListener(listener: (data: string) =\u003e void): void;\n\n  /**\n   * Attach to the stderr stream\n   */\n  addErrListener(listener: (errData: string) =\u003e void): void;\n}\n\n//---------------\n// Node\n//---------------\n\ninterface EnvOptions {\n  [key: string]: string;\n}\n\nexport interface ExecOptions {\n  cwd?: string;\n  env?: EnvOptions;\n}\n\n//---------------\n// Kerberos\n//---------------\n\ninterface KerberosTicketResult {\n  ticket?: string;\n  error?: string;\n}\n\n//---------------\n// JWT\n//---------------\n\nexport interface JWTTokenResult {\n  token?: string;\n  error?: string;\n}\n\n//---------------\n// Context\n//---------------\n\nexport interface Context {\n  global: {\n    settings: Settings;\n    online: boolean;\n  };\n  projects: Project[];\n  activationKeys: GraphAppLicense[];\n}\n\nexport interface GraphAppLicense {\n  featureName: string;\n  expirationDate: string;\n  activationVersion: string;\n  featureVersion: string;\n  registrant: string;\n  organization: string;\n  email: string;\n  signature: string;\n}\n\nexport interface Settings {\n  allowSendStats: boolean;\n  allowSendReports: boolean;\n  allowStoreCredentials: boolean;\n}\n\nexport interface Project {\n  id: string;\n  name: string;\n  graphs: Graph[];\n}\n\nexport interface Graph {\n  id: string;\n  name: string;\n  description: string;\n  status: \"ACTIVE\" | \"INACTIVE\";\n  connection: GraphLocalConnection | GraphRemoteConnection;\n}\n\nexport interface GraphLocalConnection {\n  type: \"LOCAL\";\n  databaseType: \"neo4j\";\n  databaseStatus: GraphLocalConnectionStatus;\n  info: {\n    version: string;\n    edition: string;\n  };\n  configuration: GraphLocalConnectionConfiguration;\n}\n\nexport interface GraphLocalConnectionConfiguration {\n  path: string;\n  protocols: {\n    bolt: {\n      enabled: boolean;\n      host: string;\n      port: number;\n      tlsLevel: \"OPTIONAL\" | \"REQUIRED\" | \"DISABLED\";\n      username?: string;\n      password?: string;\n      url: string;\n    };\n    http: {\n      enabled: boolean;\n      host: string;\n      port: number;\n      url: string;\n    };\n    https: {\n      enabled: boolean;\n      host: string;\n      port: number;\n      url: string;\n    };\n  };\n  authenticationMethods?: {\n    kerberos: {\n      enabled: boolean;\n    };\n  };\n}\n\nexport type GraphLocalConnectionStatus =\n  | \"STOPPED\"\n  | \"STOPPING\"\n  | \"STARTING\"\n  | \"RESTARTING\"\n  | \"RUNNING\"\n  | \"UNKNOWN\"\n  | \"NEW\"\n  | \"CREATING\"\n  | \"REMOVING\"\n  | \"UPGRADING\"\n  | \"MISSING\";\n\nexport interface GraphRemoteConnection {\n  type: \"REMOTE\";\n  databaseType: \"neo4j\";\n  databaseStatus: GraphRemoteConnectionStatus;\n  info: {\n    version: \"UNKNOWN\" | string;\n    edition: \"UNKNOWN\" | string;\n  };\n  configuration: GraphRemoteConnectionProtocols;\n}\n\nexport interface GraphRemoteConnectionProtocols {\n  protocols: {\n    bolt: {\n      enabled: boolean;\n      host: string;\n      port: number;\n      tlsLevel: \"OPTIONAL\" | \"REQUIRED\" | \"DISABLED\";\n      username?: string;\n      password?: string;\n      url: string;\n    };\n    http: {\n      enabled: boolean;\n      host: string;\n      port: number;\n      url: string;\n    };\n    https: {\n      enabled: boolean;\n      host: string;\n      port: number;\n      url: string;\n    };\n  };\n  authenticationMethods?: {\n    kerberos: {\n      enabled: boolean;\n      servicePrincipal?: string;\n    };\n  };\n}\n\nexport type GraphRemoteConnectionStatus =\n  | \"UNKNOWN\"\n  | \"NEW\"\n  | \"CREATING\"\n  | \"REMOVING\"\n  | \"ACTIVATING\"\n  | \"AVAILABLE\"\n  | \"UPDATING\"\n  | \"NOT_AVAILABLE\"\n  | \"INVALID_PASSWORD\"\n  | \"DEACTIVATING\"\n  | \"DEACTIVATED\";\n\n//---------------\n// Events\n//---------------\n\nexport type Event =\n  | ApplicationOnlineEvent\n  | ApplicationOfflineEvent\n  | ProjectCreatedEvent\n  | ProjectRemovedEvent\n  | ProjectRenamedEvent\n  | GraphActiveEvent\n  | GraphInactiveEvent\n  | DatabaseCreatedEvent\n  | DatabaseStartedEvent\n  | DatabaseStoppedEvent\n  | DatabaseRenamedEvent\n  | DatabaseRemovedEvent\n  | DatabaseUpdatedEvent\n  | DatabaseUpgradedEvent\n  | DatabaseSettingsSavedEvent\n  | RemoteConnectionCreatedEvent\n  | RemoteConnectionRemovedEvent\n  | RemoteConnectionActivatedEvent\n  | RemoteConnectionDeactivatedEvent;\n\ninterface ApplicationOnlineEvent {\n  type: \"APPLICATION_ONLINE\";\n}\n\ninterface ApplicationOfflineEvent {\n  type: \"APPLICATION_OFFLINE\";\n}\n\ninterface ProjectCreatedEvent {\n  type: \"PROJECT_CREATED\";\n  id: string;\n  name: string;\n}\n\ninterface ProjectRemovedEvent {\n  type: \"PROJECT_REMOVED\";\n  id: string;\n}\n\ninterface ProjectRenamedEvent {\n  type: \"PROJECT_RENAMED\";\n  id: string;\n  name: string;\n}\n\ninterface GraphActiveEvent {\n  type: \"GRAPH_ACTIVE\";\n  id: string;\n}\n\ninterface GraphInactiveEvent {\n  type: \"GRAPH_INACTIVE\";\n  id: string;\n}\n\ninterface DatabaseCreatedEvent {\n  type: \"DATABASE_CREATED\";\n  id: string;\n  projectId: string;\n  name: string;\n  description: string;\n  status: GraphLocalConnectionStatus;\n  version: string;\n  edition: \"community\" | \"enterprise\";\n}\n\ninterface DatabaseStartedEvent {\n  type: \"DATABASE_STARTED\";\n  id: string;\n}\n\ninterface DatabaseStoppedEvent {\n  type: \"DATABASE_STOPPED\";\n  id: string;\n}\n\ninterface DatabaseRenamedEvent {\n  type: \"DATABASE_RENAMED\";\n  id: string;\n  name: string;\n}\n\ninterface DatabaseRemovedEvent {\n  type: \"DATABASE_REMOVED\";\n  id: string;\n}\n\ninterface DatabaseUpdatedEvent {\n  type: \"DATABASE_UPDATED\";\n  id: string;\n  database: {\n    description: string;\n  };\n}\n\ninterface DatabaseUpgradedEvent {\n  type: \"DATABASE_UPGRADED\";\n  id: string;\n  version: string;\n}\n\ninterface DatabaseSettingsSavedEvent {\n  type: \"DATABASE_SETTINGS_SAVED\";\n  id: string;\n}\n\ninterface RemoteConnectionCreatedEvent {\n  type: \"REMOTE_CONNECTION_CREATED\";\n  id: string;\n}\n\ninterface RemoteConnectionRemovedEvent {\n  type: \"REMOTE_CONNECTION_REMOVED\";\n  id: string;\n}\n\ninterface RemoteConnectionActivatedEvent {\n  type: \"REMOTE_CONNECTION_ACTIVATED\";\n  id: string;\n}\n\ninterface RemoteConnectionDeactivatedEvent {\n  type: \"REMOTE_CONNECTION_DEACTIVATED\";\n  id: string;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneo4j-devtools%2Fgraph-app-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneo4j-devtools%2Fgraph-app-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneo4j-devtools%2Fgraph-app-starter/lists"}