@kuratchi/js 0.0.18 → 0.0.20

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.
Files changed (40) hide show
  1. package/README.md +172 -9
  2. package/dist/compiler/client-module-pipeline.d.ts +8 -0
  3. package/dist/compiler/client-module-pipeline.js +181 -30
  4. package/dist/compiler/compiler-shared.d.ts +23 -0
  5. package/dist/compiler/config-reading.js +27 -1
  6. package/dist/compiler/convention-discovery.d.ts +2 -0
  7. package/dist/compiler/convention-discovery.js +16 -0
  8. package/dist/compiler/durable-object-pipeline.d.ts +1 -0
  9. package/dist/compiler/durable-object-pipeline.js +459 -119
  10. package/dist/compiler/import-linking.js +1 -1
  11. package/dist/compiler/index.js +41 -2
  12. package/dist/compiler/page-route-pipeline.js +31 -2
  13. package/dist/compiler/parser.d.ts +1 -0
  14. package/dist/compiler/parser.js +47 -4
  15. package/dist/compiler/root-layout-pipeline.js +26 -1
  16. package/dist/compiler/route-discovery.js +5 -5
  17. package/dist/compiler/route-pipeline.d.ts +2 -0
  18. package/dist/compiler/route-pipeline.js +28 -4
  19. package/dist/compiler/routes-module-feature-blocks.js +149 -17
  20. package/dist/compiler/routes-module-types.d.ts +1 -0
  21. package/dist/compiler/template.d.ts +4 -0
  22. package/dist/compiler/template.js +50 -18
  23. package/dist/compiler/worker-output-pipeline.js +2 -0
  24. package/dist/compiler/wrangler-sync.d.ts +3 -0
  25. package/dist/compiler/wrangler-sync.js +25 -11
  26. package/dist/create.js +6 -6
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +1 -0
  29. package/dist/runtime/context.d.ts +6 -0
  30. package/dist/runtime/context.js +22 -1
  31. package/dist/runtime/generated-worker.d.ts +1 -0
  32. package/dist/runtime/generated-worker.js +11 -7
  33. package/dist/runtime/index.d.ts +2 -0
  34. package/dist/runtime/index.js +1 -0
  35. package/dist/runtime/schema.d.ts +49 -0
  36. package/dist/runtime/schema.js +148 -0
  37. package/dist/runtime/types.d.ts +2 -0
  38. package/dist/runtime/validation.d.ts +26 -0
  39. package/dist/runtime/validation.js +147 -0
  40. package/package.json +5 -1
