File size: 2,878 Bytes
61d39e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Puter Extensions

## Quickstart

Create and edit this file: `mods/mods_enabled/hello-puter.js`

```javascript

// You can get definitions exposed by Puter via `use`

const { UserActorType, AppUnderUserActorType } = use.core;



// Endpoints can be registered directly on an extension

extension.get('/hello-puter', (req, res) => {

    const actor = req.actor;

    



    // Make a string "who" which says:

    //   "<username>", or:

    //   "<app> acting on behalf of <username>"

    let who = 'unknown';

    if ( actor.type instanceof UserActorType ) {

        who = actor.type.user.username;

    }

    if ( actor.type instanceof AppUnderUserActorType ) {

        who = actor.type.app.name

            + ' on behalf of '

            + actor.type.user.username;

    }



    res.send(`Hello, ${who}!`);

});



// Extensions can listen to events and manipulate Puter's behavior

extension.on('core.email.validate', event => {

    if ( event.email.includes('evil') ) {

        event.allow = false;

    }

});

```

### Scope of `extension` and `use`

It is important to know that the `extension` global is temporary and does not
exist after your extension is loaded. If you wish to access the extension
object within a callback you will need to first bind it to a variable in
your extension's scope.

```javascript

const ext = extension;

extension.on('some-event', () => {

    // This would throw an error

    // extension.something();



    // This works

    ext.example();

})

```

The same is true for `use`. Calls to `use` should happen at the top of
the file, just like imports in ES6.

## Database Access

A database access object is provided to the extension via `extension.db`.
You **must** scope `extension` to another variable (`ext` in this example)
in order to access `db` from callbacks.

```javascript

const ext = extension;



extension.get('/user-count', { noauth: true, mw: [] }, (req, res) => {

    const [count] = await ext.db.read(

        'SELECT COUNT(*) as c FROM `user`'

    );

});

```

The database access object has the following methods:
- `read(query, params)` - read from the database using a prepared statement. If read-replicas are enabled, this will use a replica.
- `write(query, params)` - write to the database using a prepared statement. If read-replicas are enabled, this will write to the primary.
- `pread(query, params)` - read from the database using a prepared statement. If read-replicas are enabled, this will read from the primary.
- `requireRead(query, params)` - read from the database using a prepared statement. If read-replicas are enabled, this will try reading from the replica first. If there are no results, a second attempt will be made on the primary.

## Events

See [events.md](./events.md)

## Definitions

See [definitions.md](./definitions.md)