talizen 0.2.3 → 0.2.5
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/README.md +54 -0
- package/auth.d.ts +32 -0
- package/auth.js +35 -0
- package/func.d.ts +91 -0
- package/func.js +90 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
Talizen's frontend SDK package. It provides a small runtime client and shared types for:
|
|
4
4
|
|
|
5
5
|
- `talizen/core`
|
|
6
|
+
- `talizen/auth`
|
|
6
7
|
- `talizen/cms`
|
|
7
8
|
- `talizen/form`
|
|
9
|
+
- `talizen/func`
|
|
8
10
|
|
|
9
11
|
The package is designed to hold the platform-level APIs that frontend projects use directly, while project-specific CMS and form schema types can still be generated separately per project.
|
|
10
12
|
|
|
@@ -106,11 +108,63 @@ When a `File` object appears in the payload, `submitForm()` will:
|
|
|
106
108
|
3. Replace the original `File` value with the returned `file_url`
|
|
107
109
|
4. Submit the final payload to `/form/:key/submit`
|
|
108
110
|
|
|
111
|
+
### Login users
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { currentUser, login, logout, register } from "talizen/auth";
|
|
115
|
+
|
|
116
|
+
await register({ email: "hi@talizen.com", password: "secret", name: "Alice" });
|
|
117
|
+
await login({ email: "hi@talizen.com", password: "secret" });
|
|
118
|
+
|
|
119
|
+
const user = await currentUser();
|
|
120
|
+
await logout();
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Invoke a custom function
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { invoke } from "talizen/func";
|
|
127
|
+
|
|
128
|
+
const result = await invoke<{ success: boolean }>("user/auth.login", {
|
|
129
|
+
email: "hi@talizen.com",
|
|
130
|
+
password: "secret",
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`invoke("<fileKey>.<method>", input)` calls the method exported by the script file. If `.method` is omitted, Talizen calls `main`:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
await invoke("user/auth", { email: "hi@talizen.com" });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Write function runtime code
|
|
141
|
+
|
|
142
|
+
Func code can use TypeScript and import runtime-only helpers from `talizen/func`:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { auth, db, cache } from "talizen/func";
|
|
146
|
+
|
|
147
|
+
export function create(input: { title: string }) {
|
|
148
|
+
const user = auth.requireUser();
|
|
149
|
+
const row = db.insert("book", {
|
|
150
|
+
title: input.title,
|
|
151
|
+
user_id: user.id,
|
|
152
|
+
status: "draft",
|
|
153
|
+
});
|
|
154
|
+
cache.set(`book:${row.id}`, row, 60);
|
|
155
|
+
return { ok: true, id: row.id };
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`db`, `cache`, and Func `auth` are injected by the Talizen Func runtime. They are typed in this package for authoring, but they are not browser/Node general-purpose APIs.
|
|
160
|
+
|
|
109
161
|
## Package Layout
|
|
110
162
|
|
|
111
163
|
- `talizen/core`: shared runtime config, request helpers, and base data types.
|
|
164
|
+
- `talizen/auth`: project user register, login, logout, and current user helpers.
|
|
112
165
|
- `talizen/cms`: CMS content types and content query APIs.
|
|
113
166
|
- `talizen/form`: form submission helpers and related types.
|
|
167
|
+
- `talizen/func`: custom function invocation helpers and Func-runtime-only `db`, `cache`, `auth` types.
|
|
114
168
|
|
|
115
169
|
## Publish
|
|
116
170
|
|
package/auth.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type TalizenRequestOptions } from "./core.js";
|
|
2
|
+
export interface AuthUser {
|
|
3
|
+
id: string;
|
|
4
|
+
email?: string;
|
|
5
|
+
phone?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
avatar?: string;
|
|
8
|
+
status?: string;
|
|
9
|
+
profile?: unknown;
|
|
10
|
+
email_verified_at?: string | null;
|
|
11
|
+
last_login_at?: string | null;
|
|
12
|
+
created_at?: string;
|
|
13
|
+
updated_at?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface AuthPasswordInput {
|
|
16
|
+
email: string;
|
|
17
|
+
password: string;
|
|
18
|
+
}
|
|
19
|
+
export interface AuthRegisterInput extends AuthPasswordInput {
|
|
20
|
+
phone?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
avatar?: string;
|
|
23
|
+
profile?: unknown;
|
|
24
|
+
}
|
|
25
|
+
export declare class TalizenAuthError extends Error {
|
|
26
|
+
constructor(message: string);
|
|
27
|
+
}
|
|
28
|
+
export declare function register(input: AuthRegisterInput, options?: TalizenRequestOptions): Promise<AuthUser>;
|
|
29
|
+
export declare function login(input: AuthPasswordInput, options?: TalizenRequestOptions): Promise<AuthUser>;
|
|
30
|
+
export declare function logout(options?: TalizenRequestOptions): Promise<void>;
|
|
31
|
+
export declare function currentUser(options?: TalizenRequestOptions): Promise<AuthUser | null>;
|
|
32
|
+
export declare function requireUser(options?: TalizenRequestOptions): Promise<AuthUser>;
|
package/auth.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { requestJson, } from "./core.js";
|
|
2
|
+
export class TalizenAuthError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "TalizenAuthError";
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export async function register(input, options) {
|
|
9
|
+
return requestJson("/auth/register", {
|
|
10
|
+
method: "POST",
|
|
11
|
+
body: JSON.stringify(input),
|
|
12
|
+
}, options);
|
|
13
|
+
}
|
|
14
|
+
export async function login(input, options) {
|
|
15
|
+
return requestJson("/auth/login", {
|
|
16
|
+
method: "POST",
|
|
17
|
+
body: JSON.stringify(input),
|
|
18
|
+
}, options);
|
|
19
|
+
}
|
|
20
|
+
export async function logout(options) {
|
|
21
|
+
await requestJson("/auth/logout", {
|
|
22
|
+
method: "POST",
|
|
23
|
+
body: JSON.stringify({}),
|
|
24
|
+
}, options);
|
|
25
|
+
}
|
|
26
|
+
export async function currentUser(options) {
|
|
27
|
+
return requestJson("/auth/me", { method: "GET" }, options);
|
|
28
|
+
}
|
|
29
|
+
export async function requireUser(options) {
|
|
30
|
+
const user = await currentUser(options);
|
|
31
|
+
if (!user) {
|
|
32
|
+
throw new TalizenAuthError("Login required.");
|
|
33
|
+
}
|
|
34
|
+
return user;
|
|
35
|
+
}
|
package/func.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type TalizenRequestOptions } from "./core.js";
|
|
2
|
+
import type { AuthUser } from "./auth.js";
|
|
3
|
+
export interface FuncLogEntry {
|
|
4
|
+
level: string;
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
export interface FuncRunResponse<T = unknown> {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
result?: T;
|
|
10
|
+
logs?: FuncLogEntry[];
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
export type DbOrderBy = string;
|
|
14
|
+
export interface DbFilterCondition {
|
|
15
|
+
field_id?: string;
|
|
16
|
+
fieldId?: string;
|
|
17
|
+
operator: "equal" | "not_equal" | "in";
|
|
18
|
+
value?: unknown;
|
|
19
|
+
values?: unknown[];
|
|
20
|
+
}
|
|
21
|
+
export interface DbFilter {
|
|
22
|
+
match?: "and" | "or";
|
|
23
|
+
conditions?: DbFilterCondition[];
|
|
24
|
+
}
|
|
25
|
+
export interface DbQuery {
|
|
26
|
+
where?: Record<string, unknown>;
|
|
27
|
+
filter?: DbFilter;
|
|
28
|
+
limit?: number;
|
|
29
|
+
offset?: number;
|
|
30
|
+
order_by?: DbOrderBy;
|
|
31
|
+
orderBy?: DbOrderBy;
|
|
32
|
+
}
|
|
33
|
+
export type DbRecord<T extends Record<string, unknown> = Record<string, unknown>> = T & {
|
|
34
|
+
id: string;
|
|
35
|
+
};
|
|
36
|
+
export interface FuncDbRuntime {
|
|
37
|
+
get<T extends Record<string, unknown> = Record<string, unknown>>(table: string, id: string): DbRecord<T> | null;
|
|
38
|
+
query<T extends Record<string, unknown> = Record<string, unknown>>(table: string, query?: DbQuery): Array<DbRecord<T>>;
|
|
39
|
+
insert<T extends Record<string, unknown> = Record<string, unknown>>(table: string, data: T): DbRecord<T>;
|
|
40
|
+
update<T extends Record<string, unknown> = Record<string, unknown>>(table: string, id: string, data: Partial<T>): {
|
|
41
|
+
ok?: boolean;
|
|
42
|
+
updated?: boolean;
|
|
43
|
+
} | DbRecord<T>;
|
|
44
|
+
delete(table: string, id: string): {
|
|
45
|
+
ok?: boolean;
|
|
46
|
+
deleted?: boolean;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface FuncAuthRuntime {
|
|
50
|
+
currentUser(): AuthUser | null;
|
|
51
|
+
requireUser(): AuthUser;
|
|
52
|
+
}
|
|
53
|
+
export interface CacheSetOptions {
|
|
54
|
+
ttl?: number;
|
|
55
|
+
ttlSeconds?: number;
|
|
56
|
+
}
|
|
57
|
+
export interface FuncCacheRuntime {
|
|
58
|
+
get<T = unknown>(key: string): T | null;
|
|
59
|
+
set(key: string, value: unknown, ttlSeconds?: number): {
|
|
60
|
+
ok?: boolean;
|
|
61
|
+
};
|
|
62
|
+
set(key: string, value: unknown, options?: CacheSetOptions): {
|
|
63
|
+
ok?: boolean;
|
|
64
|
+
};
|
|
65
|
+
del(key: string): {
|
|
66
|
+
ok?: boolean;
|
|
67
|
+
deleted?: boolean;
|
|
68
|
+
};
|
|
69
|
+
incr(key: string, delta?: number): number;
|
|
70
|
+
expire(key: string, ttlSeconds: number): {
|
|
71
|
+
ok?: boolean;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export declare const db: FuncDbRuntime;
|
|
75
|
+
export declare const auth: FuncAuthRuntime;
|
|
76
|
+
export declare const cache: FuncCacheRuntime;
|
|
77
|
+
export declare class TalizenFuncError extends Error {
|
|
78
|
+
readonly key: string;
|
|
79
|
+
readonly method: string;
|
|
80
|
+
readonly logs: FuncLogEntry[];
|
|
81
|
+
constructor(key: string, method: string, message: string, logs?: FuncLogEntry[]);
|
|
82
|
+
}
|
|
83
|
+
export declare function invoke<T = unknown>(name: string, input?: unknown, options?: TalizenRequestOptions): Promise<T>;
|
|
84
|
+
export interface RunFuncOptions extends TalizenRequestOptions {
|
|
85
|
+
method?: string;
|
|
86
|
+
}
|
|
87
|
+
export declare function runFunc<T = unknown>(key: string, input?: unknown, options?: RunFuncOptions): Promise<T>;
|
|
88
|
+
export declare function parseInvokeName(name: string): {
|
|
89
|
+
key: string;
|
|
90
|
+
method: string;
|
|
91
|
+
};
|
package/func.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { requestJson, } from "./core.js";
|
|
2
|
+
function funcRuntimeUnavailable() {
|
|
3
|
+
throw new Error("talizen/func db/cache/auth are only available inside Talizen Func runtime.");
|
|
4
|
+
}
|
|
5
|
+
export const db = {
|
|
6
|
+
get: funcRuntimeUnavailable,
|
|
7
|
+
query: funcRuntimeUnavailable,
|
|
8
|
+
insert: funcRuntimeUnavailable,
|
|
9
|
+
update: funcRuntimeUnavailable,
|
|
10
|
+
delete: funcRuntimeUnavailable,
|
|
11
|
+
};
|
|
12
|
+
export const auth = {
|
|
13
|
+
currentUser: funcRuntimeUnavailable,
|
|
14
|
+
requireUser: funcRuntimeUnavailable,
|
|
15
|
+
};
|
|
16
|
+
export const cache = {
|
|
17
|
+
get: funcRuntimeUnavailable,
|
|
18
|
+
set: funcRuntimeUnavailable,
|
|
19
|
+
del: funcRuntimeUnavailable,
|
|
20
|
+
incr: funcRuntimeUnavailable,
|
|
21
|
+
expire: funcRuntimeUnavailable,
|
|
22
|
+
};
|
|
23
|
+
export class TalizenFuncError extends Error {
|
|
24
|
+
key;
|
|
25
|
+
method;
|
|
26
|
+
logs;
|
|
27
|
+
constructor(key, method, message, logs) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "TalizenFuncError";
|
|
30
|
+
this.key = key;
|
|
31
|
+
this.method = method;
|
|
32
|
+
this.logs = logs ?? [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function invoke(name, input, options) {
|
|
36
|
+
const target = parseInvokeName(name);
|
|
37
|
+
return runFunc(target.key, input, {
|
|
38
|
+
...options,
|
|
39
|
+
method: target.method,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export async function runFunc(key, input, options) {
|
|
43
|
+
const normalizedKey = normalizeFuncKey(key);
|
|
44
|
+
const method = normalizeFuncMethod(options?.method);
|
|
45
|
+
const response = await requestJson(`/func/${encodeFuncKey(normalizedKey)}${method === "main" ? "" : `.${encodeURIComponent(method)}`}`, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
body: JSON.stringify(input ?? {}),
|
|
48
|
+
}, options);
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new TalizenFuncError(normalizedKey, method, response.error || "Talizen func failed.", response.logs);
|
|
51
|
+
}
|
|
52
|
+
return response.result;
|
|
53
|
+
}
|
|
54
|
+
export function parseInvokeName(name) {
|
|
55
|
+
const normalized = normalizeFuncKey(name);
|
|
56
|
+
const lastSlash = normalized.lastIndexOf("/");
|
|
57
|
+
const lastDot = normalized.lastIndexOf(".");
|
|
58
|
+
if (lastDot <= lastSlash) {
|
|
59
|
+
return { key: normalized, method: "main" };
|
|
60
|
+
}
|
|
61
|
+
const key = normalized.slice(0, lastDot);
|
|
62
|
+
const method = normalized.slice(lastDot + 1);
|
|
63
|
+
return {
|
|
64
|
+
key: normalizeFuncKey(key),
|
|
65
|
+
method: normalizeFuncMethod(method),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function normalizeFuncKey(key) {
|
|
69
|
+
const normalized = key.trim().replace(/^\/+|\/+$/g, "");
|
|
70
|
+
if (normalized === "") {
|
|
71
|
+
throw new Error("Talizen func key is required.");
|
|
72
|
+
}
|
|
73
|
+
if (normalized.includes("..") || normalized.includes("\0")) {
|
|
74
|
+
throw new Error(`Invalid Talizen func key: ${key}`);
|
|
75
|
+
}
|
|
76
|
+
return normalized;
|
|
77
|
+
}
|
|
78
|
+
function normalizeFuncMethod(method) {
|
|
79
|
+
const normalized = (method ?? "main").trim();
|
|
80
|
+
if (normalized === "") {
|
|
81
|
+
return "main";
|
|
82
|
+
}
|
|
83
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(normalized)) {
|
|
84
|
+
throw new Error(`Invalid Talizen func method: ${method}`);
|
|
85
|
+
}
|
|
86
|
+
return normalized;
|
|
87
|
+
}
|
|
88
|
+
function encodeFuncKey(key) {
|
|
89
|
+
return key.split("/").map(encodeURIComponent).join("/");
|
|
90
|
+
}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "talizen",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Talizen frontend SDK types for cms, form and core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"types": "./core.d.ts",
|
|
21
21
|
"import": "./core.js"
|
|
22
22
|
},
|
|
23
|
+
"./auth": {
|
|
24
|
+
"types": "./auth.d.ts",
|
|
25
|
+
"import": "./auth.js"
|
|
26
|
+
},
|
|
23
27
|
"./cms": {
|
|
24
28
|
"types": "./cms.d.ts",
|
|
25
29
|
"import": "./cms.js"
|
|
@@ -32,6 +36,10 @@
|
|
|
32
36
|
"types": "./form.d.ts",
|
|
33
37
|
"import": "./form.js"
|
|
34
38
|
},
|
|
39
|
+
"./func": {
|
|
40
|
+
"types": "./func.d.ts",
|
|
41
|
+
"import": "./func.js"
|
|
42
|
+
},
|
|
35
43
|
"./i18n": {
|
|
36
44
|
"types": "./i18n.d.ts",
|
|
37
45
|
"import": "./i18n.js"
|