Files
directus/sdk/readme.md
Brainslug d71b0e94ee SDK Revamp (#18987)
* Setup build chain

* Initial structure

* Typing, exports, fix build

* Reorganize

* prutsen met output types

* Thursday fun times

* failed experiments in feature composition

* got feature flags on the client

* using interfaces instead of literals

* messed with decorators

* split up decorators

* added fetch and ws types

* reintroduced the global.d.ts we'll figure that out later

* reworked composables

* some changes

* experimenting with commands

* got the read item command working again with types

* trying authentication

* basic gql implementation

* Super basic websocket implementation

* renamed websocket composable and removed obsolete code

* Typing relational fields

Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>

* fixed recursive type

* SDK revamp revamp (#18916)

* Split up files

* Simplify some more (too much?)

* Oh boy we figured out object extending

* OK JK now we're there

* OK getting somewhere real now

* Start structuring type helpers

* Types werken zowaar!

* Remove unneeded "T"'s for readability

* Added support for array relational types

* split up query nesting logic

* make relational fields optional to support multiple relations

* improved readability

* updated REST

* Move URL to top level

* Remove T

* recursively join fields in params

* cleaning up

* updated graphql implementation

* removing old unused code

---------

Co-authored-by: Brainslug <tim@brainslug.nl>

* Reduce global reuse of rest

* Start messing with output types

* Return it from the rest command

* first level schema output filtering

* It works!! but will need some docs for context

* Added some comments

* removed export keyword from types that do not need to be exported

* cleaned up debug script

* graphql update

* Added dom for WebSocket and Fetch typings

* initial readme setup

* moved some types

* removed accidental commit

* Refactor `useDirectus` and improve token handling (#18966)

* Add comment and reduce code of useDirectus

* Add fabian-hiller to contributors.yml

* Change token handling of useDirectus client

---------

Co-authored-by: Brainslug <br41nslug@users.noreply.github.com>

* Change ClientConfig type back to interface (#18968)

* initial realtime feature

* started on some ws commands and implemented message receiving callback

* disabled rest config for now

* setup auth extension boilerplate

* Added some websocket examples to the readme

* docs: add getting started guide

* docs: add link to previous sdk

* docs: updates

* implemented readItem

* updated readItems

* Added delete commands

* docs: updates to snippets and phrasing

* updated lockfile

* Update dictionary

* docs: removed repeated typescript snippet

* Enrich package.json for SDK

* docs: update snippet

* Fix casing of readme

* added create items commands

* fixed read items output

* removed obsolete types

* added update commands

* updated tsup

* removed unused dependencies

* implemented basic memory storage fallback

* implemented the login function for auth

* implemented refresh and logout auth functions

* docs: update guide

* updated auth refresh logic

* oops, have to actually store the expires at value

* fixed authentication timeout

* added autoRefresh config option

* updated readme

* updated getting started

* docs: updates to guide

* added beta version nr

* removed debug scripts

* added docblocks to the composables

* Added some docblocks

* Added BETA warning to readme

* Added extra type extends object checks

* added a bunch of index files

* updated tsup build entrypoints and exports

* updated import paths

* updated code examples

* docs: removed unnecessary phrases

* Unignore SDK changesets

* Revert "docs: removed unnecessary phrases"

This reverts commit 3559ade873.

* docs: removed unnecessary phrases

* Make sure we export all available functions

* Tweak exports

* Add TypeDoc for new (and old) SDK

* Update docs/guides/sdk/getting-started.md

* Re-add beta version flag in package.json

* Format readme

* Tweaks

* Spellchecker

* v10.4.0

* Add link to TypeDoc of new SDK

* updated query types

* trying to expand the query types

* extending the Query options

* add all exports to the root

* fixed incorrect field mapping

* Abstracted more  of the request logic for more flexibility

* partial error handling, global fetch settings and fetch response options

* reworked the requests for better options control and started on better error handling

* type fix

* Run formatter & linter

* Spell fixes

* added onRequest handler

* updated global request hooks

* expanded ItemType to accept singletons

* updated output types for singletons

* fixed fields type generation

* removed rest globaloptions in favor of onRequest

* started singleton command

* different commands for singletons

* ran prettier

* updated readme

* stateless helpers for tomorrow

* support m2a in field types

* added m2a fields parsing and attempt at output typing

* made the base client stateless

* making sure things are exported as needed

* added minimal core table schema for files and users

* added update singleton command

* Added core user read commands

* merged related commands into the same file

* Added create users commands

* Added user update commands

* added user delete commands

* updated query handling

* ran prettier and bumped version

* ran prettier

* disabled global error handling for now

* fixed output formatting for delete commands

* fixed onResponse handling

* fixed item types for create and update

* added missing partial item for create

* ran prettier

* updated readme

* added missing export

* Publish beta version

* Added a bunch of core collection types

* updated users commands

* added more complex core types

* double checked nullable core fields

* fixed core collection merging with custom properties

* added authentication commands

* ran prettier and fixed line endings

* Added all core read commands

* Added all core create commands

* Added all core delete commands

* Added all core update commands

* ran prettier

* renamed `useDirectus` to `createDirectus` and `.use` to `.with` to prevent naming confusion with reacthooks or express middleware.

* ran prettier

* added more misc core commands

* added schema endpoints

* added server api commands

* ran prettier

* added most utility endpoints

* finished utility endpoints

* checking the command typing and jsdoc

* fixed those pesky relational output types

* ran prettier

* removed obsolete type

* initial aggregation typing

* improved aggregation and grouping typing

* ran prettier

* checked exports

* Beta 4

* fixed the m2a fields regression

* added basic client test

* do query parsing at the latest stage

* extra type comments

* reverted accidental commit and ran prettier

* Adjust tsconfig to updated @directus/tsconfig package

* updated websocket event handling

* fixed capitalization

* removed obsolete queryToParams usage

* implemented websocket reconnecting and some non-happy path fixes

* persist subscription across reconnecting

* updated readme

* ran prettier

* 11.0.0-beta.5

* using plurar for uploadFiles ad removed "D" from updateFiles

* fix incorrect paths

* created new util types file

* extracted output types

* fixed input typing issue (for items)

* extracted functions to its own file

* fixed path for presets

* ran prettier

* Applied typing fix to all commands

* fixed naming error `updatedItems` -> `updateItems`

* fixed type error

* Failing types gracefully if no schema is provided

* beta.6

* Clean-up tsup config

- Use documented way to define config
- Doesn't need to be ts file: not type checked, intellisense available
  in vscode anyway
- remove default & deprecated options

* added other user commands

* added other share commands

* satisfy prettier

* added string array types to webhook core schema

* fixed plain string request output

* keep nullability for relational fields

* Update documentation guides to use new SDK (#19131)

Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
Co-authored-by: Kevin Lewis <kvn@lws.io>
Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
Co-authored-by: Brainslug <tim@brainslug.nl>

* Fix error messages for core collections

* updated dictionary

* updated partial item input for fields

* Ready, set, go!

---------

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
Co-authored-by: Fabian Hiller <35291865+fabian-hiller@users.noreply.github.com>
Co-authored-by: Esther Agbaje <folasadeagbaje@gmail.com>
Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
Co-authored-by: Esther Agbaje <53586167+estheragbaje@users.noreply.github.com>
Co-authored-by: Kevin Lewis <kvn@lws.io>
2023-07-25 14:46:06 -04:00

3.8 KiB

Directus JavaScript SDK

The design goals for this rebuild:

  • TypeScript first
  • Modular/Composable architecture
  • Lightweight and Dependency Free

Composable Client

The client is split up in separate features you can mix and match to compose a client with only the features you need or want.

const client = createDirectus<Schema>('https://api.directus.io');

This client is currently an empty wrapper without any functionality.Before you can do anything with it you'll need to add some features. The following composables are available/in progress:

  • rest() REST request functions
    • adds .request(...) on the client
  • graphql() GraphQL request functions
    • adds .query(...) on the client
  • staticToken() authentication functions
    • adds .getToken() and .setToken() on the client
  • authenticate() authentication functions
    • adds .login({ email, password }), .logout(), .refresh() on the client
    • adds .getToken() and .setToken() on the client
  • realtime() websocket connectivity
    • adds .subscribe(...), .sendMessage(...), .onWebsocket('message', (message) => {}) on the client

For this example we'll build a client including rest and graphql:

const client = createDirectus<Schema>('https://api.directus.io').with(rest()).with(graphql());

// do a REST request
const restResult = await client.request(readItems('articles'));

// do a GraphQL request
const gqlResult = await client.query<OutputType>(`
    query {
        articles {
            id
            title
            author {
                first_name
            }
        }
    }
`);

Authentication

const client = createDirectus<Schema>('https://api.directus.io').with(rest()).with(authentication('json'));

await client.login('admin@example.com', 'd1r3ctu5');

// do authenticated requests
const client = createDirectus<Schema>('https://api.directus.io').with(rest()).with(staticToken('super-secure-token'));

// do authenticated requests

Real-Time

The realtime() extension allows you to work with a Directus REST WebSocket.

Subscribing to updates:

const client = createDirectus<Schema>('https://api.directus.io').with(
	realtime({
		authMode: 'public',
	})
);

const { subscription, unsubscribe } = await client.subscribe('test', {
	query: { fields: ['*'] },
});

for await (const item of subscription) {
	console.log('subscription', { item });
}

// unsubscribe()

Receive/Send messages:

const client = createDirectus<Schema>('https://api.directus.io').with(
	realtime({
		authMode: 'public',
	})
);

const stop = client.onWebSocket('message', (message) => {
	if ('type' in message && message['type'] === 'pong') {
		console.log('PONG received');
		stop();
	}
});

client.sendMessage({ type: 'ping' });

Build Your Schema

// The main schema type containing all collections available
interface MySchema {
	collection_a: CollectionA[]; // regular collections are array types
	collection_b: CollectionB[];
	collection_c: CollectionC; // this is a singleton
	// junction collections are collections too
	collection_a_b_m2m: CollectionAB_Many[];
	collection_a_b_m2a: CollectionAB_Any[];
}

// collection A
interface CollectionA {
	id: number;
	status: string;
	// relations
	m2o: number | CollectionB;
	o2m: number[] | CollectionB[];
	m2m: number[] | CollectionAB_Many[];
	m2a: number[] | CollectionAB_Any[];
}

// Many-to-Many junction table
interface CollectionAB_Many {
	id: number;
	collection_a_id: CollectionA;
	collection_b_id: CollectionB;
}

// Many-to-Any junction table
interface CollectionAB_Any {
	id: number;
	collection_a_id: CollectionA;
	collection: 'collection_b' | 'collection_c';
	item: string | CollectionB | CollectionC;
}

// collection B
interface CollectionB {
	id: number;
	value: string;
}

// singleton collection
interface CollectionC {
	id: number;
	app_settings: string;
	something: string;
}