@axium/notes 0.1.11 → 0.2.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 ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "../server/schemas/db.json",
3
+ "format": 0,
4
+ "versions": [
5
+ {
6
+ "delta": false,
7
+ "tables": {
8
+ "notes": {
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
+ "modified": { "type": "timestamptz", "required": true, "default": "now()" },
14
+ "publicPermission": { "type": "integer", "required": true, "default": 0 },
15
+ "title": { "type": "text", "required": true },
16
+ "content": { "type": "text" },
17
+ "labels": { "type": "text[]", "required": true, "default": "'{}'::text[]" }
18
+ }
19
+ },
20
+ "acl.notes": {
21
+ "columns": {
22
+ "userId": { "type": "uuid", "required": true, "references": "users.id", "onDelete": "cascade" },
23
+ "itemId": { "type": "uuid", "required": true, "references": "notes.id", "onDelete": "cascade" },
24
+ "createdAt": { "type": "timestamptz", "required": true, "default": "now()" },
25
+ "permission": { "type": "integer", "required": true, "check": "permission >= 0 AND permission <= 5" }
26
+ }
27
+ }
28
+ },
29
+ "indexes": ["notes:userId", "acl.notes:userId", "acl.notes:itemId"]
30
+ },
31
+ {
32
+ "delta": true,
33
+ "alter_tables": {
34
+ "notes": {
35
+ "drop_columns": ["publicPermission"]
36
+ },
37
+ "acl.notes": {
38
+ "drop_constraints": ["PK_acl_notes"],
39
+ "drop_columns": ["permission"],
40
+ "add_columns": {
41
+ "role": { "type": "text" },
42
+ "tag": { "type": "text" },
43
+ "read": { "type": "boolean", "required": true, "default": false },
44
+ "edit": { "type": "boolean", "required": true, "default": false },
45
+ "manage": { "type": "boolean", "required": true, "default": false }
46
+ },
47
+ "alter_columns": {
48
+ "userId": { "ops": ["drop_required"] }
49
+ },
50
+ "add_constraints": {
51
+ "unique_notes": { "type": "unique", "on": ["itemId", "userId", "role", "tag"], "nulls_not_distinct": true }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ ],
57
+ "wipe": ["notes", "acl.notes"],
58
+ "acl_tables": {
59
+ "notes": "acl.notes"
60
+ }
61
+ }
package/dist/common.d.ts CHANGED
@@ -3,19 +3,6 @@ export declare const NoteInit: z.ZodObject<{
3
3
  title: z.ZodString;
4
4
  content: z.ZodOptional<z.ZodNullable<z.ZodString>>;
5
5
  labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
6
- publicPermission: z.ZodDefault<z.ZodEnum<{
7
- readonly None: 0;
8
- readonly Read: 1;
9
- readonly Comment: 2;
10
- readonly Edit: 3;
11
- readonly Manage: 5;
12
- }> & {
13
- readonly None: 0;
14
- readonly Read: 1;
15
- readonly Comment: 2;
16
- readonly Edit: 3;
17
- readonly Manage: 5;
18
- }>;
19
6
  }, z.core.$strip>;
20
7
  export interface NoteInit extends z.infer<typeof NoteInit> {
21
8
  }
package/dist/common.js CHANGED
@@ -1,8 +1,6 @@
1
- import { Permission } from '@axium/core/access';
2
1
  import * as z from 'zod';
3
2
  export const NoteInit = z.object({
4
3
  title: z.string().max(100),
5
4
  content: z.string().max(10_000).nullish(),
6
5
  labels: z.array(z.string().max(30)).default([]),
7
- publicPermission: Permission.default(0),
8
6
  });
package/dist/hooks.d.ts CHANGED
@@ -1,6 +1,3 @@
1
1
  import './common.js';
2
2
  import './server.js';
3
3
  export declare function statusText(): Promise<string>;
4
- export declare function db_init(): Promise<void>;
5
- export declare function db_wipe(): Promise<void>;
6
- export declare function remove(): Promise<void>;
package/dist/hooks.js CHANGED
@@ -1,38 +1,7 @@
1
- import { done, start } from '@axium/core/node/io';
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 { notes } = await count('notes');
9
6
  return `${notes} notes`;
10
7
  }
11
- export async function db_init() {
12
- start('Creating table notes');
13
- await database.schema
14
- .createTable('notes')
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('modified', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
19
- .addColumn('publicPermission', 'integer', col => col.notNull().defaultTo(0))
20
- .addColumn('title', 'text', col => col.notNull())
21
- .addColumn('content', 'text')
22
- .addColumn('labels', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
23
- .execute()
24
- .then(done)
25
- .catch(warnExists);
26
- await createIndex('notes', 'userId');
27
- await acl.createTable('notes');
28
- }
29
- export async function db_wipe() {
30
- start('Wiping data from notes');
31
- await database.deleteFrom('notes').execute().then(done);
32
- await acl.wipeTable('notes');
33
- }
34
- export async function remove() {
35
- await acl.dropTable('notes');
36
- start('Dropping table notes');
37
- await database.schema.dropTable('notes').execute().then(done);
38
- }
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 {
@@ -9,11 +8,8 @@ declare module '@axium/server/database' {
9
8
  modified: Generated<Date>;
10
9
  title: string;
11
10
  content: string | null;
12
- publicPermission: Generated<Permission>;
13
11
  labels: Generated<string[]>;
14
12
  };
15
- }
16
- interface ExpectedSchema {
17
- notes: ColumnTypes<Schema['notes']>;
13
+ 'acl.notes': DBAccessControl & DBBool<'read' | 'edit' | 'manage'>;
18
14
  }
19
15
  }
package/dist/server.js CHANGED
@@ -1,25 +1,13 @@
1
- import { Permission } from '@axium/core';
2
1
  import { checkAuthForItem, checkAuthForUser } from '@axium/server/auth';
3
- import { database, expectedTypes } from '@axium/server/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';
6
5
  import * as z from 'zod';
7
6
  import { NoteInit } from './common.js';
8
- expectedTypes.notes = {
9
- id: { type: 'uuid', required: true, hasDefault: true },
10
- userId: { type: 'uuid', required: true },
11
- created: { type: 'timestamptz', required: true, hasDefault: true },
12
- modified: { type: 'timestamptz', required: true, hasDefault: true },
13
- title: { type: 'text', required: true },
14
- content: { type: 'text' },
15
- publicPermission: { type: 'int4', required: true, hasDefault: true },
16
- labels: { type: '_text', required: true, hasDefault: true },
17
- };
18
7
  addRoute({
19
8
  path: '/api/users/:id/notes',
20
9
  params: { id: z.uuid() },
21
- async GET(request, params) {
22
- const userId = params.id;
10
+ async GET(request, { id: userId }) {
23
11
  await checkAuthForUser(request, userId);
24
12
  return await database
25
13
  .selectFrom('notes')
@@ -28,9 +16,8 @@ addRoute({
28
16
  .execute()
29
17
  .catch(withError('Could not get notes'));
30
18
  },
31
- async PUT(request, params) {
19
+ async PUT(request, { id: userId }) {
32
20
  const init = await parseBody(request, NoteInit);
33
- const userId = params.id;
34
21
  await checkAuthForUser(request, userId);
35
22
  return await database
36
23
  .insertInto('notes')
@@ -43,15 +30,13 @@ addRoute({
43
30
  addRoute({
44
31
  path: '/api/notes/:id',
45
32
  params: { id: z.uuid() },
46
- async GET(request, params) {
47
- const id = params.id;
48
- const { item } = await checkAuthForItem(request, 'notes', id, Permission.Read);
33
+ async GET(request, { id }) {
34
+ const { item } = await checkAuthForItem(request, 'notes', id, { read: true });
49
35
  return item;
50
36
  },
51
- async PATCH(request, params) {
37
+ async PATCH(request, { id }) {
52
38
  const init = await parseBody(request, NoteInit);
53
- const id = params.id;
54
- await checkAuthForItem(request, 'notes', id, Permission.Edit);
39
+ await checkAuthForItem(request, 'notes', id, { edit: true });
55
40
  return await database
56
41
  .updateTable('notes')
57
42
  .set(init)
@@ -61,9 +46,8 @@ addRoute({
61
46
  .executeTakeFirstOrThrow()
62
47
  .catch(withError('Could not update note'));
63
48
  },
64
- async DELETE(request, params) {
65
- const id = params.id;
66
- await checkAuthForItem(request, 'notes', id, Permission.Manage);
49
+ async DELETE(request, { id }) {
50
+ await checkAuthForItem(request, 'notes', id, { manage: true });
67
51
  return await database
68
52
  .deleteFrom('notes')
69
53
  .where('id', '=', id)
package/lib/Note.svelte CHANGED
@@ -7,10 +7,10 @@
7
7
  import { copy } from '@axium/client/clipboard';
8
8
  import { download } from 'utilium/dom.js';
9
9
 
10
- let { note = $bindable(), notes = $bindable() }: { note: Note; notes?: Note[] } = $props();
10
+ let { note = $bindable(), notes = $bindable(), pageMode = false }: { note: Note; notes?: Note[]; pageMode?: boolean } = $props();
11
11
  </script>
12
12
 
13
- <div class="note">
13
+ <div class={['note', pageMode && 'full-page']}>
14
14
  <div class="note-header">
15
15
  <input
16
16
  type="text"
@@ -77,6 +77,20 @@
77
77
  padding: 1em;
78
78
  border: 1px solid var(--bg-accent);
79
79
  background-color: var(--bg-alt);
80
+ height: fit-content;
81
+ max-height: 40em;
82
+ anchor-name: --note;
83
+
84
+ textarea {
85
+ resize: none;
86
+ field-sizing: content;
87
+ height: max-content;
88
+ }
89
+ }
90
+
91
+ .note.full-page {
92
+ max-height: unset;
93
+ height: 100%;
80
94
  }
81
95
 
82
96
  .note-header {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/notes",
3
- "version": "0.1.11",
3
+ "version": "0.2.0",
4
4
  "author": "James Prevett <axium@jamespre.dev>",
5
5
  "description": "Notes 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.6.0",
38
- "@axium/core": ">=0.10.0",
39
- "@axium/server": ">=0.26.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.4.0"
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
  {
@@ -32,7 +32,7 @@
32
32
  </div>
33
33
  {/if}
34
34
 
35
- <Note note={data.note} />
35
+ <Note note={data.note} pageMode />
36
36
  </div>
37
37
 
38
38
  <style>