stitchkit 0.7.0 → 0.8.1
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 +20 -10
- package/dist/cli.js +3 -7
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +5 -2
- package/dist/contract/pagination.d.ts +11 -0
- package/dist/contract/pagination.d.ts.map +1 -1
- package/dist/{index-za2p453b.js → index-031q8xmx.js} +1 -1
- package/dist/{index-hty3443r.js → index-9zrq8x5z.js} +9 -6
- package/dist/{index-9bk6r5ff.js → index-eq29zkrx.js} +26 -1
- package/dist/{index-p8byjw3e.js → index-f39j6twc.js} +4 -8
- package/dist/index-jgpsd7dy.js +105 -0
- package/dist/{index-mwmpw6j1.js → index-p9m9c0jw.js} +2 -4
- package/dist/{index-8hsj2qm9.js → index-svvpy5bz.js} +18 -19
- package/dist/index-tm7dqzxc.js +20 -0
- package/dist/index.js +434 -14
- package/dist/node.js +4 -8
- package/dist/observability/index.js +4 -7
- package/dist/react.js +0 -2
- package/dist/server/index.js +89 -34
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/types.d.ts +10 -2
- package/dist/server/types.d.ts.map +1 -1
- package/dist/tools/mcp-app.d.ts.map +1 -1
- package/dist/tools.js +253 -21
- package/llms-full.txt +3025 -0
- package/llms.txt +23 -0
- package/package.json +8 -4
- package/dist/index-37x76zdn.js +0 -4
- package/dist/index-4843j09b.js +0 -37
- package/dist/index-48ffdxgk.js +0 -6
- package/dist/index-809wc1tt.js +0 -18
- package/dist/index-kdkvp26v.js +0 -380
- package/dist/index-kzfs85xp.js +0 -9
- package/dist/index-mahbaen9.js +0 -72
- package/dist/index-x3fcszf8.js +0 -8
package/README.md
CHANGED
|
@@ -352,10 +352,13 @@ A complete runnable app lives in [`packages/starter`](./packages/starter) — a
|
|
|
352
352
|
notes CRUD with a contract, a typed client, `react-query-kit` hooks and a
|
|
353
353
|
Socket.IO live-reload.
|
|
354
354
|
|
|
355
|
-
## Documentation
|
|
355
|
+
## Documentation — two roads
|
|
356
356
|
|
|
357
|
-
This README is the quick start.
|
|
358
|
-
|
|
357
|
+
This README is the quick start. Where you go next depends on what you're doing:
|
|
358
|
+
|
|
359
|
+
### 📦 Building an app **with** stitchkit
|
|
360
|
+
|
|
361
|
+
The full guide and API reference, in [`docs/`](./docs/README.md):
|
|
359
362
|
|
|
360
363
|
- **Guide** — [getting started](./docs/guide/getting-started.md) ·
|
|
361
364
|
[contracts](./docs/guide/contracts.md) ·
|
|
@@ -364,16 +367,23 @@ This README is the quick start. The full guide and API reference are in
|
|
|
364
367
|
[MCP & agents](./docs/guide/mcp-and-agents.md) ·
|
|
365
368
|
[realtime](./docs/guide/realtime.md) ·
|
|
366
369
|
[auth & errors](./docs/guide/auth-and-errors.md) ·
|
|
367
|
-
[testing & deployment](./docs/guide/testing-and-deployment.md)
|
|
370
|
+
[testing & deployment](./docs/guide/testing-and-deployment.md) ·
|
|
371
|
+
[multi-tenant](./docs/guide/multi-tenant.md) ·
|
|
372
|
+
[upgrading](./docs/guide/upgrading.md)
|
|
368
373
|
- **[API reference](./docs/api/reference.md)** — every export, by entrypoint.
|
|
369
|
-
- **
|
|
370
|
-
-
|
|
374
|
+
- **Coding agent?** The package ships **`llms.txt`** (a curated index) and
|
|
375
|
+
**`llms-full.txt`** (the whole guide inlined) — your agent reads them from
|
|
376
|
+
`node_modules/stitchkit/`. For Claude Code, the repo also provides a
|
|
377
|
+
[stitchkit skill](./skills/stitchkit) you can drop into `.claude/skills/`.
|
|
371
378
|
|
|
372
|
-
|
|
379
|
+
### 🔧 Developing stitchkit itself
|
|
373
380
|
|
|
374
|
-
|
|
375
|
-
changes
|
|
376
|
-
[
|
|
381
|
+
- **[AGENTS.md](./AGENTS.md)** — the development guide (setup, rules, hooks,
|
|
382
|
+
local-dev, breaking changes, release flow). One place for human and agent
|
|
383
|
+
contributors; [CONTRIBUTING.md](./CONTRIBUTING.md) points here.
|
|
384
|
+
- **[Architecture decisions](./docs/decisions/)** — the *why* behind the design.
|
|
385
|
+
- **[Roadmap](./ROADMAP.md)** · **[Changelog](./CHANGELOG.md)** ·
|
|
386
|
+
**[Backlog](./docs/backlog/)** · security via **[SECURITY.md](./SECURITY.md)**.
|
|
377
387
|
|
|
378
388
|
## License
|
|
379
389
|
|
package/dist/cli.js
CHANGED
|
@@ -4,14 +4,10 @@ import {
|
|
|
4
4
|
emitResult,
|
|
5
5
|
parseCliArgs,
|
|
6
6
|
pollUntilDone
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-f39j6twc.js";
|
|
8
8
|
import"./index-0ed3bx43.js";
|
|
9
|
-
import"./index-
|
|
10
|
-
import"./index-
|
|
11
|
-
import"./index-9bk6r5ff.js";
|
|
12
|
-
import"./index-kzfs85xp.js";
|
|
13
|
-
import"./index-809wc1tt.js";
|
|
14
|
-
import"./index-37x76zdn.js";
|
|
9
|
+
import"./index-jgpsd7dy.js";
|
|
10
|
+
import"./index-tm7dqzxc.js";
|
|
15
11
|
export {
|
|
16
12
|
pollUntilDone,
|
|
17
13
|
parseCliArgs,
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { ALL_TRANSPORTS, type ContractDef, type ContractMeta, defineContract, type EndpointDef, type EndpointFn, type EndpointToolAnnotations, type EndpointUiMeta, type HandlerContext, type HttpMethod, type RuntimeContext, type ScopedEndpointFn, type ScopedHttpClient, type Transport, type TransportSource, type TypedClient, type TypedHttpClient, } from './define';
|
|
2
2
|
export { AppError, appError, badRequest, conflict, type ErrorEnvelope, forbidden, isStitchErrorCode, notFound, rateLimited, STITCH_ERROR_STATUS, type StitchErrorCode, unauthorized, } from './errors';
|
|
3
|
-
export { type Paginated, paginatedSchema } from './pagination';
|
|
3
|
+
export { decodeCursor, encodeCursor, type Paginated, paginatedSchema, } from './pagination';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,KAAK,aAAa,EAClB,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,KAAK,aAAa,EAClB,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EACd,eAAe,GAChB,MAAM,cAAc,CAAC"}
|
package/dist/contract/index.js
CHANGED
|
@@ -5,15 +5,16 @@ import {
|
|
|
5
5
|
appError,
|
|
6
6
|
badRequest,
|
|
7
7
|
conflict,
|
|
8
|
+
decodeCursor,
|
|
8
9
|
defineContract,
|
|
10
|
+
encodeCursor,
|
|
9
11
|
forbidden,
|
|
10
12
|
isStitchErrorCode,
|
|
11
13
|
notFound,
|
|
12
14
|
paginatedSchema,
|
|
13
15
|
rateLimited,
|
|
14
16
|
unauthorized
|
|
15
|
-
} from "../index-
|
|
16
|
-
import"../index-37x76zdn.js";
|
|
17
|
+
} from "../index-eq29zkrx.js";
|
|
17
18
|
export {
|
|
18
19
|
unauthorized,
|
|
19
20
|
rateLimited,
|
|
@@ -21,7 +22,9 @@ export {
|
|
|
21
22
|
notFound,
|
|
22
23
|
isStitchErrorCode,
|
|
23
24
|
forbidden,
|
|
25
|
+
encodeCursor,
|
|
24
26
|
defineContract,
|
|
27
|
+
decodeCursor,
|
|
25
28
|
conflict,
|
|
26
29
|
badRequest,
|
|
27
30
|
appError,
|
|
@@ -16,4 +16,15 @@ export declare function paginatedSchema<T extends ZodType>(itemSchema: T): z.Zod
|
|
|
16
16
|
items: z.ZodArray<T>;
|
|
17
17
|
nextCursor: z.ZodNullable<z.ZodString>;
|
|
18
18
|
}, z.core.$strip>;
|
|
19
|
+
/**
|
|
20
|
+
* Encode a JSON-serializable value (e.g. a keyset `{ v, id }`) into an opaque,
|
|
21
|
+
* URL-safe cursor string for `nextCursor`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function encodeCursor(value: unknown): string;
|
|
24
|
+
/**
|
|
25
|
+
* Decode a cursor produced by {@link encodeCursor} and validate it against
|
|
26
|
+
* `schema`. Returns `null` for a missing, malformed or schema-invalid cursor —
|
|
27
|
+
* so a garbage cursor in a URL is treated as "no cursor" rather than throwing.
|
|
28
|
+
*/
|
|
29
|
+
export declare function decodeCursor<T>(cursor: string | null | undefined, schema: ZodType<T>): T | null;
|
|
19
30
|
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/contract/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,UAAU,EAAE,CAAC;;;kBAK/D"}
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/contract/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,UAAU,EAAE,CAAC;;;kBAK/D;AA4BD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GACjB,CAAC,GAAG,IAAI,CAQV"}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
forbidden,
|
|
3
3
|
unauthorized
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-jgpsd7dy.js";
|
|
5
5
|
import {
|
|
6
|
+
isRecord,
|
|
6
7
|
isUnsafeKey,
|
|
7
8
|
safeJsonParse
|
|
8
|
-
} from "./index-
|
|
9
|
-
import {
|
|
10
|
-
isRecord
|
|
11
|
-
} from "./index-809wc1tt.js";
|
|
9
|
+
} from "./index-tm7dqzxc.js";
|
|
12
10
|
|
|
13
11
|
// src/server/middleware/cookies.ts
|
|
14
12
|
function parseCookies(header) {
|
|
@@ -216,4 +214,9 @@ async function verifyPkce(verifier, challenge) {
|
|
|
216
214
|
return derived === challenge;
|
|
217
215
|
}
|
|
218
216
|
|
|
219
|
-
|
|
217
|
+
// src/internal/http-input.ts
|
|
218
|
+
function inputIsQuery(method) {
|
|
219
|
+
return method === "GET" || method === "DELETE";
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export { parseCookies, serializeCookie, defineCookie, verifyJwt, signJwt, extractToken, createAuthHook, createBearerResolver, deriveCodeChallenge, verifyPkce, inputIsQuery };
|
|
@@ -97,4 +97,29 @@ function paginatedSchema(itemSchema) {
|
|
|
97
97
|
nextCursor: z.string().nullable()
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
function toBase64Url(str) {
|
|
101
|
+
const bytes = new TextEncoder().encode(str);
|
|
102
|
+
let binary = "";
|
|
103
|
+
for (const byte of bytes)
|
|
104
|
+
binary += String.fromCharCode(byte);
|
|
105
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
106
|
+
}
|
|
107
|
+
function fromBase64Url(value) {
|
|
108
|
+
const base64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
109
|
+
const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
|
|
110
|
+
return new TextDecoder().decode(Uint8Array.from(atob(padded), (c) => c.charCodeAt(0)));
|
|
111
|
+
}
|
|
112
|
+
function encodeCursor(value) {
|
|
113
|
+
return toBase64Url(JSON.stringify(value));
|
|
114
|
+
}
|
|
115
|
+
function decodeCursor(cursor, schema) {
|
|
116
|
+
if (!cursor)
|
|
117
|
+
return null;
|
|
118
|
+
try {
|
|
119
|
+
const parsed = schema.safeParse(JSON.parse(fromBase64Url(cursor)));
|
|
120
|
+
return parsed.success ? parsed.data : null;
|
|
121
|
+
} catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export { ALL_TRANSPORTS, defineContract, AppError, notFound, badRequest, unauthorized, forbidden, conflict, rateLimited, STITCH_ERROR_STATUS, isStitchErrorCode, appError, paginatedSchema, encodeCursor, decodeCursor };
|
|
@@ -2,21 +2,17 @@ import {
|
|
|
2
2
|
jsonSchemaFields,
|
|
3
3
|
toJsonSchema
|
|
4
4
|
} from "./index-0ed3bx43.js";
|
|
5
|
-
import {
|
|
6
|
-
isWithinDir
|
|
7
|
-
} from "./index-x3fcszf8.js";
|
|
8
5
|
import {
|
|
9
6
|
formatZodError,
|
|
7
|
+
isWithinDir,
|
|
10
8
|
normalizeError,
|
|
11
9
|
validateHandlerOutput
|
|
12
|
-
} from "./index-
|
|
10
|
+
} from "./index-jgpsd7dy.js";
|
|
13
11
|
import {
|
|
12
|
+
isRecord,
|
|
14
13
|
isUnsafeKey,
|
|
15
14
|
safeJsonParse
|
|
16
|
-
} from "./index-
|
|
17
|
-
import {
|
|
18
|
-
isRecord
|
|
19
|
-
} from "./index-809wc1tt.js";
|
|
15
|
+
} from "./index-tm7dqzxc.js";
|
|
20
16
|
|
|
21
17
|
// src/tools/coerce.ts
|
|
22
18
|
import { z } from "zod";
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// src/contract/errors.ts
|
|
2
|
+
class AppError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
status;
|
|
5
|
+
details;
|
|
6
|
+
hint;
|
|
7
|
+
constructor(code, message, status = 500, details, hint) {
|
|
8
|
+
super(message ?? code);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.details = details;
|
|
12
|
+
this.hint = hint;
|
|
13
|
+
this.name = "AppError";
|
|
14
|
+
}
|
|
15
|
+
static is(err) {
|
|
16
|
+
return err instanceof AppError;
|
|
17
|
+
}
|
|
18
|
+
toJSON() {
|
|
19
|
+
return {
|
|
20
|
+
error: {
|
|
21
|
+
code: this.code,
|
|
22
|
+
message: this.message,
|
|
23
|
+
...this.details && { details: this.details },
|
|
24
|
+
...this.hint && { hint: this.hint }
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function notFound(message = "Not found") {
|
|
30
|
+
throw new AppError("NOT_FOUND", message, 404);
|
|
31
|
+
}
|
|
32
|
+
function badRequest(message, details) {
|
|
33
|
+
throw new AppError("BAD_REQUEST", message, 400, details);
|
|
34
|
+
}
|
|
35
|
+
function unauthorized(message = "Unauthorized") {
|
|
36
|
+
throw new AppError("UNAUTHORIZED", message, 401);
|
|
37
|
+
}
|
|
38
|
+
function forbidden(message = "Forbidden") {
|
|
39
|
+
throw new AppError("FORBIDDEN", message, 403);
|
|
40
|
+
}
|
|
41
|
+
function conflict(message = "Conflict", details) {
|
|
42
|
+
throw new AppError("CONFLICT", message, 409, details);
|
|
43
|
+
}
|
|
44
|
+
function rateLimited(message = "Too many requests") {
|
|
45
|
+
throw new AppError("RATE_LIMITED", message, 429);
|
|
46
|
+
}
|
|
47
|
+
var STITCH_ERROR_STATUS = {
|
|
48
|
+
BAD_REQUEST: 400,
|
|
49
|
+
UNAUTHORIZED: 401,
|
|
50
|
+
FORBIDDEN: 403,
|
|
51
|
+
NOT_FOUND: 404,
|
|
52
|
+
METHOD_NOT_ALLOWED: 405,
|
|
53
|
+
CONFLICT: 409,
|
|
54
|
+
RATE_LIMITED: 429,
|
|
55
|
+
VALIDATION_ERROR: 400,
|
|
56
|
+
INTERNAL_SERVER_ERROR: 500
|
|
57
|
+
};
|
|
58
|
+
function isStitchErrorCode(code) {
|
|
59
|
+
return code in STITCH_ERROR_STATUS;
|
|
60
|
+
}
|
|
61
|
+
function appError(code, message, details) {
|
|
62
|
+
throw new AppError(code, message, isStitchErrorCode(code) ? STITCH_ERROR_STATUS[code] : 500, details);
|
|
63
|
+
}
|
|
64
|
+
// src/contract/pagination.ts
|
|
65
|
+
import { z } from "zod";
|
|
66
|
+
// src/internal/errors.ts
|
|
67
|
+
import { z as z2 } from "zod";
|
|
68
|
+
function formatZodError(error) {
|
|
69
|
+
const issues = error.issues.slice(0, 5);
|
|
70
|
+
const lines = issues.map((issue) => {
|
|
71
|
+
const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
72
|
+
return `${path}: ${issue.message}`;
|
|
73
|
+
});
|
|
74
|
+
const suffix = error.issues.length > 5 ? `
|
|
75
|
+
...and ${error.issues.length - 5} more issues` : "";
|
|
76
|
+
return lines.join(`
|
|
77
|
+
`) + suffix;
|
|
78
|
+
}
|
|
79
|
+
function normalizeError(err) {
|
|
80
|
+
if (AppError.is(err))
|
|
81
|
+
return err;
|
|
82
|
+
if (err instanceof z2.ZodError) {
|
|
83
|
+
return new AppError("VALIDATION_ERROR", formatZodError(err), 400);
|
|
84
|
+
}
|
|
85
|
+
console.error("[stitchkit] unhandled error:", err);
|
|
86
|
+
return new AppError("INTERNAL_SERVER_ERROR", "Internal server error", 500);
|
|
87
|
+
}
|
|
88
|
+
function validateHandlerOutput(schema, data) {
|
|
89
|
+
const parsed = schema.safeParse(data);
|
|
90
|
+
if (parsed.success)
|
|
91
|
+
return { ok: true, data: parsed.data };
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
message: `Handler output does not match the contract: ${formatZodError(parsed.error)}`
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/internal/within-dir.ts
|
|
99
|
+
import { sep } from "node:path";
|
|
100
|
+
function isWithinDir(root, target) {
|
|
101
|
+
const base = root.endsWith(sep) ? root.slice(0, -sep.length) : root;
|
|
102
|
+
return target === root || target === base || target.startsWith(base + sep);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { AppError, notFound, badRequest, unauthorized, forbidden, conflict, rateLimited, STITCH_ERROR_STATUS, isStitchErrorCode, appError, formatZodError, normalizeError, validateHandlerOutput, isWithinDir };
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
AppError,
|
|
3
|
+
badRequest,
|
|
4
|
+
isWithinDir,
|
|
5
5
|
normalizeError,
|
|
6
6
|
validateHandlerOutput
|
|
7
|
-
} from "./index-
|
|
8
|
-
import {
|
|
9
|
-
AppError,
|
|
10
|
-
badRequest
|
|
11
|
-
} from "./index-9bk6r5ff.js";
|
|
7
|
+
} from "./index-jgpsd7dy.js";
|
|
12
8
|
import {
|
|
13
9
|
extractIp,
|
|
14
10
|
getClientInfo,
|
|
15
11
|
parseQueryParams,
|
|
16
12
|
resolveSocketIp,
|
|
17
13
|
resolveTraceId
|
|
18
|
-
} from "./index-
|
|
14
|
+
} from "./index-p9m9c0jw.js";
|
|
19
15
|
import {
|
|
16
|
+
__require,
|
|
20
17
|
isUnsafeKey,
|
|
21
|
-
safeJsonParse
|
|
22
|
-
} from "./index-kzfs85xp.js";
|
|
23
|
-
import {
|
|
18
|
+
safeJsonParse,
|
|
24
19
|
typedEntries
|
|
25
|
-
} from "./index-
|
|
26
|
-
import {
|
|
27
|
-
__require
|
|
28
|
-
} from "./index-37x76zdn.js";
|
|
20
|
+
} from "./index-tm7dqzxc.js";
|
|
29
21
|
|
|
30
22
|
// src/server/multipart.ts
|
|
31
23
|
var DEFAULT_MAX_UPLOAD_BYTES = 25 * 1024 * 1024;
|
|
@@ -266,9 +258,16 @@ function matchRawRoute(rawRoutes, httpMethod, pathname) {
|
|
|
266
258
|
if (route.method !== "ALL" && route.method !== httpMethod)
|
|
267
259
|
continue;
|
|
268
260
|
if (route.path.endsWith("/*")) {
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
261
|
+
const prefixSegs = route.path.slice(0, -2).split("/").filter(Boolean);
|
|
262
|
+
const pathSegs = pathname.split("/").filter(Boolean);
|
|
263
|
+
if (pathSegs.length < prefixSegs.length)
|
|
264
|
+
continue;
|
|
265
|
+
const params = matchSegments(prefixSegs, pathSegs.slice(0, prefixSegs.length));
|
|
266
|
+
if (params) {
|
|
267
|
+
return {
|
|
268
|
+
route,
|
|
269
|
+
params: { ...params, "*": pathSegs.slice(prefixSegs.length).join("/") }
|
|
270
|
+
};
|
|
272
271
|
}
|
|
273
272
|
continue;
|
|
274
273
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// src/internal/safe-json.ts
|
|
5
|
+
function isUnsafeKey(key) {
|
|
6
|
+
return key === "__proto__";
|
|
7
|
+
}
|
|
8
|
+
function safeJsonParse(text) {
|
|
9
|
+
return JSON.parse(text, (key, value) => isUnsafeKey(key) ? undefined : value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// src/internal/typed.ts
|
|
13
|
+
function typedEntries(value) {
|
|
14
|
+
return Object.entries(value);
|
|
15
|
+
}
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { __require, isUnsafeKey, safeJsonParse, typedEntries, isRecord };
|