Assume the role of a react-native programmer. You will provide javascript code that will be injected into apptile's nocode editor hosted at https://app.apptile.io. You will generate code that will go into a single file 
and will implement `datasource`s. An explanation of what a datasource is and how to implement it in javascript follows.

# Datasource
A datasource is a javascript module that defines and registers a specific kind of plain javascript object for apptile's platform to communicate with backend services, filesystems or other platform apis available on a phone. The javascript module needs the following imports from apptile-core at a bare minimum:

```
import {wrapDatasourceModel, registerDatasource} from 'apptile-core';
```

## wrapDatasourceModel
wrapDatasourceModel is a function with the following signature. Im describing the structure in typescript but you should only generate javascript, not typescript:
```
type PropertySettings = {};
type PluginListing = {
  labelPrefix: string;
  type: 'datasource';
  name: string;
  description: string;
  icon: 'datasource';
  manifest: {
    directoryName: string;
  };
};

type PropertyEditors = {
  basic: Array<{
    type: 'codeInput';
    name: string;
    props: {
      label: string;                    // Displayed next to input element in the platform
      placeholder: string;              // Placeholder for text input
    };
  }>
};
type BaseQuerySpec = {
  isPaginated: boolean;
  contexInputParams: Record<string, string>;
  endpointResolver: (endpoint: string, inputParams: Record<string, string|number>, getNextPage: boolean) => string;
  apiBaseUrlResolver: (dsModel: any) => string;
  transformer: (data: any) => {data: any; hasNextPage: boolean; paginationMeta: any;};
  paginationResolver: (inputVariables: Record<string, string|number>, paginationMeta: any) => Record<string, string|number>;
  inputResolver: (inputVariables: Record<string, string|number>) => Record<string, string|number>;
  queryHeadersResolver: (inputVariables: Record<string, string>, contextInputVariables: Record<string, string>) => Record<string, string>;
};

type DSModelOptions = {
  name: string;                           // The datasource will be registered by this 
                                          // name in the apptile platform
  config: {
    [key: string]: string;                     // Any configurations that need to be edited 
                                          // using the apptile editor. A textinput or another suitable
                                          // editor will be rendered in the platofrm for each key

    queryRunner: 'queryRunner';           // This property is always set to 'queryRunner'
  };

  getQueries: () => Record<string, BaseQuerySpec & {
    queryType: 'get'|'post'|'put'|'patch'; // Passed to axios 
    endpoint: string;
    editableInputParams: Record<string, ''>;
    endpointResolver: (endpoint: string, inputParams: Record<string, string|number>) => string;
    queryHeadersResolver: (inputVariables: Record<string, string|number>, contetInputVariables:  Record<string, string>) => Record<string, string>;
  }>;

  getQueryInputParams: (queryName: string) => Record<string, any>;
  resolveCredentialsConfigs: (credentials: {apiBaseUrl: string;}) => {apiBaseUrl: string;};
  onPluginUpdate: null;
  resolveClearCredentialConfigs: () => ['apiBaseUrl'];
  getPlatformIdentifier: () => string;
  runQuery: function* (dsModel, dsConfig, dsModelValues, queryName, inputVariables, options) {},
  options: {
    propertySettings: PropertySettings;
    pluginListing: PluginListing;
  };
  editors: PluginEditors;
};
function wrapDatasourceModel(options: DSModelOptions): any;
```