@@ -0,0 +1,147 @@
1
+ export class RpcValidationError extends Error {
2
+ isRpcValidationError = true;
3
+ status = 400;
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = 'RpcValidationError';
7
+ }
8
+ }
9
+ function formatPath(path) {
10
+ return path || 'value';
11
+ }
12
+ function describe(value) {
13
+ if (value === null)
14
+ return 'null';
15
+ if (Array.isArray(value))
16
+ return 'array';
17
+ return typeof value;
18
+ }
19
+ function fail(path, message) {
20
+ throw new RpcValidationError(`${formatPath(path)} ${message}`);
21
+ }
22
+ function createValidator(parse) {
23
+ return {
24
+ parse(input, path = 'value') {
25
+ return parse(input, path);
26
+ },
27
+ };
28
+ }
29
+ function isPlainObject(value) {
30
+ return !!value && typeof value === 'object' && !Array.isArray(value);
31
+ }
32
+ export const v = {
33
+ string() {
34
+ return createValidator((input, path) => {
35
+ if (typeof input !== 'string')
36
+ fail(path, `must be a string, got ${describe(input)}`);
37
+ return input;
38
+ });
39
+ },
40
+ number() {
41
+ return createValidator((input, path) => {
42
+ if (typeof input !== 'number' || Number.isNaN(input))
43
+ fail(path, `must be a number, got ${describe(input)}`);
44
+ return input;
45
+ });
46
+ },
47
+ boolean() {
48
+ return createValidator((input, path) => {
49
+ if (typeof input !== 'boolean')
50
+ fail(path, `must be a boolean, got ${describe(input)}`);
51
+ return input;
52
+ });
53
+ },
54
+ literal(expected) {
55
+ return createValidator((input, path) => {
56
+ if (input !== expected)
57
+ fail(path, `must be ${JSON.stringify(expected)}`);
58
+ return expected;
59
+ });
60
+ },
61
+ optional(inner) {
62
+ return createValidator((input, path) => {
63
+ if (typeof input === 'undefined')
64
+ return undefined;
65
+ return inner.parse(input, path);
66
+ });
67
+ },
68
+ nullable(inner) {
69
+ return createValidator((input, path) => {
70
+ if (input === null)
71
+ return null;
72
+ return inner.parse(input, path);
73
+ });
74
+ },
75
+ array(inner) {
76
+ return createValidator((input, path) => {
77
+ if (!Array.isArray(input))
78
+ fail(path, `must be an array, got ${describe(input)}`);
79
+ return input.map((value, index) => inner.parse(value, `${path}[${index}]`));
80
+ });
81
+ },
82
+ object(shape) {
83
+ return createValidator((input, path) => {
84
+ if (!isPlainObject(input))
85
+ fail(path, `must be an object, got ${describe(input)}`);
86
+ const out = {};
87
+ for (const key of Object.keys(shape)) {
88
+ out[key] = shape[key].parse(input[key], `${path}.${key}`);
89
+ }
90
+ return out;
91
+ });
92
+ },
93
+ tuple(items) {
94
+ return createValidator((input, path) => {
95
+ if (!Array.isArray(input))
96
+ fail(path, `must be an array, got ${describe(input)}`);
97
+ if (input.length !== items.length)
98
+ fail(path, `must contain ${items.length} item(s), got ${input.length}`);
99
+ const out = [];
100
+ for (let index = 0; index < items.length; index++) {
101
+ out.push(items[index].parse(input[index], `${path}[${index}]`));
102
+ }
103
+ return out;
104
+ });
105
+ },
106
+ union(items) {
107
+ return createValidator((input, path) => {
108
+ const messages = [];
109
+ for (const item of items) {
110
+ try {
111
+ return item.parse(input, path);
112
+ }
113
+ catch (error) {
114
+ if (error instanceof RpcValidationError)
115
+ messages.push(error.message);
116
+ }
117
+ }
118
+ fail(path, messages.length > 0 ? `did not match any allowed shape: ${messages.join('; ')}` : 'did not match any allowed shape');
119
+ });
120
+ },
121
+ };
122
+ export function rpc(validator, handler) {
123
+ const rpcHandler = handler;
124
+ rpcHandler.__kuratchiRpcValidator = validator;
125
+ return rpcHandler;
126
+ }
127
+ export function validateRpcArgs(fn, args) {
128
+ const validator = fn.__kuratchiRpcValidator;
129
+ if (!validator)
130
+ return args;
131
+ return validator.parse(args, 'args');
132
+ }
133
+ export function parseRpcArgsPayload(payload) {
134
+ if (!payload)
135
+ return [];
136
+ let parsed;
137
+ try {
138
+ parsed = JSON.parse(payload);
139
+ }
140
+ catch {
141
+ throw new RpcValidationError('args must be valid JSON');
142
+ }
143
+ if (!Array.isArray(parsed)) {
144
+ throw new RpcValidationError('args must be a JSON array');
145
+ }
146
+ return parsed;
147
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuratchi/js",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "A thin, Cloudflare Workers-native web framework with Svelte-inspired syntax",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,6 +38,10 @@
38
38
  "types": "./dist/runtime/do.d.ts",
39
39
  "import": "./dist/runtime/do.js"
40
40
  },
41
+ "./runtime/schema.js": {
42
+ "types": "./dist/runtime/schema.d.ts",
43
+ "import": "./dist/runtime/schema.js"
44
+ },
41
45
  "./runtime/generated-worker.js": {
42
46
  "types": "./dist/runtime/generated-worker.d.ts",
43
47
  "import": "./dist/runtime/generated-worker.js"