@inflector/aura 0.1.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/dist/auth.d.ts +1232 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +71 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +546 -0
- package/dist/database.d.ts +258 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +100 -0
- package/dist/fluent.d.ts +14 -0
- package/dist/fluent.d.ts.map +1 -0
- package/dist/fluent.js +29 -0
- package/dist/function.d.ts +2 -0
- package/dist/function.d.ts.map +1 -0
- package/dist/function.js +90 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/lib.d.ts +12 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +1 -0
- package/dist/storage.d.ts +31 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +164 -0
- package/package.json +45 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAS,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAIjE,cAAM,WAAW,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,SAAS,CAAQ;gBAEb,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAMxD,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wvBAUF;IACD,MAAM;;ovBAUL;IACD,MAAM;;wvBAUL;IACD,GAAG,GAAI,QAAQ,QAAQ,CAAC,IAAI,CAAC,gvBAa5B;IACD,OAAO,GAAI,QAAQ,QAAQ,CAAC,IAAI,CAAC,EAAE,gvBAalC;IACD,MAAM,GAAI,QAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;;wvBAUpC;IACD,KAAK;;4BAUJ;IACD,KAAK;;6BAUJ;IACD,SAAS,GAAI,UAAU,CAAC,CAAC,CAAC,EAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAA,IAAI,EAAC,GAAG,CAAA;KAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAA,IAAI,EAAC,GAAG,CAAA;KAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,gBAO5G;CACJ;AAED,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,EACzE,KAAK,MAAM,EACX,WAAW,MAAM,EACjB,QAAQ,CAAC,QAEe,CAAC,kCAY5B,CAAA"}
|
package/dist/database.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createFluentBuilder } from "./fluent";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
class RemoteTable {
|
|
4
|
+
URL;
|
|
5
|
+
Name;
|
|
6
|
+
WorkSpace;
|
|
7
|
+
constructor(url, name, workspace) {
|
|
8
|
+
this.URL = url;
|
|
9
|
+
this.Name = name;
|
|
10
|
+
this.WorkSpace = workspace;
|
|
11
|
+
}
|
|
12
|
+
Get = () => {
|
|
13
|
+
return createFluentBuilder(async (data) => {
|
|
14
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
15
|
+
operation: 'Get',
|
|
16
|
+
settings: data,
|
|
17
|
+
})).data;
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
GetOne = () => {
|
|
21
|
+
return createFluentBuilder(async (data) => {
|
|
22
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
23
|
+
operation: 'GetOne',
|
|
24
|
+
settings: data,
|
|
25
|
+
})).data;
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
Delete = () => {
|
|
29
|
+
return createFluentBuilder(async (data) => {
|
|
30
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
31
|
+
operation: 'Delete',
|
|
32
|
+
settings: { ...data, returning: true },
|
|
33
|
+
})).data;
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
Add = (record) => {
|
|
37
|
+
return createFluentBuilder(async () => {
|
|
38
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
39
|
+
operation: 'Add',
|
|
40
|
+
settings: {
|
|
41
|
+
returning: true
|
|
42
|
+
},
|
|
43
|
+
data: record
|
|
44
|
+
})).data;
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
AddMany = (record) => {
|
|
48
|
+
return createFluentBuilder(async () => {
|
|
49
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
50
|
+
operation: 'AddMany',
|
|
51
|
+
settings: {
|
|
52
|
+
returning: true
|
|
53
|
+
},
|
|
54
|
+
data: record
|
|
55
|
+
})).data;
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
Update = (record) => {
|
|
59
|
+
return createFluentBuilder(async (data) => {
|
|
60
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
61
|
+
operation: 'Update',
|
|
62
|
+
settings: { ...data, returning: true },
|
|
63
|
+
})).data;
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
Count = () => {
|
|
67
|
+
return createFluentBuilder(async (data) => {
|
|
68
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
69
|
+
operation: 'Count',
|
|
70
|
+
settings: data,
|
|
71
|
+
})).data;
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
Exist = () => {
|
|
75
|
+
return createFluentBuilder(async (data) => {
|
|
76
|
+
return (await axios.post(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`, {
|
|
77
|
+
operation: 'Exist',
|
|
78
|
+
settings: data,
|
|
79
|
+
})).data;
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
Subscribe = (callback) => {
|
|
83
|
+
const eventSource = new EventSource(`${this.URL}/api/db/${this.WorkSpace}/${this.Name}`);
|
|
84
|
+
eventSource.addEventListener(this.Name, (event) => {
|
|
85
|
+
const { op, ...data } = JSON.parse(event.data);
|
|
86
|
+
callback({ action: op, data });
|
|
87
|
+
});
|
|
88
|
+
return () => eventSource.close();
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export const AuraDatabase = (url, workspace, tables) => {
|
|
92
|
+
const Tables = {};
|
|
93
|
+
for (const key in tables) {
|
|
94
|
+
if (Object.prototype.hasOwnProperty.call(tables, key)) {
|
|
95
|
+
// @ts-ignore
|
|
96
|
+
Tables[key] = new RemoteTable(url, key, workspace);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return Tables;
|
|
100
|
+
};
|
package/dist/fluent.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type SetFlag<State, Key extends keyof State> = {
|
|
2
|
+
[P in keyof State]: P extends Key ? true : State[P];
|
|
3
|
+
};
|
|
4
|
+
type MapToFalse<T> = {
|
|
5
|
+
[K in keyof T]: false;
|
|
6
|
+
};
|
|
7
|
+
type FluentStep<Schema, State extends {
|
|
8
|
+
[K in keyof Schema]: boolean | unknown;
|
|
9
|
+
}, Result> = {
|
|
10
|
+
[K in keyof Schema as State[K] extends true ? never : K]: Schema[K] extends boolean ? () => FluentStep<Schema, SetFlag<State, K>, Result> : Schema[K] extends any[] ? (...args: Schema[K]) => FluentStep<Schema, SetFlag<State, K>, Result> : (arg: Schema[K]) => FluentStep<Schema, SetFlag<State, K>, Result>;
|
|
11
|
+
} & PromiseLike<Result>;
|
|
12
|
+
export declare function createFluentBuilder<Schema, R = Schema>(onBuild?: (data: Schema) => R | Promise<R>): FluentStep<Schema, MapToFalse<Schema>, R>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=fluent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluent.d.ts","sourceRoot":"","sources":["../src/fluent.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,KAAK,EAAE,GAAG,SAAS,MAAM,KAAK,IAAI;KACjD,CAAC,IAAI,MAAM,KAAK,GAAG,CAAC,SAAS,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;CACpD,CAAC;AACF,KAAK,UAAU,CAAC,CAAC,IAAI;KAClB,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK;CACtB,CAAC;AACF,KAAK,UAAU,CACb,MAAM,EACN,KAAK,SAAS;KAAG,CAAC,IAAI,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO;CAAE,EACxD,MAAM,IACJ;KACD,CAAC,IAAI,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,GACvC,KAAK,GACL,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,OAAO,GAC7B,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,GACnD,MAAM,CAAC,CAAC,CAAC,SAAS,GAAG,EAAE,GACvB,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,GACrE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC;CACtE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAExB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EACpD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACzC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAgC3C"}
|
package/dist/fluent.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function createFluentBuilder(onBuild) {
|
|
2
|
+
const data = {};
|
|
3
|
+
const handler = {
|
|
4
|
+
get(target, prop) {
|
|
5
|
+
if (prop === "then") {
|
|
6
|
+
return (resolve, reject) => {
|
|
7
|
+
const result = onBuild ? onBuild(target) : target;
|
|
8
|
+
Promise.resolve(result).then(resolve, reject);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return (...args) => {
|
|
12
|
+
// 1. No Args -> True (Flag)
|
|
13
|
+
if (args.length === 0) {
|
|
14
|
+
target[prop] = true;
|
|
15
|
+
}
|
|
16
|
+
// 2. One Arg -> Store value
|
|
17
|
+
else if (args.length === 1) {
|
|
18
|
+
target[prop] = args[0];
|
|
19
|
+
}
|
|
20
|
+
// 3. Multiple Args -> Store as Array/Tuple
|
|
21
|
+
else {
|
|
22
|
+
target[prop] = args;
|
|
23
|
+
}
|
|
24
|
+
return new Proxy(target, handler);
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
return new Proxy(data, handler);
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,GAAG,CAiGvG"}
|
package/dist/function.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export function createFunctionHandler(baseUrl, workspace, functionsFolder) {
|
|
2
|
+
const handler = new Proxy({}, {
|
|
3
|
+
get(_, prop) {
|
|
4
|
+
return createNestedProxy([prop]);
|
|
5
|
+
}
|
|
6
|
+
});
|
|
7
|
+
function createNestedProxy(path) {
|
|
8
|
+
// Target function is just a placeholder
|
|
9
|
+
return new Proxy(() => { }, {
|
|
10
|
+
get(_, prop) {
|
|
11
|
+
return createNestedProxy([...path, prop]);
|
|
12
|
+
},
|
|
13
|
+
// 1. Remove 'async' here to prevent native Promise wrapping
|
|
14
|
+
apply(_, __, args) {
|
|
15
|
+
const url = [baseUrl, "api", "fn", workspace, ...path].join("/");
|
|
16
|
+
// 2. Start the fetch properly (without await)
|
|
17
|
+
const requestPromise = fetch(url, {
|
|
18
|
+
method: "POST",
|
|
19
|
+
body: JSON.stringify(args ?? {}),
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
"Accept": "text/event-stream,application/json",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
// 3. Return a custom "Thenable" object immediately
|
|
26
|
+
return {
|
|
27
|
+
then(onFulfilled, onRejected) {
|
|
28
|
+
requestPromise.then(async (response) => {
|
|
29
|
+
const contentType = response.headers.get("Content-Type") || "";
|
|
30
|
+
// ─────────────────────────────────────────────
|
|
31
|
+
// SSE PATH
|
|
32
|
+
// ─────────────────────────────────────────────
|
|
33
|
+
if (contentType.includes("text/event-stream")) {
|
|
34
|
+
const reader = response.body.getReader();
|
|
35
|
+
const decoder = new TextDecoder("utf-8");
|
|
36
|
+
let buffer = "";
|
|
37
|
+
try {
|
|
38
|
+
while (true) {
|
|
39
|
+
const { value, done } = await reader.read();
|
|
40
|
+
if (done)
|
|
41
|
+
break;
|
|
42
|
+
buffer += decoder.decode(value, { stream: true });
|
|
43
|
+
// Split by SSE message delimiter
|
|
44
|
+
const parts = buffer.split("\n\n");
|
|
45
|
+
buffer = parts.pop() || ""; // Keep incomplete chunk
|
|
46
|
+
for (const part of parts) {
|
|
47
|
+
// Extract data lines, remove 'data: ' prefix, join with newline
|
|
48
|
+
const message = part
|
|
49
|
+
.split("\n")
|
|
50
|
+
.filter(line => line.trim().startsWith("data: "))
|
|
51
|
+
.map(line => line.replace(/^data: /, ""))
|
|
52
|
+
.join("\n");
|
|
53
|
+
if (message) {
|
|
54
|
+
try {
|
|
55
|
+
// Emit parsed JSON
|
|
56
|
+
onFulfilled(JSON.parse(message));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Or emit raw string if parsing fails
|
|
60
|
+
onFulfilled(message);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (onRejected)
|
|
68
|
+
onRejected(err);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// ─────────────────────────────────────────────
|
|
72
|
+
// NORMAL JSON PATH
|
|
73
|
+
// ─────────────────────────────────────────────
|
|
74
|
+
else {
|
|
75
|
+
const data = await response.json();
|
|
76
|
+
onFulfilled(data.data ?? data);
|
|
77
|
+
}
|
|
78
|
+
}).catch((err) => {
|
|
79
|
+
if (onRejected)
|
|
80
|
+
onRejected(err);
|
|
81
|
+
});
|
|
82
|
+
// Return 'this' to allow chaining, though strictly custom behavior
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return handler;
|
|
90
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AuraAuth } from "./auth";
|
|
2
|
+
import { AuraDatabase } from "./database";
|
|
3
|
+
import { AuraStorage } from "./storage";
|
|
4
|
+
export * from "@inflector/optima/types";
|
|
5
|
+
export * from "./lib";
|
|
6
|
+
type CreateAuraConfig<T extends Record<string, any>> = {
|
|
7
|
+
config: {
|
|
8
|
+
Url: string;
|
|
9
|
+
WorkSpace: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
};
|
|
12
|
+
Tables: T;
|
|
13
|
+
};
|
|
14
|
+
type AuraInstance<F, T extends Record<string, any>> = {
|
|
15
|
+
Database: ReturnType<typeof AuraDatabase<T>>;
|
|
16
|
+
Function: F;
|
|
17
|
+
Storage: ReturnType<typeof AuraStorage>;
|
|
18
|
+
Auth: ReturnType<typeof AuraAuth>;
|
|
19
|
+
};
|
|
20
|
+
export declare const CreateAura: <F, T extends Record<string, any>>(Config: CreateAuraConfig<T>) => AuraInstance<F, T>;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,cAAc,yBAAyB,CAAC;AACxC,cAAc,OAAO,CAAC;AAEtB,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;IACnD,MAAM,EAAE;QACJ,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACtB,CAAC;IACF,MAAM,EAAE,CAAC,CAAC;CACb,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;IAClD,QAAQ,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,QAAQ,EAAE,CAAC,CAAC;IACZ,OAAO,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACxC,IAAI,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,UAAU,GACnB,CAAC,EACD,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAE7B,QAAQ,gBAAgB,CAAC,CAAC,CAAC,KAC5B,YAAY,CAAC,CAAC,EAAE,CAAC,CAQnB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AuraAuth } from "./auth";
|
|
2
|
+
import { AuraDatabase } from "./database";
|
|
3
|
+
import { createFunctionHandler } from "./function";
|
|
4
|
+
import { AuraStorage } from "./storage";
|
|
5
|
+
export * from "@inflector/optima/types";
|
|
6
|
+
export * from "./lib";
|
|
7
|
+
export const CreateAura = (Config) => {
|
|
8
|
+
const auth = AuraAuth(Config.config.Url, Config.config.WorkSpace);
|
|
9
|
+
return {
|
|
10
|
+
Database: AuraDatabase(Config.config.Url, Config.config.WorkSpace, Config.Tables),
|
|
11
|
+
Function: createFunctionHandler(Config.config.Url, Config.config.WorkSpace),
|
|
12
|
+
Auth: auth,
|
|
13
|
+
Storage: AuraStorage(Config.config.Url, Config.config.WorkSpace, auth.Signal),
|
|
14
|
+
};
|
|
15
|
+
};
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type AuraFunctionHandler<Args = any, Result = any> = (ctx: {
|
|
2
|
+
args: Args;
|
|
3
|
+
ctx: any;
|
|
4
|
+
secrets: Record<string, string>;
|
|
5
|
+
}) => Result | Promise<Result>;
|
|
6
|
+
export interface SSEHandler {
|
|
7
|
+
__isSSE: true;
|
|
8
|
+
handler: (send: (event: string, data: any) => void, close: () => void) => Promise<void> | void;
|
|
9
|
+
}
|
|
10
|
+
export declare function AuraFunction<Args = any, Result = any>(handler: AuraFunctionHandler<Args, Result>): AuraFunctionHandler<Args, Result>;
|
|
11
|
+
export declare function sse(handler: (send: (event: string, data: any) => void, close: () => void) => Promise<void> | void): SSEHandler;
|
|
12
|
+
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,mBAAmB,CAAC,IAAI,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,GAAG,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAA;CAAE,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtJ,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAChG;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,IAAI,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,EAC3D,OAAO,EAAE,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,GACzC,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAErC,MAAM,CAAC,OAAO,UAAU,GAAG,CACzB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAC7F,UAAU,CAAC"}
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type FileAura = {
|
|
2
|
+
ID: string;
|
|
3
|
+
FileName: string;
|
|
4
|
+
MimeType: string;
|
|
5
|
+
Size: number;
|
|
6
|
+
Path: string;
|
|
7
|
+
UploadedBy?: string;
|
|
8
|
+
UploadedAt: Date;
|
|
9
|
+
};
|
|
10
|
+
export declare const AuraStorage: (url: string, workspace: string, userAtom: any) => {
|
|
11
|
+
Upload: (file?: File, config?: {
|
|
12
|
+
openSelector?: boolean;
|
|
13
|
+
allowedTypes?: string[];
|
|
14
|
+
}) => Promise<any>;
|
|
15
|
+
File: (id: string) => string;
|
|
16
|
+
Delete: (id: string) => Promise<any>;
|
|
17
|
+
Get: (id: string) => Promise<FileAura | undefined>;
|
|
18
|
+
List: () => Promise<FileAura[]>;
|
|
19
|
+
UploadMultiple: (files?: File[], config?: {
|
|
20
|
+
openSelector?: boolean;
|
|
21
|
+
allowedTypes?: string[];
|
|
22
|
+
}) => Promise<any[]>;
|
|
23
|
+
Exists: (id: string) => Promise<boolean | undefined>;
|
|
24
|
+
Download: (id: string, download?: boolean) => Promise<{
|
|
25
|
+
blob: any;
|
|
26
|
+
fileName: string;
|
|
27
|
+
mimeType: any;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,IAAI,CAAC;CACpB,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,WAAW,MAAM,EAAE,UAAU,GAAG;oBAG1D,IAAI,WACH;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;eAgDhD,MAAM;iBAGE,MAAM;cAUT,MAAM;;6BAoBV,IAAI,EAAE,WACN;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;iBAuC5C,MAAM;mBAUJ,MAAM,aAAY,OAAO;;;;;CA6BrD,CAAA"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
export const AuraStorage = (url, workspace, userAtom) => {
|
|
3
|
+
const UploadFn = async (file, config = {}) => {
|
|
4
|
+
if (!userAtom.get().data)
|
|
5
|
+
return;
|
|
6
|
+
// If no file is passed, or openSelector is true, open a file input dialog automatically
|
|
7
|
+
if (!file || config.openSelector) {
|
|
8
|
+
return new Promise(async (resolve, reject) => {
|
|
9
|
+
const input = document.createElement("input");
|
|
10
|
+
input.type = "file";
|
|
11
|
+
// Set allowedTypes if provided
|
|
12
|
+
if (config.allowedTypes && config.allowedTypes.length > 0) {
|
|
13
|
+
input.accept = config.allowedTypes.join(",");
|
|
14
|
+
}
|
|
15
|
+
input.style.display = "none";
|
|
16
|
+
document.body.appendChild(input);
|
|
17
|
+
input.onchange = async () => {
|
|
18
|
+
try {
|
|
19
|
+
const selectedFile = input.files?.[0];
|
|
20
|
+
if (!selectedFile) {
|
|
21
|
+
reject(new Error("No file selected"));
|
|
22
|
+
document.body.removeChild(input);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const fd = new FormData();
|
|
26
|
+
fd.set("operation", "Upload");
|
|
27
|
+
fd.set("owner", userAtom.get().data.user.id);
|
|
28
|
+
fd.set("file", selectedFile);
|
|
29
|
+
const result = (await axios.post(url + "/api/storage/" + workspace, fd)).data;
|
|
30
|
+
resolve(result);
|
|
31
|
+
document.body.removeChild(input);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
reject(e);
|
|
35
|
+
document.body.removeChild(input);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
input.click();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const fd = new FormData();
|
|
43
|
+
fd.set("operation", "Upload");
|
|
44
|
+
fd.set("owner", userAtom.get().data.user.id);
|
|
45
|
+
fd.set("file", file);
|
|
46
|
+
return (await axios.post(url + "/api/storage/" + workspace, fd)).data;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
Upload: UploadFn,
|
|
51
|
+
File: (id) => {
|
|
52
|
+
return `${url}/api/storage/${workspace}/${id}`;
|
|
53
|
+
},
|
|
54
|
+
Delete: async (id) => {
|
|
55
|
+
if (!userAtom.get().data)
|
|
56
|
+
return;
|
|
57
|
+
return (await axios.post(url + "/api/storage/" + workspace, {
|
|
58
|
+
operation: "Delete",
|
|
59
|
+
settings: {
|
|
60
|
+
FileID: id,
|
|
61
|
+
Owner: userAtom.get().data.user.id
|
|
62
|
+
}
|
|
63
|
+
})).data;
|
|
64
|
+
},
|
|
65
|
+
Get: async (id) => {
|
|
66
|
+
if (!userAtom.get().data)
|
|
67
|
+
return;
|
|
68
|
+
return (await axios.post(url + "/api/storage/" + workspace, {
|
|
69
|
+
operation: "Get",
|
|
70
|
+
settings: {
|
|
71
|
+
FileID: id,
|
|
72
|
+
Owner: userAtom.get().data.user.id
|
|
73
|
+
}
|
|
74
|
+
})).data;
|
|
75
|
+
},
|
|
76
|
+
List: async () => {
|
|
77
|
+
if (!userAtom.get().data)
|
|
78
|
+
return [];
|
|
79
|
+
return (await axios.post(url + "/api/storage/" + workspace, {
|
|
80
|
+
operation: "List",
|
|
81
|
+
settings: {
|
|
82
|
+
Owner: userAtom.get().data.user.id
|
|
83
|
+
}
|
|
84
|
+
})).data;
|
|
85
|
+
},
|
|
86
|
+
UploadMultiple: async (files, config = {}) => {
|
|
87
|
+
// If files not passed or openSelector is true, open selector
|
|
88
|
+
if (config.openSelector || !files || files.length === 0) {
|
|
89
|
+
return await new Promise((resolve, reject) => {
|
|
90
|
+
const input = document.createElement("input");
|
|
91
|
+
input.type = "file";
|
|
92
|
+
input.multiple = true;
|
|
93
|
+
// Set allowedTypes if provided
|
|
94
|
+
if (config.allowedTypes && config.allowedTypes.length > 0) {
|
|
95
|
+
input.accept = config.allowedTypes.join(",");
|
|
96
|
+
}
|
|
97
|
+
input.style.display = "none";
|
|
98
|
+
document.body.appendChild(input);
|
|
99
|
+
input.onchange = async () => {
|
|
100
|
+
const selectedFiles = Array.from(input.files ?? []);
|
|
101
|
+
try {
|
|
102
|
+
if (selectedFiles.length === 0) {
|
|
103
|
+
reject(new Error("No files selected"));
|
|
104
|
+
document.body.removeChild(input);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const uploadResults = await Promise.all(selectedFiles.map(f => UploadFn(f, config)));
|
|
108
|
+
resolve(uploadResults);
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
reject(e);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
document.body.removeChild(input);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
input.click();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Use given files directly
|
|
122
|
+
return await Promise.all(files.map(f => UploadFn(f, config)));
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
Exists: async (id) => {
|
|
126
|
+
if (!userAtom.get().data)
|
|
127
|
+
return;
|
|
128
|
+
return (await axios.post(url + "/api/storage/" + workspace, {
|
|
129
|
+
operation: "Get",
|
|
130
|
+
settings: {
|
|
131
|
+
FileID: id,
|
|
132
|
+
Owner: userAtom.get().data.user.id
|
|
133
|
+
}
|
|
134
|
+
})).data;
|
|
135
|
+
},
|
|
136
|
+
Download: async (id, download = true) => {
|
|
137
|
+
try {
|
|
138
|
+
const response = await axios.get(`${url}/api/storage/${workspace}/${id}?download=${download ? '1' : '0'}`, {
|
|
139
|
+
responseType: "blob",
|
|
140
|
+
withCredentials: true
|
|
141
|
+
});
|
|
142
|
+
// Extract filename from content-disposition
|
|
143
|
+
const contentDisposition = response.headers["content-disposition"];
|
|
144
|
+
let fileName = id;
|
|
145
|
+
if (contentDisposition) {
|
|
146
|
+
const match = /filename="?([^"]+)"?/i.exec(contentDisposition);
|
|
147
|
+
if (match)
|
|
148
|
+
fileName = decodeURIComponent(match[1]);
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
blob: response.data,
|
|
152
|
+
fileName,
|
|
153
|
+
mimeType: response.headers["content-type"] || "application/octet-stream"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
if (error.response && error.response.data && error.response.data.message) {
|
|
158
|
+
throw new Error(error.response.data.message);
|
|
159
|
+
}
|
|
160
|
+
throw new Error("File not found");
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@inflector/aura",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": ["dist"],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"aura": "./dist/bin.js"
|
|
19
|
+
},
|
|
20
|
+
"browser": false,
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/bun": "latest",
|
|
23
|
+
"@types/node": "^20.14.10",
|
|
24
|
+
"ts-node": "^10.9.2",
|
|
25
|
+
"tslib": "^2.8.1",
|
|
26
|
+
"typescript": "^5.8.3",
|
|
27
|
+
"rollup": "^4.0.0",
|
|
28
|
+
"rollup-plugin-esbuild": "^6.1.0",
|
|
29
|
+
"rollup-plugin-dts": "^6.1.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"typescript": "^5"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@inflector/optima": "1.1.0",
|
|
36
|
+
"@nanostores/react": "^1.0.0",
|
|
37
|
+
"axios": "^1.13.2",
|
|
38
|
+
"better-auth": "^1.4.16",
|
|
39
|
+
"chalk": "^5.6.2",
|
|
40
|
+
"chokidar": "^5.0.0",
|
|
41
|
+
"eventsource": "^4.1.0",
|
|
42
|
+
"tsx": "^4.20.4",
|
|
43
|
+
"zod": "^3.25.67"
|
|
44
|
+
}
|
|
45
|
+
}
|