@luvabase/sdk 0.0.10 → 0.0.11
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/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -5
- package/dist/index.js.map +1 -1
- package/dist/manifest-schema.json +24 -0
- package/package.json +2 -2
- package/src/index.ts +43 -0
- package/src/manifestSchema.ts +8 -0
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,13 @@ declare const AppManifest: z.ZodLazy<z.ZodObject<{
|
|
|
72
72
|
name: z.ZodString;
|
|
73
73
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
74
74
|
}, z.core.$strip>>>;
|
|
75
|
+
hooks: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
76
|
+
type: z.ZodEnum<{
|
|
77
|
+
"app.update": "app.update";
|
|
78
|
+
"member.update": "member.update";
|
|
79
|
+
}>;
|
|
80
|
+
relativeUrl: z.ZodString;
|
|
81
|
+
}, z.core.$strip>>>;
|
|
75
82
|
relatedApps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
76
83
|
type: z.ZodEnum<{
|
|
77
84
|
android: "android";
|
|
@@ -118,6 +125,14 @@ declare function parseRequest(request: Request): {
|
|
|
118
125
|
name: string;
|
|
119
126
|
};
|
|
120
127
|
};
|
|
128
|
+
type Member = {
|
|
129
|
+
id: string;
|
|
130
|
+
name: string;
|
|
131
|
+
imageUrl: string | null;
|
|
132
|
+
};
|
|
133
|
+
declare function getCurrentUser(): Promise<Member>;
|
|
134
|
+
declare function getMembers(): Promise<Member[]>;
|
|
135
|
+
declare function getDevMembers(type?: "single" | "multi"): Promise<Member[]>;
|
|
121
136
|
//#endregion
|
|
122
|
-
export { AppManifest, LuvaEnv, R2RuntimeService, RelatedApp, RuntimeService, TursoRuntimeService, getAdminUrl, parseEnv, parseRequest };
|
|
137
|
+
export { AppManifest, LuvaEnv, R2RuntimeService, RelatedApp, RuntimeService, TursoRuntimeService, getAdminUrl, getCurrentUser, getDevMembers, getMembers, parseEnv, parseRequest };
|
|
123
138
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/envSchema.ts","../src/manifestSchema.ts","../src/index.ts"],"mappings":";;;KAEY,OAAA,GAAU,CAAA,CAAE,KAAA,QAAa,OAAA;AAAA,cACxB,OAAA,EAAO,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;KASR,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cACpC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;KASpB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,gBAAA;AAAA,cACjC,gBAAA,EAAgB,CAAA,CAAA,SAAA;;;;;;KAOjB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,cAAA;AAAA,cAC/B,cAAA,EAAc,CAAA,CAAA,QAAA,WAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;KC7Bf,WAAA,GAAc,CAAA,CAAE,KAAA,QAAa,WAAA;AAAA,cAC5B,WAAA,EAAW,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,SAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/envSchema.ts","../src/manifestSchema.ts","../src/index.ts"],"mappings":";;;KAEY,OAAA,GAAU,CAAA,CAAE,KAAA,QAAa,OAAA;AAAA,cACxB,OAAA,EAAO,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;KASR,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cACpC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;KASpB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,gBAAA;AAAA,cACjC,gBAAA,EAAgB,CAAA,CAAA,SAAA;;;;;;KAOjB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,cAAA;AAAA,cAC/B,cAAA,EAAc,CAAA,CAAA,QAAA,WAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;KC7Bf,WAAA,GAAc,CAAA,CAAE,KAAA,QAAa,WAAA;AAAA,cAC5B,WAAA,EAAW,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2EX,UAAA,EAAU,CAAA,CAAA,SAAA;;;;;;;;;;;iBCzEP,QAAA,CAAS,GAAA,EAAK,MAAA;;;;YAAA,MAAA;;;;;;;;;;;;;;iBAQd,WAAA,CAAY,GAAA,EAAK,MAAA;AAAA,iBAKjB,YAAA,CAAa,OAAA,EAAS,OAAA;;;;;;KASjC,MAAA;EACH,EAAA;EACA,IAAA;EACA,QAAA;AAAA;AAAA,iBAGoB,cAAA,CAAA,GAAkB,OAAA,CAAQ,MAAA;AAAA,iBAI1B,UAAA,CAAA,GAAc,OAAA,CAAQ,MAAA;AAAA,iBAItB,aAAA,CACpB,IAAA,wBACC,OAAA,CAAQ,MAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
|
|
3
2
|
//#region src/envSchema.ts
|
|
4
3
|
const LuvaEnv = z.lazy(() => z.object({
|
|
5
4
|
podId: z.string().describe("The id of the pod"),
|
|
@@ -22,7 +21,6 @@ const R2RuntimeService = z.object({
|
|
|
22
21
|
bucketName: z.string()
|
|
23
22
|
});
|
|
24
23
|
const RuntimeService = z.union([TursoRuntimeService, R2RuntimeService]);
|
|
25
|
-
|
|
26
24
|
//#endregion
|
|
27
25
|
//#region src/manifestSchema.ts
|
|
28
26
|
const AppManifest = z.lazy(() => z.object({
|
|
@@ -44,6 +42,10 @@ const AppManifest = z.lazy(() => z.object({
|
|
|
44
42
|
name: z.string(),
|
|
45
43
|
metadata: z.record(z.string(), z.any()).optional()
|
|
46
44
|
})).optional(),
|
|
45
|
+
hooks: z.array(z.object({
|
|
46
|
+
type: z.enum(["app.update", "member.update"]),
|
|
47
|
+
relativeUrl: z.string().describe("Relative URL to the hook handler")
|
|
48
|
+
})).optional(),
|
|
47
49
|
relatedApps: z.array(RelatedApp).optional()
|
|
48
50
|
}));
|
|
49
51
|
const RelatedApp = z.object({
|
|
@@ -52,7 +54,6 @@ const RelatedApp = z.object({
|
|
|
52
54
|
downloadLink: z.string().optional(),
|
|
53
55
|
redirectUrls: z.array(z.string())
|
|
54
56
|
});
|
|
55
|
-
|
|
56
57
|
//#endregion
|
|
57
58
|
//#region src/index.ts
|
|
58
59
|
function parseEnv(env) {
|
|
@@ -68,7 +69,36 @@ function parseRequest(request) {
|
|
|
68
69
|
name: request.headers.get("x-luva-user-name")
|
|
69
70
|
} };
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
+
async function getCurrentUser() {
|
|
73
|
+
return fetch("/api/me").then((res) => res.json());
|
|
74
|
+
}
|
|
75
|
+
async function getMembers() {
|
|
76
|
+
return fetch("/api/members").then((res) => res.json());
|
|
77
|
+
}
|
|
78
|
+
async function getDevMembers(type = "multi") {
|
|
79
|
+
const currentUser = await getCurrentUser();
|
|
80
|
+
if (type === "single") return [currentUser];
|
|
81
|
+
else if (type === "multi") return [
|
|
82
|
+
currentUser,
|
|
83
|
+
{
|
|
84
|
+
id: "cff82f4082bf996c36bb3",
|
|
85
|
+
name: "Jill Smith",
|
|
86
|
+
imageUrl: "https://i.pravatar.cc/150?u=a042581f4e29026701d"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "4082bf996c36bb39c3d9",
|
|
90
|
+
name: "Simon Smith",
|
|
91
|
+
imageUrl: "https://i.pravatar.cc/150?u=a042581f4e29026702d"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "bb39c3d9c3d92hdjj33s",
|
|
95
|
+
name: "Laura Williams",
|
|
96
|
+
imageUrl: "https://i.pravatar.cc/150?u=a042581f4e29026704d"
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
throw new Error(`Invalid dev member type: ${type}`);
|
|
100
|
+
}
|
|
72
101
|
//#endregion
|
|
73
|
-
export { AppManifest, LuvaEnv, R2RuntimeService, RelatedApp, RuntimeService, TursoRuntimeService, getAdminUrl, parseEnv, parseRequest };
|
|
102
|
+
export { AppManifest, LuvaEnv, R2RuntimeService, RelatedApp, RuntimeService, TursoRuntimeService, getAdminUrl, getCurrentUser, getDevMembers, getMembers, parseEnv, parseRequest };
|
|
103
|
+
|
|
74
104
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/envSchema.ts","../src/manifestSchema.ts","../src/index.ts"],"sourcesContent":["import { z } from \"zod\"\n\nexport type LuvaEnv = z.infer<typeof LuvaEnv>\nexport const LuvaEnv = z.lazy(() =>\n z.object({\n podId: z.string().describe(\"The id of the pod\"),\n installedAt: z.string(),\n updatedAt: z.string(),\n services: z.record(z.string(), RuntimeService),\n }),\n)\n\nexport type TursoRuntimeService = z.infer<typeof TursoRuntimeService>\nexport const TursoRuntimeService = z.object({\n type: z.literal(\"turso\"),\n name: z.string(),\n createdAt: z.string(),\n databaseName: z.string(),\n databaseApiToken: z.string(),\n databaseHostname: z.string(),\n})\n\nexport type R2RuntimeService = z.infer<typeof R2RuntimeService>\nexport const R2RuntimeService = z.object({\n type: z.literal(\"r2\"),\n name: z.string(),\n createdAt: z.string(),\n bucketName: z.string(),\n})\n\nexport type RuntimeService = z.infer<typeof RuntimeService>\nexport const RuntimeService = z.union([TursoRuntimeService, R2RuntimeService])\n","import { z } from \"zod\"\n\nexport type AppManifest = z.infer<typeof AppManifest>\nexport const AppManifest = z.lazy(() =>\n z.object({\n $schema: z.string().optional().describe(\"JSON Schema for the manifest\"),\n identifier: z\n .string()\n .regex(/^[a-z0-9-]+$/)\n .min(3)\n .max(50)\n .optional()\n .describe(\n \"Globally unique url safe and lowercased identifier for the app e.g. 'luvabase-snake' (required for Luvabase submissions)\",\n ),\n name: z\n .string()\n .min(3)\n .max(30)\n .describe(\"Name of the app e.g. 'Snake' (max 30 characters)\"),\n subtitle: z\n .string()\n .min(3)\n .max(50)\n .optional()\n .describe(\n \"Subtitle of the app e.g. 'Play the classic of classics' (max 50 characters)\",\n ),\n description: z\n .string()\n .max(10000)\n .optional()\n .describe(\"Full description of the app\"),\n screenshots: z\n .array(z.string())\n .optional()\n .describe(\n \"Relative paths of app screenshots e.g. ['images/screenshot1.png', 'images/screenshot2.png']\",\n ),\n category: z\n .string()\n .optional()\n .describe(\n \"Could be 'productivity', 'health', etc (must be one of the standard categories listed here https://github.com/w3c/manifest/wiki/Categories)\",\n ),\n icon: z\n .string()\n .optional()\n .describe(\n \"Relative path of the app icon inside the .luva app file e.g. 'images/icon.png'\",\n ),\n repository: z\n .string()\n .optional()\n .describe(\n \"URL of the source code repository e.g. 'https://github.com/luvabase/snake'\",\n ),\n services: z\n .array(\n z.object({\n type: z.enum([\"turso\", \"durable-object\", \"r2\"]),\n name: z.string(),\n metadata: z.record(z.string(), z.any()).optional(),\n }),\n )\n .optional(),\n relatedApps: z.array(RelatedApp).optional(),\n }),\n)\n\nexport const RelatedApp = z.object({\n type: z.enum([\"android\", \"ios\"]),\n identifier: z.string(), // android package name or ios bundle id\n downloadLink: z.string().optional(),\n redirectUrls: z.array(z.string()),\n})\n","import { LuvaEnv } from \"./envSchema\"\n\nexport * from \"./envSchema\"\nexport * from \"./manifestSchema\"\n\nexport function parseEnv(env: Record<string, unknown> | string) {\n if (typeof env === \"string\") {\n env = JSON.parse(env)\n }\n const luvabaseEnv = LuvaEnv.parse(env)\n return luvabaseEnv\n}\n\nexport function getAdminUrl(env: Record<string, unknown> | string) {\n const luvaEnv = parseEnv(env)\n return `https://luvabase.com/dash/pods/${luvaEnv.podId}`\n}\n\nexport function parseRequest(request: Request) {\n return {\n user: {\n id: request.headers.get(\"x-luva-user-id\")!,\n name: request.headers.get(\"x-luva-user-name\")!,\n },\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/envSchema.ts","../src/manifestSchema.ts","../src/index.ts"],"sourcesContent":["import { z } from \"zod\"\n\nexport type LuvaEnv = z.infer<typeof LuvaEnv>\nexport const LuvaEnv = z.lazy(() =>\n z.object({\n podId: z.string().describe(\"The id of the pod\"),\n installedAt: z.string(),\n updatedAt: z.string(),\n services: z.record(z.string(), RuntimeService),\n }),\n)\n\nexport type TursoRuntimeService = z.infer<typeof TursoRuntimeService>\nexport const TursoRuntimeService = z.object({\n type: z.literal(\"turso\"),\n name: z.string(),\n createdAt: z.string(),\n databaseName: z.string(),\n databaseApiToken: z.string(),\n databaseHostname: z.string(),\n})\n\nexport type R2RuntimeService = z.infer<typeof R2RuntimeService>\nexport const R2RuntimeService = z.object({\n type: z.literal(\"r2\"),\n name: z.string(),\n createdAt: z.string(),\n bucketName: z.string(),\n})\n\nexport type RuntimeService = z.infer<typeof RuntimeService>\nexport const RuntimeService = z.union([TursoRuntimeService, R2RuntimeService])\n","import { z } from \"zod\"\n\nexport type AppManifest = z.infer<typeof AppManifest>\nexport const AppManifest = z.lazy(() =>\n z.object({\n $schema: z.string().optional().describe(\"JSON Schema for the manifest\"),\n identifier: z\n .string()\n .regex(/^[a-z0-9-]+$/)\n .min(3)\n .max(50)\n .optional()\n .describe(\n \"Globally unique url safe and lowercased identifier for the app e.g. 'luvabase-snake' (required for Luvabase submissions)\",\n ),\n name: z\n .string()\n .min(3)\n .max(30)\n .describe(\"Name of the app e.g. 'Snake' (max 30 characters)\"),\n subtitle: z\n .string()\n .min(3)\n .max(50)\n .optional()\n .describe(\n \"Subtitle of the app e.g. 'Play the classic of classics' (max 50 characters)\",\n ),\n description: z\n .string()\n .max(10000)\n .optional()\n .describe(\"Full description of the app\"),\n screenshots: z\n .array(z.string())\n .optional()\n .describe(\n \"Relative paths of app screenshots e.g. ['images/screenshot1.png', 'images/screenshot2.png']\",\n ),\n category: z\n .string()\n .optional()\n .describe(\n \"Could be 'productivity', 'health', etc (must be one of the standard categories listed here https://github.com/w3c/manifest/wiki/Categories)\",\n ),\n icon: z\n .string()\n .optional()\n .describe(\n \"Relative path of the app icon inside the .luva app file e.g. 'images/icon.png'\",\n ),\n repository: z\n .string()\n .optional()\n .describe(\n \"URL of the source code repository e.g. 'https://github.com/luvabase/snake'\",\n ),\n services: z\n .array(\n z.object({\n type: z.enum([\"turso\", \"durable-object\", \"r2\"]),\n name: z.string(),\n metadata: z.record(z.string(), z.any()).optional(),\n }),\n )\n .optional(),\n hooks: z\n .array(\n z.object({\n type: z.enum([\"app.update\", \"member.update\"]),\n relativeUrl: z.string().describe(\"Relative URL to the hook handler\"),\n }),\n )\n .optional(),\n relatedApps: z.array(RelatedApp).optional(),\n }),\n)\n\nexport const RelatedApp = z.object({\n type: z.enum([\"android\", \"ios\"]),\n identifier: z.string(), // android package name or ios bundle id\n downloadLink: z.string().optional(),\n redirectUrls: z.array(z.string()),\n})\n","import { LuvaEnv } from \"./envSchema\"\n\nexport * from \"./envSchema\"\nexport * from \"./manifestSchema\"\n\nexport function parseEnv(env: Record<string, unknown> | string) {\n if (typeof env === \"string\") {\n env = JSON.parse(env)\n }\n const luvabaseEnv = LuvaEnv.parse(env)\n return luvabaseEnv\n}\n\nexport function getAdminUrl(env: Record<string, unknown> | string) {\n const luvaEnv = parseEnv(env)\n return `https://luvabase.com/dash/pods/${luvaEnv.podId}`\n}\n\nexport function parseRequest(request: Request) {\n return {\n user: {\n id: request.headers.get(\"x-luva-user-id\")!,\n name: request.headers.get(\"x-luva-user-name\")!,\n },\n }\n}\n\ntype Member = {\n id: string\n name: string\n imageUrl: string | null\n}\n\nexport async function getCurrentUser(): Promise<Member> {\n return fetch(\"/api/me\").then((res) => res.json())\n}\n\nexport async function getMembers(): Promise<Member[]> {\n return fetch(\"/api/members\").then((res) => res.json())\n}\n\nexport async function getDevMembers(\n type: \"single\" | \"multi\" = \"multi\",\n): Promise<Member[]> {\n const currentUser = await getCurrentUser()\n if (type === \"single\") {\n return [currentUser]\n } else if (type === \"multi\") {\n return [\n currentUser,\n {\n id: \"cff82f4082bf996c36bb3\",\n name: \"Jill Smith\",\n imageUrl: \"https://i.pravatar.cc/150?u=a042581f4e29026701d\",\n },\n {\n id: \"4082bf996c36bb39c3d9\",\n name: \"Simon Smith\",\n imageUrl: \"https://i.pravatar.cc/150?u=a042581f4e29026702d\",\n },\n {\n id: \"bb39c3d9c3d92hdjj33s\",\n name: \"Laura Williams\",\n imageUrl: \"https://i.pravatar.cc/150?u=a042581f4e29026704d\",\n },\n ]\n }\n throw new Error(`Invalid dev member type: ${type}`)\n}\n"],"mappings":"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"}
|
|
@@ -80,6 +80,30 @@
|
|
|
80
80
|
"additionalProperties": false
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
|
+
"hooks": {
|
|
84
|
+
"type": "array",
|
|
85
|
+
"items": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"properties": {
|
|
88
|
+
"type": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"enum": [
|
|
91
|
+
"app.update",
|
|
92
|
+
"member.update"
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"relativeUrl": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"description": "Relative URL to the hook handler"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"required": [
|
|
101
|
+
"type",
|
|
102
|
+
"relativeUrl"
|
|
103
|
+
],
|
|
104
|
+
"additionalProperties": false
|
|
105
|
+
}
|
|
106
|
+
},
|
|
83
107
|
"relatedApps": {
|
|
84
108
|
"type": "array",
|
|
85
109
|
"items": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luvabase/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build": "tsdown src/index.ts && bun run generate-manifest-json-schema"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"tsdown": "^0.21.
|
|
21
|
+
"tsdown": "^0.21.2"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"zod": "^4.3.6"
|
package/src/index.ts
CHANGED
|
@@ -24,3 +24,46 @@ export function parseRequest(request: Request) {
|
|
|
24
24
|
},
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
type Member = {
|
|
29
|
+
id: string
|
|
30
|
+
name: string
|
|
31
|
+
imageUrl: string | null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function getCurrentUser(): Promise<Member> {
|
|
35
|
+
return fetch("/api/me").then((res) => res.json())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function getMembers(): Promise<Member[]> {
|
|
39
|
+
return fetch("/api/members").then((res) => res.json())
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function getDevMembers(
|
|
43
|
+
type: "single" | "multi" = "multi",
|
|
44
|
+
): Promise<Member[]> {
|
|
45
|
+
const currentUser = await getCurrentUser()
|
|
46
|
+
if (type === "single") {
|
|
47
|
+
return [currentUser]
|
|
48
|
+
} else if (type === "multi") {
|
|
49
|
+
return [
|
|
50
|
+
currentUser,
|
|
51
|
+
{
|
|
52
|
+
id: "cff82f4082bf996c36bb3",
|
|
53
|
+
name: "Jill Smith",
|
|
54
|
+
imageUrl: "https://i.pravatar.cc/150?u=a042581f4e29026701d",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "4082bf996c36bb39c3d9",
|
|
58
|
+
name: "Simon Smith",
|
|
59
|
+
imageUrl: "https://i.pravatar.cc/150?u=a042581f4e29026702d",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "bb39c3d9c3d92hdjj33s",
|
|
63
|
+
name: "Laura Williams",
|
|
64
|
+
imageUrl: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`Invalid dev member type: ${type}`)
|
|
69
|
+
}
|
package/src/manifestSchema.ts
CHANGED
|
@@ -64,6 +64,14 @@ export const AppManifest = z.lazy(() =>
|
|
|
64
64
|
}),
|
|
65
65
|
)
|
|
66
66
|
.optional(),
|
|
67
|
+
hooks: z
|
|
68
|
+
.array(
|
|
69
|
+
z.object({
|
|
70
|
+
type: z.enum(["app.update", "member.update"]),
|
|
71
|
+
relativeUrl: z.string().describe("Relative URL to the hook handler"),
|
|
72
|
+
}),
|
|
73
|
+
)
|
|
74
|
+
.optional(),
|
|
67
75
|
relatedApps: z.array(RelatedApp).optional(),
|
|
68
76
|
}),
|
|
69
77
|
)
|