@tiddlywiki/mws 0.0.12 → 0.0.13
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 +3 -1
- package/dist/server.d.ts +923 -0
- package/dist/server.js +1763 -1415
- package/dist/server.js.map +1 -1
- package/editions/mws-docs/tiddlers/$__StoryList.tid +3 -3
- package/editions/mws-docs/tiddlers/MWS and SQLite.md +11 -0
- package/editions/mws-docs/tiddlers/Request Server.md +20 -0
- package/editions/mws-docs/tiddlers/Request Server.md.meta +5 -0
- package/package.json +16 -10
- package/prisma/schema.prisma +1 -0
- package/react-user-mgmt/package-lock.json +76 -321
- package/react-user-mgmt/package.json +2 -5
- package/react-user-mgmt/public/chunk-YALWN5OT.js +2 -0
- package/react-user-mgmt/public/chunk-YALWN5OT.js.map +7 -0
- package/react-user-mgmt/public/esm-QKDFEP3B.js +3 -0
- package/react-user-mgmt/public/esm-QKDFEP3B.js.map +7 -0
- package/react-user-mgmt/public/index.html +1 -26
- package/react-user-mgmt/public/main.js +68 -109
- package/react-user-mgmt/public/main.js.map +4 -4
- package/react-user-mgmt/public/stats.css +597 -0
- package/react-user-mgmt/public/stats.html +59 -0
- package/react-user-mgmt/public/stats.js +2013 -0
- package/react-user-mgmt/public/stats.json +1 -0
- package/react-user-mgmt/public/stats.svg +4 -0
- package/react-user-mgmt/tsconfig.json +3 -0
- package/dist/server.cjs +0 -16677
- package/dist/server.cjs.map +0 -1
- package/src/StateObject.ts +0 -316
- package/src/commander.ts +0 -417
- package/src/commands/divider.ts +0 -20
- package/src/commands/index.ts +0 -24
- package/src/commands/mws-init-store.ts +0 -77
- package/src/commands/mws-listen.ts +0 -136
- package/src/commands/mws-load-archive.ts +0 -281
- package/src/commands/mws-load-plugin-bags.ts +0 -151
- package/src/commands/mws-load-tiddlers.ts +0 -37
- package/src/commands/mws-load-wiki-folder.ts +0 -124
- package/src/commands/mws-render-tiddlywiki5.ts +0 -55
- package/src/commands/mws-save-archive.ts +0 -111
- package/src/commands/mws-save-tiddler-text.ts +0 -33
- package/src/commands/tests-complete.ts +0 -21
- package/src/global.ts +0 -247
- package/src/routes/TiddlerStore.ts +0 -722
- package/src/routes/bag-file-server.ts +0 -340
- package/src/routes/cache.ts +0 -25
- package/src/routes/index.ts +0 -138
- package/src/routes/managers/index.ts +0 -17
- package/src/routes/managers/manager-recipes.ts +0 -438
- package/src/routes/managers/manager-users.ts +0 -201
- package/src/routes/managers/router-tiddlers.ts +0 -313
- package/src/routes/router.ts +0 -429
- package/src/routes/services/PasswordService.ts +0 -178
- package/src/routes/services/attachments.ts +0 -259
- package/src/routes/services/sessions.ts +0 -166
- package/src/routes/tw-test.ts +0 -65
- package/src/server.ts +0 -151
- package/src/setupDevServer.ts +0 -71
- package/src/streamer.ts +0 -430
- package/src/tiddlywiki.ts +0 -94
- package/src/utils/data-checks.ts +0 -172
- package/src/utils/index.ts +0 -4
- package/src/utils/rootRoute.ts +0 -237
- package/src/utils/utils.ts +0 -403
- package/src/utils/zodAssert.ts +0 -269
- /package/prisma/{migrations/notes.md → notes.md} +0 -0
package/src/utils/data-checks.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { Prisma } from "@prisma/client";
|
|
2
|
-
import { truthy } from "./utils";
|
|
3
|
-
import { ok } from "node:assert";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export class DataChecks {
|
|
7
|
-
allowAnonReads;
|
|
8
|
-
allowAnonWrites;
|
|
9
|
-
constructor(options: { allowAnonReads?: boolean, allowAnonWrites?: boolean }) {
|
|
10
|
-
this.allowAnonReads = options.allowAnonReads;
|
|
11
|
-
this.allowAnonWrites = options.allowAnonWrites;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
okTiddlerFields(tiddlerFields: Record<string, any>) {
|
|
15
|
-
ok(tiddlerFields.title, 'title must not be empty');
|
|
16
|
-
Object.entries(tiddlerFields).forEach(([key, value]) => {
|
|
17
|
-
if (typeof value === "undefined" || value === null) return;
|
|
18
|
-
ok(typeof value === "string", `tiddler fields must be a string, ${key} is ${typeof value}`);
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
okBagName(bagName: PrismaField<"Bags", "bag_name">) {
|
|
23
|
-
ok(typeof bagName === "string", 'bagName must be a string');
|
|
24
|
-
ok(bagName, 'bagName must not be empty');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
okRecipeName(recipeName: PrismaField<"Recipes", "recipe_name">) {
|
|
28
|
-
ok(typeof recipeName === "string", 'recipeName must be a string');
|
|
29
|
-
ok(recipeName, 'recipeName must not be empty');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
okUserID(userID: PrismaField<"Users", "user_id">) {
|
|
33
|
-
ok(typeof userID === "number", 'userID must be a number');
|
|
34
|
-
ok(userID > 0, 'userID must be greater than zero');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
okTiddlerTitle(tiddlerTitle: string): asserts tiddlerTitle is PrismaField<"Tiddlers", "title"> {
|
|
38
|
-
ok(typeof tiddlerTitle === "string", 'tiddler title must be a string');
|
|
39
|
-
ok(tiddlerTitle, 'tiddler title must not be empty');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
okEntityType(entityType: EntityType) {
|
|
43
|
-
ok(entityType === "bag" || entityType === "recipe", "Invalid entity type: " + entityType);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
okEntityName(entityName: EntityName<EntityType>) {
|
|
47
|
-
ok(typeof entityName === "string", 'entityName must be a string');
|
|
48
|
-
ok(entityName, 'entityName must not be empty');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
okSessionID(sessionID: string): asserts sessionID is PrismaField<"Sessions", "session_id"> {
|
|
52
|
-
ok(typeof sessionID === "string", 'sessionID must be a string');
|
|
53
|
-
ok(sessionID, 'sessionID must not be empty');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
isPermissionName = <T extends string>(e: T): e is T & ACLPermissionName => {
|
|
57
|
-
const test = e as ACLPermissionName;
|
|
58
|
-
switch (test) {
|
|
59
|
-
case "ADMIN":
|
|
60
|
-
case "READ":
|
|
61
|
-
case "WRITE":
|
|
62
|
-
return true;
|
|
63
|
-
default: {
|
|
64
|
-
const _: never = test;
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
permissions: { [K in ACLPermissionName]: K } = { READ: "READ", WRITE: "WRITE", ADMIN: "ADMIN", };
|
|
71
|
-
|
|
72
|
-
isEntityType = (x: any): x is "recipe" | "bag" => ["recipe", "bag"].includes(x);
|
|
73
|
-
|
|
74
|
-
entityTypes: { [K in EntityType]: K } = { recipe: "recipe", bag: "bag" };
|
|
75
|
-
|
|
76
|
-
/** If the user isn't logged in, user_id is 0. */
|
|
77
|
-
getBagWhereACL({ recipe_id, permission, user_id, role_ids }: {
|
|
78
|
-
/** Recipe ID can be provided as an extra restriction */
|
|
79
|
-
recipe_id?: number,
|
|
80
|
-
permission: ACLPermissionName,
|
|
81
|
-
user_id: number,
|
|
82
|
-
role_ids: number[],
|
|
83
|
-
}) {
|
|
84
|
-
|
|
85
|
-
const OR = this.getWhereACL({ permission, user_id, role_ids });
|
|
86
|
-
|
|
87
|
-
return ([
|
|
88
|
-
// all system bags are allowed to be read by any user
|
|
89
|
-
permission === "READ" && { is_plugin: true },
|
|
90
|
-
...OR,
|
|
91
|
-
// admin permission doesn't get inherited
|
|
92
|
-
permission === "ADMIN" ? undefined : {
|
|
93
|
-
recipe_bags: {
|
|
94
|
-
some: {
|
|
95
|
-
// check if we're in position 0 (for write) or any position (for read)
|
|
96
|
-
position: permission === "WRITE" ? 0 : undefined,
|
|
97
|
-
// of a recipe that the user has this permission on
|
|
98
|
-
recipe: { OR },
|
|
99
|
-
// if the connection was created with admin permissions
|
|
100
|
-
with_acl: true,
|
|
101
|
-
// for the specific recipe, if provided
|
|
102
|
-
recipe_id,
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
] satisfies (Prisma.BagsWhereInput | undefined | null | false)[]).filter(truthy)
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
getWhereACL({ permission, user_id, role_ids }: {
|
|
110
|
-
permission: ACLPermissionName,
|
|
111
|
-
user_id?: number,
|
|
112
|
-
role_ids?: number[],
|
|
113
|
-
}) {
|
|
114
|
-
const { allowAnonReads, allowAnonWrites } = this;
|
|
115
|
-
const anonRead = allowAnonReads && permission === "READ";
|
|
116
|
-
const anonWrite = allowAnonWrites && permission === "WRITE";
|
|
117
|
-
const allowAnon = anonRead || anonWrite;
|
|
118
|
-
const allperms = ["READ", "WRITE", "ADMIN"] as const;
|
|
119
|
-
const index = allperms.indexOf(permission);
|
|
120
|
-
if (index === -1) throw new Error("Invalid permission");
|
|
121
|
-
const checkPerms = allperms.slice(index);
|
|
122
|
-
|
|
123
|
-
return ([
|
|
124
|
-
// allow unowned for any user (conditional for anon reads)
|
|
125
|
-
(user_id || allowAnon) && { acl: { none: {} }, owner_id: null },
|
|
126
|
-
// allow owner for user
|
|
127
|
-
user_id && { owner_id: user_id },
|
|
128
|
-
// allow acl for user
|
|
129
|
-
user_id && role_ids?.length && {
|
|
130
|
-
acl: {
|
|
131
|
-
some: {
|
|
132
|
-
permission: { in: checkPerms },
|
|
133
|
-
role_id: { in: role_ids },
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
user_id && role_ids?.length && {
|
|
138
|
-
acl: {
|
|
139
|
-
some: {
|
|
140
|
-
permission: { in: checkPerms },
|
|
141
|
-
role_id: { in: role_ids },
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
] satisfies (Prisma.RecipesWhereInput | Prisma.BagsWhereInput | undefined | null | false | 0)[]
|
|
147
|
-
).filter(truthy)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
## assumptions about prisma that should be tested
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
return await this.engine.acl.findMany({
|
|
161
|
-
where: {
|
|
162
|
-
entity_name: entityName,
|
|
163
|
-
entity_type: entityType,
|
|
164
|
-
// if permission_name is undefined, will prisma
|
|
165
|
-
// include records without a permission connection?
|
|
166
|
-
// ChatGPT 03-mini-high doesn't think so.
|
|
167
|
-
permission: { permission_name }
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
```
|
|
171
|
-
*/
|
|
172
|
-
declare let _dataChecks: any;
|
package/src/utils/index.ts
DELETED
package/src/utils/rootRoute.ts
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import { AuthStateRouteACL, StateObject } from "../StateObject";
|
|
2
|
-
import * as z from "zod";
|
|
3
|
-
import { AllowedMethod, BodyFormat } from "../routes/router";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export interface RouteOptAny extends RouteOptBase<BodyFormat, AllowedMethod[], string[]> { }
|
|
7
|
-
|
|
8
|
-
export interface Route extends RouteDef<ParentTuple, string[]> { }
|
|
9
|
-
|
|
10
|
-
export interface rootRoute extends RouteDef<[
|
|
11
|
-
undefined,
|
|
12
|
-
AllowedMethod[],
|
|
13
|
-
StateObject<BodyFormat, AllowedMethod>,
|
|
14
|
-
[[]]
|
|
15
|
-
], []> { }
|
|
16
|
-
|
|
17
|
-
export interface RouteMatch {
|
|
18
|
-
route: Route;
|
|
19
|
-
params: (string | undefined)[];
|
|
20
|
-
remainingPath: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
type DetermineRouteOptions<
|
|
24
|
-
P extends ParentTuple, PA extends string[]
|
|
25
|
-
> = P extends [BodyFormat, AllowedMethod[], any, any]
|
|
26
|
-
?
|
|
27
|
-
RouteOptBase<P[0], P[1], PA> & { bodyFormat?: undefined; }
|
|
28
|
-
:
|
|
29
|
-
P extends [undefined, AllowedMethod[], any, any]
|
|
30
|
-
?
|
|
31
|
-
| { [K in BodyFormat]: RouteOptBase<K, P[1], PA> & { bodyFormat: K; }; }[BodyFormat]
|
|
32
|
-
| RouteOptBase<BodyFormat, P[1], PA> & { bodyFormat?: undefined; }
|
|
33
|
-
: never;
|
|
34
|
-
|
|
35
|
-
type ParentTuple = [BodyFormat | undefined, AllowedMethod[], any, string[][]];
|
|
36
|
-
|
|
37
|
-
interface RouteOptBase<B extends BodyFormat, M extends AllowedMethod[], PA extends string[]> {
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Regex to test the pathname on. It must start with `^`. If this is a child route,
|
|
41
|
-
* it will be tested against the remaining portion of the parent route.
|
|
42
|
-
*/
|
|
43
|
-
path: RegExp;
|
|
44
|
-
pathParams?: PA;
|
|
45
|
-
/** The uppercase method names to match this route */
|
|
46
|
-
method: M;
|
|
47
|
-
/**
|
|
48
|
-
* The highest bodyformat in the chain always takes precedent. Type-wise, only one is allowed,
|
|
49
|
-
* but at runtime the first one found is the one used.
|
|
50
|
-
*
|
|
51
|
-
* Note that bodyFormat is completely ignored for GET and HEAD requests.
|
|
52
|
-
*/
|
|
53
|
-
bodyFormat?: B;
|
|
54
|
-
/** If this route is the last one matched, it will NOT be called, and a 404 will be returned. */
|
|
55
|
-
denyFinal?: boolean;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface RouteDef<P extends ParentTuple, PA extends string[]> extends RouteOptBase<P[0] & {}, P[1], PA> {
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* If this route's handler sends headers, the matched child route will not be called.
|
|
62
|
-
*/
|
|
63
|
-
handler: (state: StateObject<P[0] extends undefined ? BodyFormat : (P[0] & {}), P[1][number], [...P[3], [...PA]], unknown>) => Promise<P[2]>
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* ### ROUTING
|
|
67
|
-
*
|
|
68
|
-
* @param route The route definition.
|
|
69
|
-
*
|
|
70
|
-
* If the parent route sends headers, or returns the STREAM_ENDED symbol,
|
|
71
|
-
* this route will not be called.
|
|
72
|
-
*
|
|
73
|
-
* Inner routes are matched on the remaining portion of the parent route
|
|
74
|
-
* using `pathname.slice(match[0].length)`. If the parent route entirely
|
|
75
|
-
* matches the pathname, this route will be matched on "/".
|
|
76
|
-
*
|
|
77
|
-
* If the body format is "stream", "buffer", "ignore" or not yet defined at this level in the tree,
|
|
78
|
-
* then zod cannot be used.
|
|
79
|
-
*
|
|
80
|
-
* Note that GET and HEAD are always bodyFormat: "ignore", regardless of what is set here.
|
|
81
|
-
*/
|
|
82
|
-
defineRoute: <R, PA extends string[],
|
|
83
|
-
// T extends DetermineRouteOptions<P, [...PA]>
|
|
84
|
-
T extends (P extends [BodyFormat, AllowedMethod[], any, any]
|
|
85
|
-
?
|
|
86
|
-
RouteOptBase<P[0], P[1], [...PA]> & { bodyFormat?: undefined; }
|
|
87
|
-
:
|
|
88
|
-
P extends [undefined, AllowedMethod[], any, any]
|
|
89
|
-
?
|
|
90
|
-
| { [K in BodyFormat]: RouteOptBase<K, P[1], [...PA]> & { bodyFormat: K; }; }[BodyFormat]
|
|
91
|
-
| RouteOptBase<BodyFormat, P[1], [...PA]> & { bodyFormat?: undefined; }
|
|
92
|
-
: never)
|
|
93
|
-
> (
|
|
94
|
-
route: T,
|
|
95
|
-
handler: (
|
|
96
|
-
/**
|
|
97
|
-
* The state object for this route.
|
|
98
|
-
*
|
|
99
|
-
* If the route only specifies "GET" and/or "HEAD", then the bodyFormat can only be "ignore"
|
|
100
|
-
*
|
|
101
|
-
* Otherwise, the bodyFormat is determined by the first parent route that specifies it.
|
|
102
|
-
*
|
|
103
|
-
* The state object is wrapped in a proxy which throws if methods return a promise that
|
|
104
|
-
* doesn't get awaited before the next property access. It only enforces the first layer
|
|
105
|
-
* of properties, so if you have a nested object, you will need to wrap it in a proxy as well.
|
|
106
|
-
*
|
|
107
|
-
* store and store.sql will probably also be wrapped in this proxy.
|
|
108
|
-
*/
|
|
109
|
-
state: StateObject<
|
|
110
|
-
// if the route only specifies "GET" and/or "HEAD", then the bodyFormat can only be "ignore"
|
|
111
|
-
(Exclude<T["method"][number], "GET" | "HEAD"> extends never ? never : (
|
|
112
|
-
// parent route specified bodyFormat?
|
|
113
|
-
P[0] extends BodyFormat ? P[0] :
|
|
114
|
-
// this route specified bodyFormat?
|
|
115
|
-
T["bodyFormat"] extends BodyFormat ? T["bodyFormat"] :
|
|
116
|
-
// otherwise it could be anything
|
|
117
|
-
BodyFormat
|
|
118
|
-
)) | (
|
|
119
|
-
// GET and HEAD requests imply "ignore"
|
|
120
|
-
T["method"][number] extends "GET" | "HEAD" ? "ignore" : never
|
|
121
|
-
),
|
|
122
|
-
// HTTP method
|
|
123
|
-
T["method"][number],
|
|
124
|
-
// possible placeholder for declaring routes
|
|
125
|
-
getPA<P, T>,
|
|
126
|
-
// infer zod, if set for this route
|
|
127
|
-
unknown
|
|
128
|
-
>) => Promise<R>
|
|
129
|
-
) =>
|
|
130
|
-
P[0] extends BodyFormat ? RouteDef<[P[0], T["method"], R, P[3]], [...PA]> :
|
|
131
|
-
T["bodyFormat"] extends BodyFormat ? RouteDef<[T["bodyFormat"], T["method"], R, P[3]], [...PA]> :
|
|
132
|
-
RouteDef<[undefined, T["method"], R, P[3]], [...PA]>
|
|
133
|
-
|
|
134
|
-
$o?: P;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
type getPA<P extends ParentTuple, T extends DetermineRouteOptions<P, any>> =
|
|
138
|
-
[...P[3], ...T["pathParams"] extends string[] ? [T["pathParams"]] : []];
|
|
139
|
-
function test<T extends z.ZodTypeAny>(schema: { schema: T }): T {
|
|
140
|
-
return schema.schema;
|
|
141
|
-
}
|
|
142
|
-
const test1 = test({ schema: z.object({ test: z.string() }) })
|
|
143
|
-
type t1 = typeof test1;
|
|
144
|
-
type t2 = z.infer<t1>;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
/** This doesn't need to run, it's just to test types */
|
|
149
|
-
function testroute(root: rootRoute) {
|
|
150
|
-
|
|
151
|
-
const test1 = root.defineRoute({
|
|
152
|
-
path: /^test/,
|
|
153
|
-
method: ["GET", "POST"],
|
|
154
|
-
bodyFormat: undefined,
|
|
155
|
-
}, async state => {
|
|
156
|
-
const test: BodyFormat = state.bodyFormat;
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const test2_2 = test1.defineRoute({
|
|
160
|
-
path: /^test/,
|
|
161
|
-
bodyFormat: "www-form-urlencoded",
|
|
162
|
-
method: ["POST"],
|
|
163
|
-
}, async state => {
|
|
164
|
-
// zod: z.object({ test: z.string() }),
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
const test2 = test1.defineRoute({
|
|
170
|
-
path: /^test/,
|
|
171
|
-
bodyFormat: "string",
|
|
172
|
-
method: ["GET"],
|
|
173
|
-
zod: z.string(),
|
|
174
|
-
// handler: ,
|
|
175
|
-
}, async (state) => {
|
|
176
|
-
//@ts-expect-error because we didn't include "string"
|
|
177
|
-
const test: Exclude<BodyFormat, "ignore"> = state.bodyFormat;
|
|
178
|
-
// no error here if bodyFormat is correctly typed
|
|
179
|
-
const test2: "ignore" = state.bodyFormat
|
|
180
|
-
// @ts-expect-error because it should be "string"
|
|
181
|
-
state.isBodyFormat("buffer");
|
|
182
|
-
// this should never be an error unless something is really messed up
|
|
183
|
-
state.isBodyFormat("ignore");
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
const test3 = test2.defineRoute({
|
|
187
|
-
path: /^test/,
|
|
188
|
-
method: ["GET"],
|
|
189
|
-
// // @ts-expect-error because it's already been defined by the parent
|
|
190
|
-
// bodyFormat: "buffer",
|
|
191
|
-
zod: z.string(),
|
|
192
|
-
}, async (state) => {
|
|
193
|
-
//@ts-expect-error because we didn't include "string"
|
|
194
|
-
const test: Exclude<BodyFormat, "ignore"> = state.bodyFormat;
|
|
195
|
-
// no error here if bodyFormat is correctly typed
|
|
196
|
-
const test2: "ignore" = state.bodyFormat
|
|
197
|
-
// @ts-expect-error because it should be "string"
|
|
198
|
-
state.isBodyFormat("buffer");
|
|
199
|
-
// this should never be an error unless something is really messed up
|
|
200
|
-
state.isBodyFormat("ignore");
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
const test2post = test1.defineRoute({
|
|
204
|
-
path: /^test/,
|
|
205
|
-
bodyFormat: "string",
|
|
206
|
-
method: ["POST"],
|
|
207
|
-
zod: z.string(),
|
|
208
|
-
// handler: ,
|
|
209
|
-
}, async (state) => {
|
|
210
|
-
// @ts-expect-error because we didn't include "string"
|
|
211
|
-
const test: Exclude<BodyFormat, "string"> = state.bodyFormat;
|
|
212
|
-
// no error here if bodyFormat is correctly typed
|
|
213
|
-
const test2: "string" = state.bodyFormat
|
|
214
|
-
// @ts-expect-error because it should be "string"
|
|
215
|
-
state.isBodyFormat("buffer");
|
|
216
|
-
// this should never be an error unless something is really messed up
|
|
217
|
-
state.isBodyFormat("string");
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
const test3post = test2post.defineRoute({
|
|
221
|
-
path: /^test/,
|
|
222
|
-
method: ["POST"],
|
|
223
|
-
// // @ts-expect-error because it's already been defined by the parent
|
|
224
|
-
// bodyFormat: "buffer",
|
|
225
|
-
zod: z.string(),
|
|
226
|
-
}, async (state) => {
|
|
227
|
-
// @ts-expect-error because we didn't include "string"
|
|
228
|
-
const test: Exclude<BodyFormat, "string"> = state.bodyFormat;
|
|
229
|
-
// no error here if bodyFormat is correctly typed
|
|
230
|
-
const test2: "string" = state.bodyFormat
|
|
231
|
-
// @ts-expect-error because it should be "string"
|
|
232
|
-
state.isBodyFormat("buffer");
|
|
233
|
-
// this should never be an error unless something is really messed up
|
|
234
|
-
state.isBodyFormat("string");
|
|
235
|
-
})
|
|
236
|
-
}
|
|
237
|
-
|