pipeway-steps 0.1.0 → 1.0.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/dist/index.cjs CHANGED
@@ -4,6 +4,17 @@ var pipeway = require('pipeway');
4
4
 
5
5
  // src/index.ts
6
6
  var json = (data, status) => new Response(JSON.stringify(data), { status, headers: { "content-type": "application/json" } });
7
+ var toIssues = (issues) => issues.map((i) => ({
8
+ message: i.message,
9
+ ...i.path ? { path: i.path.map((p) => typeof p === "object" ? p.key : p) } : {}
10
+ }));
11
+ var validate = async (schema, value) => {
12
+ let result = schema["~standard"].validate(value);
13
+ if (result instanceof Promise) {
14
+ result = await result;
15
+ }
16
+ return result.issues ? { ok: false, issues: toIssues(result.issues) } : { ok: true, value: result.value };
17
+ };
7
18
  var body = (schema) => async (ctx) => {
8
19
  let raw;
9
20
  try {
@@ -11,13 +22,13 @@ var body = (schema) => async (ctx) => {
11
22
  } catch {
12
23
  return pipeway.fail(json({ error: "InvalidJson" }, 400));
13
24
  }
14
- const parsed = schema.safeParse(raw);
15
- return parsed.success ? pipeway.ok({ body: parsed.data }) : pipeway.fail(json({ error: "ValidationError", issues: parsed.error.issues }, 400));
25
+ const result = await validate(schema, raw);
26
+ return result.ok ? pipeway.ok({ body: result.value }) : pipeway.fail(json({ error: "ValidationError", issues: result.issues }, 400));
16
27
  };
17
- var query = (schema) => (ctx) => {
28
+ var query = (schema) => async (ctx) => {
18
29
  const obj = Object.fromEntries(new URL(ctx.req.url).searchParams);
19
- const parsed = schema.safeParse(obj);
20
- return parsed.success ? pipeway.ok({ query: parsed.data }) : pipeway.fail(json({ error: "ValidationError", issues: parsed.error.issues }, 400));
30
+ const result = await validate(schema, obj);
31
+ return result.ok ? pipeway.ok({ query: result.value }) : pipeway.fail(json({ error: "ValidationError", issues: result.issues }, 400));
21
32
  };
22
33
 
23
34
  exports.body = body;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["fail","ok"],"mappings":";;;;;AAMA,IAAM,OAAO,CAAC,IAAA,EAAe,MAAA,KAC3B,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG,EAAE,MAAA,EAAQ,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,IAAsB,CAAA;AAGzF,IAAM,IAAA,GAAO,CAAI,MAAA,KAA4D,OAAO,GAAA,KAAQ;AACjG,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAM,GAAA,CAAI,GAAA,CAAI,IAAA,EAAK;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAOA,aAAK,IAAA,CAAK,EAAE,OAAO,aAAA,EAAc,EAAG,GAAG,CAAC,CAAA;AAAA,EACjD;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA;AACnC,EAAA,OAAO,MAAA,CAAO,UAAUC,UAAA,CAAG,EAAE,MAAM,MAAA,CAAO,IAAA,EAAM,CAAA,GAAID,YAAA,CAAK,KAAK,EAAE,KAAA,EAAO,mBAAmB,MAAA,EAAQ,MAAA,CAAO,MAAM,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AAC/H;AAGO,IAAM,KAAA,GAAQ,CAAI,MAAA,KAA6D,CAAC,GAAA,KAAQ;AAC7F,EAAA,MAAM,GAAA,GAAM,OAAO,WAAA,CAAY,IAAI,IAAI,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,YAAY,CAAA;AAChE,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA;AACnC,EAAA,OAAO,MAAA,CAAO,UAAUC,UAAA,CAAG,EAAE,OAAO,MAAA,CAAO,IAAA,EAAM,CAAA,GAAID,YAAA,CAAK,KAAK,EAAE,KAAA,EAAO,mBAAmB,MAAA,EAAQ,MAAA,CAAO,MAAM,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AAChI","file":"index.cjs","sourcesContent":["import { ok, fail, type Step } from 'pipeway'\nimport type { ZodType } from 'zod'\n\n// Generic, app-agnostic steps. Auth / rate-limit are deliberately NOT bundled:\n// they depend on your stack. Compose your own the same way these are written.\n\nconst json = (data: unknown, status: number): Response =>\n new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' } })\n\n// Validates the JSON body against a Zod schema, adding a typed `body` to ctx.\nexport const body = <T>(schema: ZodType<T>): Step<{ req: Request }, { body: T }> => async (ctx) => {\n let raw: unknown\n try {\n raw = await ctx.req.json()\n } catch {\n return fail(json({ error: 'InvalidJson' }, 400))\n }\n const parsed = schema.safeParse(raw)\n return parsed.success ? ok({ body: parsed.data }) : fail(json({ error: 'ValidationError', issues: parsed.error.issues }, 400))\n}\n\n// Validates the URL search params against a Zod schema, adding typed `query`.\nexport const query = <T>(schema: ZodType<T>): Step<{ req: Request }, { query: T }> => (ctx) => {\n const obj = Object.fromEntries(new URL(ctx.req.url).searchParams)\n const parsed = schema.safeParse(obj)\n return parsed.success ? ok({ query: parsed.data }) : fail(json({ error: 'ValidationError', issues: parsed.error.issues }, 400))\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["fail","ok"],"mappings":";;;;;AAOA,IAAM,OAAO,CAAC,IAAA,EAAe,MAAA,KAC3B,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG,EAAE,MAAA,EAAQ,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,IAAsB,CAAA;AAIhG,IAAM,WAAW,CAAC,MAAA,KAChB,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,EACjB,SAAS,CAAA,CAAE,OAAA;AAAA,EACX,GAAI,CAAA,CAAE,IAAA,GAAO,EAAE,IAAA,EAAM,CAAA,CAAE,KAAK,GAAA,CAAI,CAAC,CAAA,KAAO,OAAO,MAAM,QAAA,GAAW,CAAA,CAAE,MAAM,CAAE,CAAA,KAAM;AAClF,CAAA,CAAE,CAAA;AAEJ,IAAM,QAAA,GAAW,OACf,MAAA,EACA,KAAA,KACoE;AACpE,EAAA,IAAI,MAAA,GAAS,MAAA,CAAO,WAAW,CAAA,CAAE,SAAS,KAAK,CAAA;AAC/C,EAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,IAAA,MAAA,GAAS,MAAM,MAAA;AAAA,EACjB;AACA,EAAA,OAAO,OAAO,MAAA,GAAS,EAAE,EAAA,EAAI,KAAA,EAAO,QAAQ,QAAA,CAAS,MAAA,CAAO,MAAM,CAAA,KAAM,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,EAAM;AAC1G,CAAA;AAGO,IAAM,IAAA,GAAO,CAAI,MAAA,KAA8E,OAAO,GAAA,KAAQ;AACnH,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAM,GAAA,CAAI,GAAA,CAAI,IAAA,EAAK;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAOA,aAAK,IAAA,CAAK,EAAE,OAAO,aAAA,EAAc,EAAG,GAAG,CAAC,CAAA;AAAA,EACjD;AACA,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,MAAA,EAAQ,GAAG,CAAA;AACzC,EAAA,OAAO,OAAO,EAAA,GAAKC,UAAA,CAAG,EAAE,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA,GAAID,aAAK,IAAA,CAAK,EAAE,OAAO,iBAAA,EAAmB,MAAA,EAAQ,OAAO,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AACrH;AAGO,IAAM,KAAA,GAAQ,CAAI,MAAA,KAA+E,OAAO,GAAA,KAAQ;AACrH,EAAA,MAAM,GAAA,GAAM,OAAO,WAAA,CAAY,IAAI,IAAI,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,YAAY,CAAA;AAChE,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,MAAA,EAAQ,GAAG,CAAA;AACzC,EAAA,OAAO,OAAO,EAAA,GAAKC,UAAA,CAAG,EAAE,KAAA,EAAO,MAAA,CAAO,OAAO,CAAA,GAAID,aAAK,IAAA,CAAK,EAAE,OAAO,iBAAA,EAAmB,MAAA,EAAQ,OAAO,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AACtH","file":"index.cjs","sourcesContent":["import { ok, fail, type Step } from 'pipeway'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\n// Validation steps built on the Standard Schema spec — they accept ANY validator\n// that implements it: Zod 3.24+, Valibot, ArkType, etc. No lock-in to one library.\n// Auth / rate-limit are deliberately NOT bundled: they depend on your stack.\n\nconst json = (data: unknown, status: number): Response =>\n new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' } })\n\ntype Issues = ReadonlyArray<{ message: string; path?: ReadonlyArray<PropertyKey> }>\n\nconst toIssues = (issues: ReadonlyArray<StandardSchemaV1.Issue>): Issues =>\n issues.map((i) => ({\n message: i.message,\n ...(i.path ? { path: i.path.map((p) => (typeof p === 'object' ? p.key : p)) } : {}),\n }))\n\nconst validate = async <T>(\n schema: StandardSchemaV1<unknown, T>,\n value: unknown,\n): Promise<{ ok: true; value: T } | { ok: false; issues: Issues }> => {\n let result = schema['~standard'].validate(value)\n if (result instanceof Promise) {\n result = await result\n }\n return result.issues ? { ok: false, issues: toIssues(result.issues) } : { ok: true, value: result.value }\n}\n\n// Reads the request's JSON body, validates it, and adds a typed `ctx.body`.\nexport const body = <T>(schema: StandardSchemaV1<unknown, T>): Step<{ req: Request }, { body: T }> => async (ctx) => {\n let raw: unknown\n try {\n raw = await ctx.req.json()\n } catch {\n return fail(json({ error: 'InvalidJson' }, 400))\n }\n const result = await validate(schema, raw)\n return result.ok ? ok({ body: result.value }) : fail(json({ error: 'ValidationError', issues: result.issues }, 400))\n}\n\n// Validates the URL search params (flat object) and adds a typed `ctx.query`.\nexport const query = <T>(schema: StandardSchemaV1<unknown, T>): Step<{ req: Request }, { query: T }> => async (ctx) => {\n const obj = Object.fromEntries(new URL(ctx.req.url).searchParams)\n const result = await validate(schema, obj)\n return result.ok ? ok({ query: result.value }) : fail(json({ error: 'ValidationError', issues: result.issues }, 400))\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Step } from 'pipeway';
2
- import { ZodType } from 'zod';
2
+ import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
 
4
- declare const body: <T>(schema: ZodType<T>) => Step<{
4
+ declare const body: <T>(schema: StandardSchemaV1<unknown, T>) => Step<{
5
5
  req: Request;
6
6
  }, {
7
7
  body: T;
8
8
  }>;
9
- declare const query: <T>(schema: ZodType<T>) => Step<{
9
+ declare const query: <T>(schema: StandardSchemaV1<unknown, T>) => Step<{
10
10
  req: Request;
11
11
  }, {
12
12
  query: T;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Step } from 'pipeway';
2
- import { ZodType } from 'zod';
2
+ import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
 
4
- declare const body: <T>(schema: ZodType<T>) => Step<{
4
+ declare const body: <T>(schema: StandardSchemaV1<unknown, T>) => Step<{
5
5
  req: Request;
6
6
  }, {
7
7
  body: T;
8
8
  }>;
9
- declare const query: <T>(schema: ZodType<T>) => Step<{
9
+ declare const query: <T>(schema: StandardSchemaV1<unknown, T>) => Step<{
10
10
  req: Request;
11
11
  }, {
12
12
  query: T;
package/dist/index.js CHANGED
@@ -2,6 +2,17 @@ import { fail, ok } from 'pipeway';
2
2
 
3
3
  // src/index.ts
4
4
  var json = (data, status) => new Response(JSON.stringify(data), { status, headers: { "content-type": "application/json" } });
5
+ var toIssues = (issues) => issues.map((i) => ({
6
+ message: i.message,
7
+ ...i.path ? { path: i.path.map((p) => typeof p === "object" ? p.key : p) } : {}
8
+ }));
9
+ var validate = async (schema, value) => {
10
+ let result = schema["~standard"].validate(value);
11
+ if (result instanceof Promise) {
12
+ result = await result;
13
+ }
14
+ return result.issues ? { ok: false, issues: toIssues(result.issues) } : { ok: true, value: result.value };
15
+ };
5
16
  var body = (schema) => async (ctx) => {
6
17
  let raw;
7
18
  try {
@@ -9,13 +20,13 @@ var body = (schema) => async (ctx) => {
9
20
  } catch {
10
21
  return fail(json({ error: "InvalidJson" }, 400));
11
22
  }
12
- const parsed = schema.safeParse(raw);
13
- return parsed.success ? ok({ body: parsed.data }) : fail(json({ error: "ValidationError", issues: parsed.error.issues }, 400));
23
+ const result = await validate(schema, raw);
24
+ return result.ok ? ok({ body: result.value }) : fail(json({ error: "ValidationError", issues: result.issues }, 400));
14
25
  };
15
- var query = (schema) => (ctx) => {
26
+ var query = (schema) => async (ctx) => {
16
27
  const obj = Object.fromEntries(new URL(ctx.req.url).searchParams);
17
- const parsed = schema.safeParse(obj);
18
- return parsed.success ? ok({ query: parsed.data }) : fail(json({ error: "ValidationError", issues: parsed.error.issues }, 400));
28
+ const result = await validate(schema, obj);
29
+ return result.ok ? ok({ query: result.value }) : fail(json({ error: "ValidationError", issues: result.issues }, 400));
19
30
  };
20
31
 
21
32
  export { body, query };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAMA,IAAM,OAAO,CAAC,IAAA,EAAe,MAAA,KAC3B,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG,EAAE,MAAA,EAAQ,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,IAAsB,CAAA;AAGzF,IAAM,IAAA,GAAO,CAAI,MAAA,KAA4D,OAAO,GAAA,KAAQ;AACjG,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAM,GAAA,CAAI,GAAA,CAAI,IAAA,EAAK;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAK,IAAA,CAAK,EAAE,OAAO,aAAA,EAAc,EAAG,GAAG,CAAC,CAAA;AAAA,EACjD;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA;AACnC,EAAA,OAAO,MAAA,CAAO,UAAU,EAAA,CAAG,EAAE,MAAM,MAAA,CAAO,IAAA,EAAM,CAAA,GAAI,IAAA,CAAK,KAAK,EAAE,KAAA,EAAO,mBAAmB,MAAA,EAAQ,MAAA,CAAO,MAAM,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AAC/H;AAGO,IAAM,KAAA,GAAQ,CAAI,MAAA,KAA6D,CAAC,GAAA,KAAQ;AAC7F,EAAA,MAAM,GAAA,GAAM,OAAO,WAAA,CAAY,IAAI,IAAI,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,YAAY,CAAA;AAChE,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA;AACnC,EAAA,OAAO,MAAA,CAAO,UAAU,EAAA,CAAG,EAAE,OAAO,MAAA,CAAO,IAAA,EAAM,CAAA,GAAI,IAAA,CAAK,KAAK,EAAE,KAAA,EAAO,mBAAmB,MAAA,EAAQ,MAAA,CAAO,MAAM,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AAChI","file":"index.js","sourcesContent":["import { ok, fail, type Step } from 'pipeway'\nimport type { ZodType } from 'zod'\n\n// Generic, app-agnostic steps. Auth / rate-limit are deliberately NOT bundled:\n// they depend on your stack. Compose your own the same way these are written.\n\nconst json = (data: unknown, status: number): Response =>\n new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' } })\n\n// Validates the JSON body against a Zod schema, adding a typed `body` to ctx.\nexport const body = <T>(schema: ZodType<T>): Step<{ req: Request }, { body: T }> => async (ctx) => {\n let raw: unknown\n try {\n raw = await ctx.req.json()\n } catch {\n return fail(json({ error: 'InvalidJson' }, 400))\n }\n const parsed = schema.safeParse(raw)\n return parsed.success ? ok({ body: parsed.data }) : fail(json({ error: 'ValidationError', issues: parsed.error.issues }, 400))\n}\n\n// Validates the URL search params against a Zod schema, adding typed `query`.\nexport const query = <T>(schema: ZodType<T>): Step<{ req: Request }, { query: T }> => (ctx) => {\n const obj = Object.fromEntries(new URL(ctx.req.url).searchParams)\n const parsed = schema.safeParse(obj)\n return parsed.success ? ok({ query: parsed.data }) : fail(json({ error: 'ValidationError', issues: parsed.error.issues }, 400))\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,IAAM,OAAO,CAAC,IAAA,EAAe,MAAA,KAC3B,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG,EAAE,MAAA,EAAQ,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,IAAsB,CAAA;AAIhG,IAAM,WAAW,CAAC,MAAA,KAChB,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,EACjB,SAAS,CAAA,CAAE,OAAA;AAAA,EACX,GAAI,CAAA,CAAE,IAAA,GAAO,EAAE,IAAA,EAAM,CAAA,CAAE,KAAK,GAAA,CAAI,CAAC,CAAA,KAAO,OAAO,MAAM,QAAA,GAAW,CAAA,CAAE,MAAM,CAAE,CAAA,KAAM;AAClF,CAAA,CAAE,CAAA;AAEJ,IAAM,QAAA,GAAW,OACf,MAAA,EACA,KAAA,KACoE;AACpE,EAAA,IAAI,MAAA,GAAS,MAAA,CAAO,WAAW,CAAA,CAAE,SAAS,KAAK,CAAA;AAC/C,EAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,IAAA,MAAA,GAAS,MAAM,MAAA;AAAA,EACjB;AACA,EAAA,OAAO,OAAO,MAAA,GAAS,EAAE,EAAA,EAAI,KAAA,EAAO,QAAQ,QAAA,CAAS,MAAA,CAAO,MAAM,CAAA,KAAM,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,EAAM;AAC1G,CAAA;AAGO,IAAM,IAAA,GAAO,CAAI,MAAA,KAA8E,OAAO,GAAA,KAAQ;AACnH,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAM,GAAA,CAAI,GAAA,CAAI,IAAA,EAAK;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAK,IAAA,CAAK,EAAE,OAAO,aAAA,EAAc,EAAG,GAAG,CAAC,CAAA;AAAA,EACjD;AACA,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,MAAA,EAAQ,GAAG,CAAA;AACzC,EAAA,OAAO,OAAO,EAAA,GAAK,EAAA,CAAG,EAAE,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA,GAAI,KAAK,IAAA,CAAK,EAAE,OAAO,iBAAA,EAAmB,MAAA,EAAQ,OAAO,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AACrH;AAGO,IAAM,KAAA,GAAQ,CAAI,MAAA,KAA+E,OAAO,GAAA,KAAQ;AACrH,EAAA,MAAM,GAAA,GAAM,OAAO,WAAA,CAAY,IAAI,IAAI,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,YAAY,CAAA;AAChE,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,MAAA,EAAQ,GAAG,CAAA;AACzC,EAAA,OAAO,OAAO,EAAA,GAAK,EAAA,CAAG,EAAE,KAAA,EAAO,MAAA,CAAO,OAAO,CAAA,GAAI,KAAK,IAAA,CAAK,EAAE,OAAO,iBAAA,EAAmB,MAAA,EAAQ,OAAO,MAAA,EAAO,EAAG,GAAG,CAAC,CAAA;AACtH","file":"index.js","sourcesContent":["import { ok, fail, type Step } from 'pipeway'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\n// Validation steps built on the Standard Schema spec — they accept ANY validator\n// that implements it: Zod 3.24+, Valibot, ArkType, etc. No lock-in to one library.\n// Auth / rate-limit are deliberately NOT bundled: they depend on your stack.\n\nconst json = (data: unknown, status: number): Response =>\n new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' } })\n\ntype Issues = ReadonlyArray<{ message: string; path?: ReadonlyArray<PropertyKey> }>\n\nconst toIssues = (issues: ReadonlyArray<StandardSchemaV1.Issue>): Issues =>\n issues.map((i) => ({\n message: i.message,\n ...(i.path ? { path: i.path.map((p) => (typeof p === 'object' ? p.key : p)) } : {}),\n }))\n\nconst validate = async <T>(\n schema: StandardSchemaV1<unknown, T>,\n value: unknown,\n): Promise<{ ok: true; value: T } | { ok: false; issues: Issues }> => {\n let result = schema['~standard'].validate(value)\n if (result instanceof Promise) {\n result = await result\n }\n return result.issues ? { ok: false, issues: toIssues(result.issues) } : { ok: true, value: result.value }\n}\n\n// Reads the request's JSON body, validates it, and adds a typed `ctx.body`.\nexport const body = <T>(schema: StandardSchemaV1<unknown, T>): Step<{ req: Request }, { body: T }> => async (ctx) => {\n let raw: unknown\n try {\n raw = await ctx.req.json()\n } catch {\n return fail(json({ error: 'InvalidJson' }, 400))\n }\n const result = await validate(schema, raw)\n return result.ok ? ok({ body: result.value }) : fail(json({ error: 'ValidationError', issues: result.issues }, 400))\n}\n\n// Validates the URL search params (flat object) and adds a typed `ctx.query`.\nexport const query = <T>(schema: StandardSchemaV1<unknown, T>): Step<{ req: Request }, { query: T }> => async (ctx) => {\n const obj = Object.fromEntries(new URL(ctx.req.url).searchParams)\n const result = await validate(schema, obj)\n return result.ok ? ok({ query: result.value }) : fail(json({ error: 'ValidationError', issues: result.issues }, 400))\n}\n"]}
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "pipeway-steps",
3
- "version": "0.1.0",
4
- "description": "Generic Zod validation steps for pipeway (body, query).",
3
+ "version": "1.0.1",
4
+ "description": "Generic validation steps for pipeway (body, query) — Standard Schema: works with Zod, Valibot, ArkType.",
5
5
  "keywords": [
6
6
  "pipeway",
7
+ "standard-schema",
7
8
  "zod",
9
+ "valibot",
10
+ "arktype",
8
11
  "validation",
9
12
  "middleware"
10
13
  ],
@@ -31,15 +34,15 @@
31
34
  "files": [
32
35
  "dist"
33
36
  ],
34
- "peerDependencies": {
35
- "zod": "^3.23.0",
36
- "pipeway": "0.1.0"
37
+ "dependencies": {
38
+ "@standard-schema/spec": "^1.0.0",
39
+ "pipeway": "^0.2.0"
37
40
  },
38
41
  "devDependencies": {
39
42
  "tsup": "^8.3.0",
40
43
  "typescript": "^5.6.0",
41
- "zod": "^3.23.0",
42
- "pipeway": "0.1.0"
44
+ "valibot": "^1.0.0",
45
+ "zod": "^3.24.0"
43
46
  },
44
47
  "publishConfig": {
45
48
  "access": "public"