@axium/tasks 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/db.json +71 -0
- package/dist/common.d.ts +0 -2
- package/dist/hooks.d.ts +0 -3
- package/dist/hooks.js +1 -50
- package/dist/server.d.ts +1 -6
- package/dist/server.js +9 -28
- package/package.json +8 -6
package/db.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../server/schemas/db.json",
|
|
3
|
+
"format": 0,
|
|
4
|
+
"versions": [
|
|
5
|
+
{
|
|
6
|
+
"delta": false,
|
|
7
|
+
"tables": {
|
|
8
|
+
"task_lists": {
|
|
9
|
+
"columns": {
|
|
10
|
+
"id": { "type": "uuid", "required": true, "primary": true, "default": "gen_random_uuid()" },
|
|
11
|
+
"userId": { "type": "uuid", "required": true, "references": "users.id", "onDelete": "cascade" },
|
|
12
|
+
"created": { "type": "timestamptz", "required": true, "default": "now()" },
|
|
13
|
+
"publicPermission": { "type": "integer", "required": true, "default": 0 },
|
|
14
|
+
"name": { "type": "text", "required": true },
|
|
15
|
+
"description": { "type": "text" }
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"tasks": {
|
|
19
|
+
"columns": {
|
|
20
|
+
"id": { "type": "uuid", "required": true, "primary": true, "default": "gen_random_uuid()" },
|
|
21
|
+
"created": { "type": "timestamptz", "required": true, "default": "now()" },
|
|
22
|
+
"listId": { "type": "uuid", "required": true, "references": "task_lists.id", "onDelete": "cascade" },
|
|
23
|
+
"summary": { "type": "text", "required": true },
|
|
24
|
+
"description": { "type": "text" },
|
|
25
|
+
"parentId": { "type": "uuid", "references": "tasks.id", "onDelete": "cascade" },
|
|
26
|
+
"completed": { "type": "boolean", "required": true, "default": false },
|
|
27
|
+
"due": { "type": "timestamptz" }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"acl.task_lists": {
|
|
31
|
+
"columns": {
|
|
32
|
+
"userId": { "type": "uuid", "required": true, "references": "users.id", "onDelete": "cascade" },
|
|
33
|
+
"itemId": { "type": "uuid", "required": true, "references": "task_lists.id", "onDelete": "cascade" },
|
|
34
|
+
"createdAt": { "type": "timestamptz", "required": true, "default": "now()" },
|
|
35
|
+
"permission": { "type": "integer", "required": true, "check": "permission >= 0 AND permission <= 5" }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"indexes": ["task_lists:userId", "acl.task_lists:userId", "acl.task_lists:itemId", "tasks:listId", "tasks:parentId"]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"delta": true,
|
|
43
|
+
"alter_tables": {
|
|
44
|
+
"task_lists": {
|
|
45
|
+
"drop_columns": ["publicPermission"]
|
|
46
|
+
},
|
|
47
|
+
"acl.task_lists": {
|
|
48
|
+
"drop_constraints": ["PK_acl_task_lists"],
|
|
49
|
+
"drop_columns": ["permission"],
|
|
50
|
+
"add_columns": {
|
|
51
|
+
"role": { "type": "text" },
|
|
52
|
+
"tag": { "type": "text" },
|
|
53
|
+
"read": { "type": "boolean", "required": true, "default": false },
|
|
54
|
+
"edit": { "type": "boolean", "required": true, "default": false },
|
|
55
|
+
"manage": { "type": "boolean", "required": true, "default": false }
|
|
56
|
+
},
|
|
57
|
+
"alter_columns": {
|
|
58
|
+
"userId": { "ops": ["drop_required"] }
|
|
59
|
+
},
|
|
60
|
+
"add_constraints": {
|
|
61
|
+
"unique_task_lists": { "type": "unique", "on": ["itemId", "userId", "role", "tag"], "nulls_not_distinct": true }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"wipe": ["task_lists", "tasks", "acl.task_lists"],
|
|
68
|
+
"acl_tables": {
|
|
69
|
+
"task_lists": "acl.task_lists"
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/common.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Permission } from '@axium/core';
|
|
2
1
|
import type { WithRequired } from 'utilium';
|
|
3
2
|
import * as z from 'zod';
|
|
4
3
|
export declare const TaskInit: z.ZodObject<{
|
|
@@ -27,7 +26,6 @@ export interface TaskList extends TaskListInit {
|
|
|
27
26
|
id: string;
|
|
28
27
|
userId: string;
|
|
29
28
|
created: Date;
|
|
30
|
-
publicPermission: Permission;
|
|
31
29
|
tasks?: Task[];
|
|
32
30
|
}
|
|
33
31
|
declare module '@axium/core/api' {
|
package/dist/hooks.d.ts
CHANGED
package/dist/hooks.js
CHANGED
|
@@ -1,56 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as acl from '@axium/server/acl';
|
|
3
|
-
import { count, createIndex, database, warnExists } from '@axium/server/database';
|
|
4
|
-
import { sql } from 'kysely';
|
|
1
|
+
import { count } from '@axium/server/database';
|
|
5
2
|
import './common.js';
|
|
6
3
|
import './server.js';
|
|
7
4
|
export async function statusText() {
|
|
8
5
|
const { tasks, task_lists } = await count('tasks', 'task_lists');
|
|
9
6
|
return `${tasks} tasks, ${task_lists} lists`;
|
|
10
7
|
}
|
|
11
|
-
export async function db_init() {
|
|
12
|
-
start('Creating table task_lists');
|
|
13
|
-
await database.schema
|
|
14
|
-
.createTable('task_lists')
|
|
15
|
-
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
16
|
-
.addColumn('userId', 'uuid', col => col.notNull().references('users.id').onDelete('cascade'))
|
|
17
|
-
.addColumn('created', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
18
|
-
.addColumn('publicPermission', 'integer', col => col.notNull().defaultTo(0))
|
|
19
|
-
.addColumn('name', 'text', col => col.notNull())
|
|
20
|
-
.addColumn('description', 'text')
|
|
21
|
-
.execute()
|
|
22
|
-
.then(done)
|
|
23
|
-
.catch(warnExists);
|
|
24
|
-
await createIndex('task_lists', 'userId');
|
|
25
|
-
await acl.createTable('task_lists');
|
|
26
|
-
start('Creating table tasks');
|
|
27
|
-
await database.schema
|
|
28
|
-
.createTable('tasks')
|
|
29
|
-
.addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
|
|
30
|
-
.addColumn('created', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
|
|
31
|
-
.addColumn('listId', 'uuid', col => col.notNull().references('task_lists.id').onDelete('cascade'))
|
|
32
|
-
.addColumn('summary', 'text', col => col.notNull())
|
|
33
|
-
.addColumn('description', 'text')
|
|
34
|
-
.addColumn('parentId', 'uuid', col => col.references('tasks.id').onDelete('cascade'))
|
|
35
|
-
.addColumn('completed', 'boolean', col => col.notNull().defaultTo(false))
|
|
36
|
-
.addColumn('due', 'timestamptz')
|
|
37
|
-
.execute()
|
|
38
|
-
.then(done)
|
|
39
|
-
.catch(warnExists);
|
|
40
|
-
await createIndex('tasks', 'listId');
|
|
41
|
-
await createIndex('tasks', 'parentId');
|
|
42
|
-
}
|
|
43
|
-
export async function db_wipe() {
|
|
44
|
-
start('Wiping data from tasks');
|
|
45
|
-
await database.deleteFrom('tasks').execute().then(done);
|
|
46
|
-
start('Wiping data from task_lists');
|
|
47
|
-
await database.deleteFrom('task_lists').execute().then(done);
|
|
48
|
-
await acl.wipeTable('task_lists');
|
|
49
|
-
}
|
|
50
|
-
export async function remove() {
|
|
51
|
-
start('Dropping table tasks');
|
|
52
|
-
await database.schema.dropTable('tasks').execute().then(done);
|
|
53
|
-
start('Dropping table task_lists');
|
|
54
|
-
await database.schema.dropTable('task_lists').execute().then(done);
|
|
55
|
-
await acl.dropTable('task_lists');
|
|
56
|
-
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Permission } from '@axium/core';
|
|
2
1
|
import type { Generated, GeneratedAlways } from 'kysely';
|
|
3
2
|
declare module '@axium/server/database' {
|
|
4
3
|
interface Schema {
|
|
@@ -16,13 +15,9 @@ declare module '@axium/server/database' {
|
|
|
16
15
|
id: GeneratedAlways<string>;
|
|
17
16
|
userId: string;
|
|
18
17
|
created: GeneratedAlways<Date>;
|
|
19
|
-
publicPermission: Generated<Permission>;
|
|
20
18
|
name: string;
|
|
21
19
|
description?: string | null;
|
|
22
20
|
};
|
|
23
|
-
|
|
24
|
-
interface ExpectedSchema {
|
|
25
|
-
tasks: ColumnTypes<Schema['tasks']>;
|
|
26
|
-
task_lists: ColumnTypes<Schema['task_lists']>;
|
|
21
|
+
'acl.task_lists': DBAccessControl & DBBool<'read' | 'edit' | 'manage'>;
|
|
27
22
|
}
|
|
28
23
|
}
|
package/dist/server.js
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
import { Permission } from '@axium/core';
|
|
2
1
|
import { checkAuthForItem, checkAuthForUser } from '@axium/server/auth';
|
|
3
|
-
import { database
|
|
2
|
+
import { database } from '@axium/server/database';
|
|
4
3
|
import { parseBody, withError } from '@axium/server/requests';
|
|
5
4
|
import { addRoute } from '@axium/server/routes';
|
|
5
|
+
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
|
6
6
|
import * as z from 'zod';
|
|
7
7
|
import { TaskInit, TaskListInit, TaskListUpdate } from './common.js';
|
|
8
|
-
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
|
9
|
-
expectedTypes.tasks = {
|
|
10
|
-
id: { type: 'uuid', required: true, hasDefault: true },
|
|
11
|
-
created: { type: 'timestamptz', required: true, hasDefault: true },
|
|
12
|
-
summary: { type: 'text', required: true },
|
|
13
|
-
description: { type: 'text' },
|
|
14
|
-
listId: { type: 'uuid', required: true },
|
|
15
|
-
parentId: { type: 'uuid' },
|
|
16
|
-
completed: { type: 'bool', required: true, hasDefault: true },
|
|
17
|
-
due: { type: 'timestamptz' },
|
|
18
|
-
};
|
|
19
|
-
expectedTypes.task_lists = {
|
|
20
|
-
id: { type: 'uuid', required: true, hasDefault: true },
|
|
21
|
-
userId: { type: 'uuid', required: true },
|
|
22
|
-
created: { type: 'timestamptz', required: true, hasDefault: true },
|
|
23
|
-
publicPermission: { type: 'int4', required: true, hasDefault: true },
|
|
24
|
-
name: { type: 'text', required: true },
|
|
25
|
-
description: { type: 'text' },
|
|
26
|
-
};
|
|
27
8
|
addRoute({
|
|
28
9
|
path: '/api/users/:id/task_lists',
|
|
29
10
|
params: { id: z.uuid() },
|
|
@@ -56,7 +37,7 @@ addRoute({
|
|
|
56
37
|
path: '/api/task_lists/:id',
|
|
57
38
|
params: { id: z.uuid() },
|
|
58
39
|
async GET(request, { id }) {
|
|
59
|
-
const { item } = await checkAuthForItem(request, 'task_lists', id,
|
|
40
|
+
const { item } = await checkAuthForItem(request, 'task_lists', id, { read: true });
|
|
60
41
|
const tasks = await database
|
|
61
42
|
.selectFrom('tasks')
|
|
62
43
|
.selectAll()
|
|
@@ -67,7 +48,7 @@ addRoute({
|
|
|
67
48
|
},
|
|
68
49
|
async PUT(request, { id: listId }) {
|
|
69
50
|
const init = await parseBody(request, TaskInit.omit({ listId: true }));
|
|
70
|
-
await checkAuthForItem(request, 'task_lists', listId,
|
|
51
|
+
await checkAuthForItem(request, 'task_lists', listId, { edit: true });
|
|
71
52
|
return await database
|
|
72
53
|
.insertInto('tasks')
|
|
73
54
|
.values({ summary: '', ...init, listId })
|
|
@@ -76,7 +57,7 @@ addRoute({
|
|
|
76
57
|
.catch(withError('Could not update task list'));
|
|
77
58
|
},
|
|
78
59
|
async PATCH(request, { id }) {
|
|
79
|
-
await checkAuthForItem(request, 'task_lists', id,
|
|
60
|
+
await checkAuthForItem(request, 'task_lists', id, { edit: true });
|
|
80
61
|
const init = await parseBody(request, TaskListInit);
|
|
81
62
|
return await database
|
|
82
63
|
.updateTable('task_lists')
|
|
@@ -88,7 +69,7 @@ addRoute({
|
|
|
88
69
|
},
|
|
89
70
|
async POST(request, { id }) {
|
|
90
71
|
const body = await parseBody(request, TaskListUpdate);
|
|
91
|
-
await checkAuthForItem(request, 'task_lists', id,
|
|
72
|
+
await checkAuthForItem(request, 'task_lists', id, { edit: true });
|
|
92
73
|
if (typeof body.all_completed == 'boolean') {
|
|
93
74
|
await database
|
|
94
75
|
.updateTable('tasks')
|
|
@@ -102,7 +83,7 @@ addRoute({
|
|
|
102
83
|
return {};
|
|
103
84
|
},
|
|
104
85
|
async DELETE(request, { id }) {
|
|
105
|
-
await checkAuthForItem(request, 'task_lists', id,
|
|
86
|
+
await checkAuthForItem(request, 'task_lists', id, { manage: true });
|
|
106
87
|
return await database
|
|
107
88
|
.deleteFrom('task_lists')
|
|
108
89
|
.where('id', '=', id)
|
|
@@ -122,7 +103,7 @@ addRoute({
|
|
|
122
103
|
.where('id', '=', id)
|
|
123
104
|
.executeTakeFirstOrThrow()
|
|
124
105
|
.catch(withError('Could not get task'));
|
|
125
|
-
await checkAuthForItem(request, 'task_lists', task.listId,
|
|
106
|
+
await checkAuthForItem(request, 'task_lists', task.listId, { edit: true });
|
|
126
107
|
return await database
|
|
127
108
|
.updateTable('tasks')
|
|
128
109
|
.set(init)
|
|
@@ -138,7 +119,7 @@ addRoute({
|
|
|
138
119
|
.where('id', '=', id)
|
|
139
120
|
.executeTakeFirstOrThrow()
|
|
140
121
|
.catch(withError('Could not fetch task'));
|
|
141
|
-
await checkAuthForItem(request, 'task_lists', task.listId,
|
|
122
|
+
await checkAuthForItem(request, 'task_lists', task.listId, { manage: true });
|
|
142
123
|
return await database
|
|
143
124
|
.deleteFrom('tasks')
|
|
144
125
|
.where('id', '=', id)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/tasks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"author": "James Prevett <axium@jamespre.dev>",
|
|
5
5
|
"description": "Tasks for Axium",
|
|
6
6
|
"funding": {
|
|
@@ -28,15 +28,16 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|
|
30
30
|
"lib",
|
|
31
|
-
"routes"
|
|
31
|
+
"routes",
|
|
32
|
+
"db.json"
|
|
32
33
|
],
|
|
33
34
|
"scripts": {
|
|
34
35
|
"build": "tsc"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
|
-
"@axium/client": ">=0.
|
|
38
|
-
"@axium/core": ">=0.
|
|
39
|
-
"@axium/server": ">=0.
|
|
38
|
+
"@axium/client": ">=0.9.0",
|
|
39
|
+
"@axium/core": ">=0.12.0",
|
|
40
|
+
"@axium/server": ">=0.28.0",
|
|
40
41
|
"@sveltejs/kit": "^2.27.3",
|
|
41
42
|
"utilium": "^2.3.8"
|
|
42
43
|
},
|
|
@@ -46,7 +47,8 @@
|
|
|
46
47
|
"axium": {
|
|
47
48
|
"server": {
|
|
48
49
|
"routes": "routes",
|
|
49
|
-
"hooks": "./dist/hooks.js"
|
|
50
|
+
"hooks": "./dist/hooks.js",
|
|
51
|
+
"db": "./db.json"
|
|
50
52
|
},
|
|
51
53
|
"apps": [
|
|
52
54
|
{
|