@fuzdev/fuz_app 0.7.0 → 0.7.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/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +21 -7
- package/dist/testing/data_exposure.js +2 -3
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +2 -3
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +2 -3
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +30 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
|
|
@@ -34,18 +34,32 @@ export const schema_to_surface = (schema) => {
|
|
|
34
34
|
return null;
|
|
35
35
|
try {
|
|
36
36
|
const json_schema = z.toJSONSchema(schema);
|
|
37
|
-
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
39
|
-
if (typeof json_schema === 'object' && json_schema !== null && '$schema' in json_schema) {
|
|
40
|
-
const { $schema: _, ...rest } = json_schema;
|
|
41
|
-
return rest;
|
|
42
|
-
}
|
|
43
|
-
return json_schema;
|
|
37
|
+
return strip_json_schema_noise(json_schema);
|
|
44
38
|
}
|
|
45
39
|
catch {
|
|
46
40
|
return null;
|
|
47
41
|
}
|
|
48
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Recursively strip `$schema` and `default` from a JSON Schema value.
|
|
45
|
+
*
|
|
46
|
+
* `$schema` is noise for snapshots. `default` can be non-deterministic
|
|
47
|
+
* when schemas use function defaults (e.g. `z.string().default(() => new Date().toISOString())`),
|
|
48
|
+
* and defaults are runtime behavior, not attack surface structure.
|
|
49
|
+
*/
|
|
50
|
+
const strip_json_schema_noise = (value) => {
|
|
51
|
+
if (typeof value !== 'object' || value === null)
|
|
52
|
+
return value;
|
|
53
|
+
if (Array.isArray(value))
|
|
54
|
+
return value.map(strip_json_schema_noise);
|
|
55
|
+
const result = {};
|
|
56
|
+
for (const [k, v] of Object.entries(value)) {
|
|
57
|
+
if (k === '$schema' || k === 'default')
|
|
58
|
+
continue;
|
|
59
|
+
result[k] = strip_json_schema_noise(v);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
49
63
|
/**
|
|
50
64
|
* Check if a middleware path pattern applies to a route path.
|
|
51
65
|
*
|
|
@@ -135,9 +135,8 @@ const describe_data_exposure_runtime_tests = (options) => {
|
|
|
135
135
|
};
|
|
136
136
|
const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
|
|
137
137
|
for (const factory of factories) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return;
|
|
138
|
+
const describe_fn = factory.skip ? describe.skip : describe;
|
|
139
|
+
describe_fn(`data exposure — runtime (${factory.name})`, () => {
|
|
141
140
|
let test_app;
|
|
142
141
|
let authed_account;
|
|
143
142
|
let admin_account;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAc7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAO9D,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACpC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,kDAAkD;IAClD,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,+EAA+E;IAC/E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,8BAA8B,GAAI,SAAS,oBAAoB,KAAG,
|
|
1
|
+
{"version":3,"file":"round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAc7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAO9D,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACpC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,kDAAkD;IAClD,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,+EAA+E;IAC/E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,8BAA8B,GAAI,SAAS,oBAAoB,KAAG,IAqF9E,CAAC"}
|
|
@@ -38,9 +38,8 @@ export const describe_round_trip_validation = (options) => {
|
|
|
38
38
|
};
|
|
39
39
|
const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
|
|
40
40
|
for (const factory of factories) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return;
|
|
41
|
+
const describe_fn = factory.skip ? describe.skip : describe;
|
|
42
|
+
describe_fn(`round-trip validation (${factory.name})`, () => {
|
|
44
43
|
let test_app;
|
|
45
44
|
let authed_account;
|
|
46
45
|
let admin_account;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAK9D,OAAO,KAAK,EAAC,eAAe,EAAsB,MAAM,oBAAoB,CAAC;AAQ7E,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,gFAAgF;IAChF,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACtC,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,oDAAoD;IACpD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AA2BD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,
|
|
1
|
+
{"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAK9D,OAAO,KAAK,EAAC,eAAe,EAAsB,MAAM,oBAAoB,CAAC;AAQ7E,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,gFAAgF;IAChF,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACtC,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,oDAAoD;IACpD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AA2BD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,IAqIhF,CAAC"}
|
|
@@ -59,9 +59,8 @@ export const describe_rpc_round_trip_tests = (options) => {
|
|
|
59
59
|
};
|
|
60
60
|
const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
|
|
61
61
|
for (const factory of factories) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return;
|
|
62
|
+
const describe_fn = factory.skip ? describe.skip : describe;
|
|
63
|
+
describe_fn(`RPC round-trip validation (${factory.name})`, () => {
|
|
65
64
|
let test_app;
|
|
66
65
|
let authed_account;
|
|
67
66
|
let admin_account;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAShE,CAAC;
|
|
1
|
+
{"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAShE,CAAC;AA+BF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAkDnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAa9E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAkB5B,CAAC"}
|
|
@@ -43,7 +43,20 @@ const generate_valid_string = (field_schema) => {
|
|
|
43
43
|
// no constraints
|
|
44
44
|
}
|
|
45
45
|
const target = Math.max(min_length, Math.min(10, max_length));
|
|
46
|
-
|
|
46
|
+
const base = 'x'.repeat(target) || 'test_value';
|
|
47
|
+
// Validate against the full schema (including refinements/brands).
|
|
48
|
+
// If the base string fails, try common patterns before giving up.
|
|
49
|
+
if (field_schema.safeParse(base).success)
|
|
50
|
+
return base;
|
|
51
|
+
// Absolute path refinement (e.g. DiskfilePath)
|
|
52
|
+
const with_slash = '/' + base;
|
|
53
|
+
if (field_schema.safeParse(with_slash).success)
|
|
54
|
+
return with_slash;
|
|
55
|
+
// URL refinement
|
|
56
|
+
const as_url = 'https://example.com/' + base;
|
|
57
|
+
if (field_schema.safeParse(as_url).success)
|
|
58
|
+
return as_url;
|
|
59
|
+
return base; // fall through — generate_valid_body will report the failure
|
|
47
60
|
};
|
|
48
61
|
/** Generate a valid-ish value for a field based on its base type. */
|
|
49
62
|
export const generate_valid_value = (field, field_schema) => {
|
|
@@ -58,6 +71,8 @@ export const generate_valid_value = (field, field_schema) => {
|
|
|
58
71
|
return '00000000-0000-0000-0000-000000000000';
|
|
59
72
|
if (format === 'email')
|
|
60
73
|
return 'test@example.com';
|
|
74
|
+
if (format === 'date-time')
|
|
75
|
+
return '2020-01-01T00:00:00.000Z';
|
|
61
76
|
return generate_valid_string(field_schema);
|
|
62
77
|
case 'number':
|
|
63
78
|
case 'int':
|
|
@@ -66,8 +81,21 @@ export const generate_valid_value = (field, field_schema) => {
|
|
|
66
81
|
return true;
|
|
67
82
|
case 'array':
|
|
68
83
|
return [];
|
|
69
|
-
case 'object':
|
|
84
|
+
case 'object': {
|
|
85
|
+
// Recursively generate valid nested objects
|
|
86
|
+
const nested_schema = zod_unwrap_to_object(field_schema);
|
|
87
|
+
if (nested_schema) {
|
|
88
|
+
const nested_fields = zod_extract_fields(nested_schema);
|
|
89
|
+
const nested = {};
|
|
90
|
+
for (const nf of nested_fields) {
|
|
91
|
+
if (!nf.required && !nf.has_default)
|
|
92
|
+
continue;
|
|
93
|
+
nested[nf.name] = generate_valid_value(nf, nested_schema.shape[nf.name]);
|
|
94
|
+
}
|
|
95
|
+
return nested;
|
|
96
|
+
}
|
|
70
97
|
return {};
|
|
98
|
+
}
|
|
71
99
|
case 'null':
|
|
72
100
|
return null;
|
|
73
101
|
case 'enum': {
|