@nullix/zod-mongoose-studio 3.3.0 → 3.3.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/.output/nitro.json +1 -1
- package/.output/public/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2 +0 -0
- package/.output/public/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2 +0 -0
- package/.output/public/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2 +0 -0
- package/.output/public/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2 +0 -0
- package/.output/public/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2 +0 -0
- package/.output/public/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2 +0 -0
- package/.output/public/_nuxt/{qQyvCkbV.js → 5Tu2WUJz.js} +1 -1
- package/.output/public/_nuxt/B0N6xv5E.js +1 -0
- package/.output/public/_nuxt/{DjPT-NCE.js → B0cUlOSM.js} +1 -1
- package/.output/public/_nuxt/B9paGgN0.js +33 -0
- package/.output/public/_nuxt/{IxYCG8hB.js → BCIlnd0g.js} +1 -1
- package/.output/public/_nuxt/{ikxafTHA.js → BNDnV2op.js} +180 -184
- package/.output/public/_nuxt/{Ce-T_1aD.js → BO4hqv6q.js} +1 -1
- package/.output/public/_nuxt/{Bd32GOUy.js → BOsJJ_ZU.js} +1 -1
- package/.output/public/_nuxt/{BzhSDy30.js → C2BHp-MG.js} +1 -1
- package/.output/public/_nuxt/{Cs8GXJCB.js → CKULsFUz.js} +1 -1
- package/.output/public/_nuxt/CMH9iX_E.js +6 -0
- package/.output/public/_nuxt/{tzj4nvDE.js → CzbCpNnc.js} +2 -2
- package/.output/public/_nuxt/{CC3n3Aga.js → D87QMS6j.js} +1 -1
- package/.output/public/_nuxt/DA0pQuyP.js +27 -0
- package/.output/public/_nuxt/{B7P0wQ35.js → DcJ7oPvZ.js} +1 -1
- package/.output/public/_nuxt/{Ick_23I4.js → Dce9SnGa.js} +1 -1
- package/.output/public/_nuxt/{CAd-qHfI.js → DpKrXpkK.js} +1 -1
- package/.output/public/_nuxt/DsnIpnT9.js +1 -0
- package/.output/public/_nuxt/{CNZorjDf.js → I3Ucam2s.js} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/51f1351c-0667-4235-9ddc-16582a51ce03.json +1 -0
- package/.output/public/_nuxt/{entry.J_CbC0oY.css → entry.B-vs1tRH.css} +1 -1
- package/.output/public/_nuxt/error-404.CTSXlFYa.css +1 -0
- package/.output/public/_nuxt/error-500.DqEfQnVZ.css +1 -0
- package/.output/public/_nuxt/{nDZOJ7rN.js → o-NCh2rp.js} +2 -2
- package/.output/public/_nuxt/{qwxNOyg7.js → sKEJiAHO.js} +1 -1
- package/.output/public/_nuxt/{81vqh61j.js → tqQNlhT9.js} +1 -1
- package/.output/public/_nuxt/ypRHVLFO.js +1 -0
- package/.output/server/chunks/_/error-500.mjs.map +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/{error-404-BN-7rNE4.mjs → error-404-KRkA0DPI.mjs} +10 -4
- package/.output/server/chunks/build/error-404-KRkA0DPI.mjs.map +1 -0
- package/.output/server/chunks/build/error-404-styles.I0NYw-Bn.mjs +8 -0
- package/.output/server/chunks/build/error-404-styles.I0NYw-Bn.mjs.map +1 -0
- package/.output/server/chunks/build/{error-500-DhIQ-2yt.mjs → error-500-DIIFf55p.mjs} +10 -4
- package/.output/server/chunks/build/error-500-DIIFf55p.mjs.map +1 -0
- package/.output/server/chunks/build/error-500-styles.D1cs9hQy.mjs +8 -0
- package/.output/server/chunks/build/error-500-styles.D1cs9hQy.mjs.map +1 -0
- package/.output/server/chunks/build/index-CB1N4gax.mjs +557 -0
- package/.output/server/chunks/build/index-CB1N4gax.mjs.map +1 -0
- package/.output/server/chunks/build/server.mjs +326 -248
- package/.output/server/chunks/build/server.mjs.map +1 -1
- package/.output/server/chunks/build/styles.mjs +4 -4
- package/.output/server/chunks/nitro/nitro.mjs +2328 -861
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/api/editor-types.get.mjs +44 -0
- package/.output/server/chunks/routes/api/editor-types.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/parse.post.mjs +26 -1448
- package/.output/server/chunks/routes/api/parse.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/resolve.get.mjs +6 -0
- package/.output/server/chunks/routes/api/resolve.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/studio/run.post.mjs +35 -0
- package/.output/server/chunks/routes/api/studio/run.post.mjs.map +1 -0
- package/.output/server/chunks/routes/renderer.mjs +1 -1
- package/.output/server/chunks/routes/renderer.mjs.map +1 -1
- package/.output/server/index.mjs +7 -1
- package/.output/server/index.mjs.map +1 -1
- package/.output/server/node_modules/acorn/dist/acorn.mjs +6266 -0
- package/.output/server/node_modules/acorn/package.json +50 -0
- package/.output/server/node_modules/ip-address/dist/common.js +112 -4
- package/.output/server/node_modules/ip-address/dist/ipv4.js +322 -87
- package/.output/server/node_modules/ip-address/dist/ipv6.js +654 -199
- package/.output/server/node_modules/ip-address/dist/v4/constants.js +45 -2
- package/.output/server/node_modules/ip-address/dist/v6/constants.js +55 -3
- package/.output/server/node_modules/ip-address/dist/v6/helpers.js +12 -3
- package/.output/server/node_modules/ip-address/package.json +49 -37
- package/.output/server/node_modules/ufo/dist/index.mjs +2 -2
- package/.output/server/node_modules/ufo/package.json +9 -9
- package/.output/server/package.json +4 -3
- package/README.md +62 -19
- package/app/assets/css/main.css +1 -0
- package/app/assets/css/studio.css +131 -0
- package/app/components/StudioConversion.vue +41 -0
- package/app/components/StudioDataPanel.vue +21 -0
- package/app/components/StudioEditor.vue +78 -102
- package/app/components/StudioExpandButton.vue +11 -0
- package/app/components/StudioOutput.vue +7 -1
- package/app/components/StudioSourcePanel.vue +16 -0
- package/app/components/StudioValidation.vue +47 -0
- package/app/components/ZodMongooseStudio.vue +216 -198
- package/app/composables/useStudioRunner.ts +142 -0
- package/app/pages/index.vue +1 -1
- package/app/plugins/monaco.client.ts +2 -0
- package/bin/index.mjs +5 -0
- package/nuxt.config.ts +4 -3
- package/package.json +4 -2
- package/server/api/editor-types.get.ts +28 -0
- package/server/api/parse.post.ts +17 -175
- package/server/api/studio/run.post.ts +17 -0
- package/server/middleware/security.ts +29 -7
- package/server/utils/example-data.ts +80 -0
- package/server/utils/parse-request.ts +28 -0
- package/server/utils/runner-client.ts +40 -0
- package/server/utils/studio-execution.ts +176 -0
- package/.output/public/_nuxt/BD40YYqZ.js +0 -33
- package/.output/public/_nuxt/BlQmLjV4.js +0 -1
- package/.output/public/_nuxt/CJ4Cv9fY.js +0 -61
- package/.output/public/_nuxt/builds/meta/495a8ebb-444d-4414-9b98-c181aa84d817.json +0 -1
- package/.output/public/_nuxt/error-404.64pZEiDn.css +0 -1
- package/.output/public/_nuxt/error-500.DHOpI0Ir.css +0 -1
- package/.output/public/_nuxt/rH_O4qXT.js +0 -1
- package/.output/server/chunks/build/error-404-BN-7rNE4.mjs.map +0 -1
- package/.output/server/chunks/build/error-404-styles.Byx46oLR.mjs +0 -8
- package/.output/server/chunks/build/error-404-styles.Byx46oLR.mjs.map +0 -1
- package/.output/server/chunks/build/error-500-DhIQ-2yt.mjs.map +0 -1
- package/.output/server/chunks/build/error-500-styles.BL3UT0Wa.mjs +0 -8
- package/.output/server/chunks/build/error-500-styles.BL3UT0Wa.mjs.map +0 -1
- package/.output/server/chunks/build/index-B4T6zHp0.mjs +0 -1904
- package/.output/server/chunks/build/index-B4T6zHp0.mjs.map +0 -1
- package/.output/server/node_modules/zod/index.js +0 -4
- /package/.output/public/_nuxt/{editor.CdBKkuhR.css → monaco.CdBKkuhR.css} +0 -0
|
@@ -1,8 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;
|
|
3
|
+
exports.SPECIAL_PURPOSE = exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;
|
|
4
4
|
exports.BITS = 32;
|
|
5
5
|
exports.GROUPS = 4;
|
|
6
|
-
|
|
6
|
+
// Each octet is 0-255 written without a leading zero. A leading zero is
|
|
7
|
+
// octal to the WHATWG URL parser, inet_aton, and getaddrinfo, but decimal to
|
|
8
|
+
// parseInt(part, 10), so accepting the notation would make this library
|
|
9
|
+
// disagree with the network stack about which host a string names.
|
|
10
|
+
exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/g;
|
|
7
11
|
exports.RE_SUBNET_STRING = /\/\d{1,2}$/;
|
|
12
|
+
/**
|
|
13
|
+
* The IANA IPv4 Special-Purpose Address Registry
|
|
14
|
+
* (https://www.iana.org/assignments/iana-ipv4-special-registry/), one entry
|
|
15
|
+
* per block: `[cidr, name, globallyReachable]`. A `null` reachability means
|
|
16
|
+
* the registry leaves the column blank and the block inherits the answer of
|
|
17
|
+
* the block containing it (or is global when nothing contains it).
|
|
18
|
+
*
|
|
19
|
+
* `Address4.isGlobal()` answers from the most specific entry containing the
|
|
20
|
+
* address. `test/data/iana-corpus.json` is generated from the registry's CSV
|
|
21
|
+
* and pins this table to it.
|
|
22
|
+
*/
|
|
23
|
+
exports.SPECIAL_PURPOSE = [
|
|
24
|
+
['0.0.0.0/8', 'This network', false],
|
|
25
|
+
['0.0.0.0/32', 'This host on this network', false],
|
|
26
|
+
['10.0.0.0/8', 'Private-Use', false],
|
|
27
|
+
['100.64.0.0/10', 'Shared Address Space', false],
|
|
28
|
+
['127.0.0.0/8', 'Loopback', false],
|
|
29
|
+
['169.254.0.0/16', 'Link Local', false],
|
|
30
|
+
['172.16.0.0/12', 'Private-Use', false],
|
|
31
|
+
['192.0.0.0/24', 'IETF Protocol Assignments', false],
|
|
32
|
+
['192.0.0.0/29', 'IPv4 Service Continuity Prefix', false],
|
|
33
|
+
['192.0.0.8/32', 'IPv4 dummy address', false],
|
|
34
|
+
['192.0.0.9/32', 'Port Control Protocol Anycast', true],
|
|
35
|
+
['192.0.0.10/32', 'Traversal Using Relays around NAT Anycast', true],
|
|
36
|
+
['192.0.0.170/32', 'NAT64/DNS64 Discovery', false],
|
|
37
|
+
['192.0.0.171/32', 'NAT64/DNS64 Discovery', false],
|
|
38
|
+
['192.0.2.0/24', 'Documentation (TEST-NET-1)', false],
|
|
39
|
+
['192.31.196.0/24', 'AS112-v4', true],
|
|
40
|
+
['192.52.193.0/24', 'AMT', true],
|
|
41
|
+
['192.88.99.0/24', 'Deprecated (6to4 Relay Anycast)', null],
|
|
42
|
+
['192.88.99.2/32', '6a44-relay anycast address', false],
|
|
43
|
+
['192.168.0.0/16', 'Private-Use', false],
|
|
44
|
+
['192.175.48.0/24', 'Direct Delegation AS112 Service', true],
|
|
45
|
+
['198.18.0.0/15', 'Benchmarking', false],
|
|
46
|
+
['198.51.100.0/24', 'Documentation (TEST-NET-2)', false],
|
|
47
|
+
['203.0.113.0/24', 'Documentation (TEST-NET-3)', false],
|
|
48
|
+
['240.0.0.0/4', 'Reserved', false],
|
|
49
|
+
['255.255.255.255/32', 'Limited Broadcast', false],
|
|
50
|
+
];
|
|
8
51
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;
|
|
3
|
+
exports.SPECIAL_PURPOSE = exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;
|
|
4
4
|
exports.BITS = 128;
|
|
5
5
|
exports.GROUPS = 8;
|
|
6
6
|
/**
|
|
@@ -44,8 +44,20 @@ exports.TYPES = {
|
|
|
44
44
|
'ff05::1:3/128': 'Multicast (All DHCP servers in this site)',
|
|
45
45
|
'::/128': 'Unspecified',
|
|
46
46
|
'::1/128': 'Loopback',
|
|
47
|
+
'::ffff:0:0/96': 'IPv4-mapped',
|
|
47
48
|
'ff00::/8': 'Multicast',
|
|
48
49
|
'fe80::/10': 'Link-local unicast',
|
|
50
|
+
'fc00::/7': 'Unique local',
|
|
51
|
+
'2001::/32': 'Teredo',
|
|
52
|
+
'2001:2::/48': 'Benchmarking',
|
|
53
|
+
'2002::/16': '6to4',
|
|
54
|
+
'2001:db8::/32': 'Documentation',
|
|
55
|
+
'3fff::/20': 'Documentation',
|
|
56
|
+
'100::/64': 'Discard-only',
|
|
57
|
+
'fec0::/10': 'Site-local unicast (deprecated)',
|
|
58
|
+
'::/96': 'IPv4-compatible (deprecated)',
|
|
59
|
+
'64:ff9b::/96': 'NAT64 (well-known)',
|
|
60
|
+
'64:ff9b:1::/48': 'NAT64 (local-use)',
|
|
49
61
|
};
|
|
50
62
|
/**
|
|
51
63
|
* A regular expression that matches bad characters in an IPv6 address
|
|
@@ -71,6 +83,46 @@ exports.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/;
|
|
|
71
83
|
* @static
|
|
72
84
|
*/
|
|
73
85
|
exports.RE_ZONE_STRING = /%.*$/;
|
|
74
|
-
exports.RE_URL =
|
|
75
|
-
exports.RE_URL_WITH_PORT =
|
|
86
|
+
exports.RE_URL = /^(?:\[([0-9a-f:.]+)\]|([0-9a-f:.]+))(?:[/?#].*)?$/i;
|
|
87
|
+
exports.RE_URL_WITH_PORT = /^\[([0-9a-f:.]+)\]:([0-9]{1,5})(?:[/?#].*)?$/i;
|
|
88
|
+
/**
|
|
89
|
+
* The IANA IPv6 Special-Purpose Address Registry
|
|
90
|
+
* (https://www.iana.org/assignments/iana-ipv6-special-registry/), one entry
|
|
91
|
+
* per block: `[cidr, name, globallyReachable]`. A `null` reachability means
|
|
92
|
+
* the registry says N/A or leaves the column blank; N/A blocks (Teredo, 6to4)
|
|
93
|
+
* are treated as not globally reachable, since a packet to one needs a relay,
|
|
94
|
+
* and blank blocks inherit the answer of the block containing them.
|
|
95
|
+
*
|
|
96
|
+
* `Address6.isGlobal()` answers from the most specific entry containing the
|
|
97
|
+
* address, after delegating IPv4-mapped and NAT64 well-known addresses to the
|
|
98
|
+
* embedded IPv4 address. `test/data/iana-corpus.json` is generated from the
|
|
99
|
+
* registry's CSV and pins this table to it.
|
|
100
|
+
*/
|
|
101
|
+
exports.SPECIAL_PURPOSE = [
|
|
102
|
+
['::1/128', 'Loopback Address', false],
|
|
103
|
+
['::/128', 'Unspecified Address', false],
|
|
104
|
+
['::ffff:0:0/96', 'IPv4-mapped Address', false],
|
|
105
|
+
['64:ff9b::/96', 'IPv4-IPv6 Translat.', true],
|
|
106
|
+
['64:ff9b:1::/48', 'IPv4-IPv6 Translat.', false],
|
|
107
|
+
['100::/64', 'Discard-Only Address Block', false],
|
|
108
|
+
['100:0:0:1::/64', 'Dummy IPv6 Prefix', false],
|
|
109
|
+
['2001::/23', 'IETF Protocol Assignments', false],
|
|
110
|
+
['2001::/32', 'TEREDO', false],
|
|
111
|
+
['2001:1::1/128', 'Port Control Protocol Anycast', true],
|
|
112
|
+
['2001:1::2/128', 'Traversal Using Relays around NAT Anycast', true],
|
|
113
|
+
['2001:1::3/128', 'DNS-SD Service Registration Protocol Anycast', true],
|
|
114
|
+
['2001:2::/48', 'Benchmarking', false],
|
|
115
|
+
['2001:3::/32', 'AMT', true],
|
|
116
|
+
['2001:4:112::/48', 'AS112-v6', true],
|
|
117
|
+
['2001:10::/28', 'Deprecated (previously ORCHID)', null],
|
|
118
|
+
['2001:20::/28', 'ORCHIDv2', true],
|
|
119
|
+
['2001:30::/28', 'Drone Remote ID Protocol Entity Tags (DETs) Prefix', true],
|
|
120
|
+
['2001:db8::/32', 'Documentation', false],
|
|
121
|
+
['2002::/16', '6to4', false],
|
|
122
|
+
['2620:4f:8000::/48', 'Direct Delegation AS112 Service', true],
|
|
123
|
+
['3fff::/20', 'Documentation', false],
|
|
124
|
+
['5f00::/16', 'Segment Routing (SRv6) SIDs', false],
|
|
125
|
+
['fc00::/7', 'Unique-Local', false],
|
|
126
|
+
['fe80::/10', 'Link-Local Unicast', false],
|
|
127
|
+
];
|
|
76
128
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeHtml = escapeHtml;
|
|
3
4
|
exports.spanAllZeroes = spanAllZeroes;
|
|
4
5
|
exports.spanAll = spanAll;
|
|
5
6
|
exports.spanLeadingZeroes = spanLeadingZeroes;
|
|
6
7
|
exports.simpleGroup = simpleGroup;
|
|
8
|
+
function escapeHtml(s) {
|
|
9
|
+
return s
|
|
10
|
+
.replace(/&/g, '&')
|
|
11
|
+
.replace(/</g, '<')
|
|
12
|
+
.replace(/>/g, '>')
|
|
13
|
+
.replace(/"/g, '"')
|
|
14
|
+
.replace(/'/g, ''');
|
|
15
|
+
}
|
|
7
16
|
/**
|
|
8
17
|
* @returns {String} the string with all zeroes contained in a <span>
|
|
9
18
|
*/
|
|
10
19
|
function spanAllZeroes(s) {
|
|
11
|
-
return s.replace(/(0+)/g, '<span class="zero">$1</span>');
|
|
20
|
+
return escapeHtml(s).replace(/(0+)/g, '<span class="zero">$1</span>');
|
|
12
21
|
}
|
|
13
22
|
/**
|
|
14
23
|
* @returns {String} the string with each character contained in a <span>
|
|
@@ -16,11 +25,11 @@ function spanAllZeroes(s) {
|
|
|
16
25
|
function spanAll(s, offset = 0) {
|
|
17
26
|
const letters = s.split('');
|
|
18
27
|
return letters
|
|
19
|
-
.map((n, i) => `<span class="digit value-${n} position-${i + offset}">${spanAllZeroes(n)}</span>`)
|
|
28
|
+
.map((n, i) => `<span class="digit value-${escapeHtml(n)} position-${i + offset}">${spanAllZeroes(n)}</span>`)
|
|
20
29
|
.join('');
|
|
21
30
|
}
|
|
22
31
|
function spanLeadingZeroesSimple(group) {
|
|
23
|
-
return group.replace(/^(0+)/, '<span class="zero">$1</span>');
|
|
32
|
+
return escapeHtml(group).replace(/^(0+)/, '<span class="zero">$1</span>');
|
|
24
33
|
}
|
|
25
34
|
/**
|
|
26
35
|
* @returns {String} the string with leading zeroes contained in a <span>
|
|
@@ -2,77 +2,89 @@
|
|
|
2
2
|
"name": "ip-address",
|
|
3
3
|
"description": "A library for parsing IPv4 and IPv6 IP addresses in node and the browser.",
|
|
4
4
|
"keywords": [
|
|
5
|
-
"
|
|
5
|
+
"ip",
|
|
6
6
|
"ipv4",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
7
|
+
"ipv6",
|
|
8
|
+
"address",
|
|
9
|
+
"cidr",
|
|
10
|
+
"subnet",
|
|
11
|
+
"netmask",
|
|
12
|
+
"validate",
|
|
13
|
+
"validation",
|
|
14
|
+
"parse",
|
|
15
|
+
"arpa",
|
|
16
|
+
"bigint",
|
|
17
|
+
"browser"
|
|
9
18
|
],
|
|
10
|
-
"version": "10.
|
|
19
|
+
"version": "10.7.2",
|
|
11
20
|
"author": "Beau Gunderson <beau@beaugunderson.com> (https://beaugunderson.com/)",
|
|
12
21
|
"license": "MIT",
|
|
13
22
|
"main": "dist/ip-address.js",
|
|
14
23
|
"types": "dist/ip-address.d.ts",
|
|
15
24
|
"scripts": {
|
|
16
|
-
"docs": "
|
|
25
|
+
"docs": "tsx scripts/build-readme.ts",
|
|
17
26
|
"build": "rm -rf dist; mkdir dist; tsc",
|
|
18
|
-
"prepack": "npm run build",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
27
|
+
"prepack": "npm run docs && npm run build",
|
|
28
|
+
"prepare": "git config core.hooksPath hooks || true",
|
|
29
|
+
"lint": "prettier --check . && eslint . --ext .ts,.js --max-warnings 0",
|
|
30
|
+
"lint:fix": "prettier --write . && eslint . --ext .ts,.js --max-warnings 0 --fix",
|
|
31
|
+
"test-ci": "c8 --experimental-monocart mocha",
|
|
21
32
|
"test": "mocha",
|
|
22
33
|
"watch": "mocha --watch"
|
|
23
34
|
},
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
35
|
+
"c8": {
|
|
36
|
+
"include": [
|
|
37
|
+
"src/**/*.ts"
|
|
27
38
|
],
|
|
28
39
|
"exclude": [
|
|
29
40
|
"**/*.d.ts",
|
|
30
|
-
".
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"test/",
|
|
34
|
-
"tmp/"
|
|
41
|
+
"src/ip-address.ts",
|
|
42
|
+
"src/v4/constants.ts",
|
|
43
|
+
"src/v6/constants.ts"
|
|
35
44
|
],
|
|
36
45
|
"reporter": [
|
|
37
46
|
"html",
|
|
38
47
|
"lcov",
|
|
39
48
|
"text"
|
|
40
|
-
]
|
|
41
|
-
"all": true
|
|
49
|
+
]
|
|
42
50
|
},
|
|
43
51
|
"engines": {
|
|
44
52
|
"node": ">= 12"
|
|
45
53
|
},
|
|
54
|
+
"sideEffects": false,
|
|
46
55
|
"files": [
|
|
47
|
-
"src",
|
|
48
56
|
"dist"
|
|
49
57
|
],
|
|
50
58
|
"repository": {
|
|
51
59
|
"type": "git",
|
|
52
|
-
"url": "
|
|
60
|
+
"url": "https://github.com/beaugunderson/ip-address.git"
|
|
61
|
+
},
|
|
62
|
+
"overrides": {
|
|
63
|
+
"diff": "^8.0.3",
|
|
64
|
+
"serialize-javascript": "^7.0.5",
|
|
65
|
+
"@eslint/plugin-kit": "^0.7.1"
|
|
53
66
|
},
|
|
54
67
|
"devDependencies": {
|
|
55
|
-
"@types/chai": "^5.
|
|
56
|
-
"@types/mocha": "^10.0.
|
|
57
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
58
|
-
"@typescript-eslint/parser": "^8.
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"eslint": "^8.
|
|
68
|
+
"@types/chai": "^5.2.3",
|
|
69
|
+
"@types/mocha": "^10.0.10",
|
|
70
|
+
"@typescript-eslint/eslint-plugin": "^8.59.1",
|
|
71
|
+
"@typescript-eslint/parser": "^8.59.1",
|
|
72
|
+
"c8": "^11.0.0",
|
|
73
|
+
"chai": "^6.2.2",
|
|
74
|
+
"eslint": "^8.57.1",
|
|
62
75
|
"eslint_d": "^14.0.4",
|
|
63
|
-
"eslint-config-airbnb": "^
|
|
64
|
-
"eslint-config-prettier": "^
|
|
76
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
77
|
+
"eslint-config-prettier": "^10.1.8",
|
|
65
78
|
"eslint-plugin-filenames": "^1.3.2",
|
|
66
|
-
"eslint-plugin-import": "^2.
|
|
67
|
-
"eslint-plugin-
|
|
68
|
-
"eslint-plugin-prettier": "^5.2.1",
|
|
79
|
+
"eslint-plugin-import": "^2.32.0",
|
|
80
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
69
81
|
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
|
|
70
|
-
"mocha": "^
|
|
71
|
-
"
|
|
72
|
-
"prettier": "^3.
|
|
73
|
-
"release-it": "^17.6.0",
|
|
82
|
+
"mocha": "^11.7.5",
|
|
83
|
+
"monocart-coverage-reports": "^2.12.11",
|
|
84
|
+
"prettier": "^3.8.3",
|
|
74
85
|
"source-map-support": "^0.5.21",
|
|
75
|
-
"tsx": "^4.
|
|
86
|
+
"tsx": "^4.21.0",
|
|
87
|
+
"typedoc": "^0.28.19",
|
|
76
88
|
"typescript": "<5.6.0"
|
|
77
89
|
}
|
|
78
90
|
}
|
|
@@ -286,8 +286,8 @@ function withoutBase(input, base) {
|
|
|
286
286
|
if (nextChar && nextChar !== "/" && nextChar !== "?") {
|
|
287
287
|
return input;
|
|
288
288
|
}
|
|
289
|
-
const trimmed = input.slice(_base.length);
|
|
290
|
-
return
|
|
289
|
+
const trimmed = input.slice(_base.length).replace(/^\/+/, "");
|
|
290
|
+
return "/" + trimmed;
|
|
291
291
|
}
|
|
292
292
|
function withQuery(input, query) {
|
|
293
293
|
const parsed = parseURL(input);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ufo",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.4",
|
|
4
4
|
"description": "URL utils for humans",
|
|
5
5
|
"repository": "unjs/ufo",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"test": "pnpm lint && vitest run --typecheck"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "^25.0
|
|
35
|
-
"@vitest/coverage-v8": "^4.
|
|
36
|
-
"automd": "^0.4.
|
|
34
|
+
"@types/node": "^25.6.0",
|
|
35
|
+
"@vitest/coverage-v8": "^4.1.5",
|
|
36
|
+
"automd": "^0.4.3",
|
|
37
37
|
"changelogen": "^0.6.2",
|
|
38
|
-
"eslint": "^
|
|
38
|
+
"eslint": "^10.2.1",
|
|
39
39
|
"eslint-config-unjs": "^0.6.2",
|
|
40
40
|
"jiti": "^2.6.1",
|
|
41
|
-
"prettier": "^3.
|
|
42
|
-
"typescript": "^
|
|
41
|
+
"prettier": "^3.8.3",
|
|
42
|
+
"typescript": "^6.0.3",
|
|
43
43
|
"unbuild": "^3.6.1",
|
|
44
44
|
"untyped": "^2.0.0",
|
|
45
|
-
"vitest": "^4.
|
|
45
|
+
"vitest": "^4.1.5"
|
|
46
46
|
},
|
|
47
|
-
"packageManager": "pnpm@10.
|
|
47
|
+
"packageManager": "pnpm@10.33.2"
|
|
48
48
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nullix/zod-mongoose-studio-prod",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"@vue/runtime-dom": "3.5.32",
|
|
17
17
|
"@vue/server-renderer": "3.5.32",
|
|
18
18
|
"@vue/shared": "3.5.32",
|
|
19
|
+
"acorn": "8.16.0",
|
|
19
20
|
"bson": "7.2.0",
|
|
20
21
|
"consola": "3.4.2",
|
|
21
22
|
"devalue": "5.6.4",
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
"esbuild": "0.28.0",
|
|
24
25
|
"estree-walker": "2.0.2",
|
|
25
26
|
"hookable": "6.1.0",
|
|
26
|
-
"ip-address": "10.
|
|
27
|
+
"ip-address": "10.7.2",
|
|
27
28
|
"kareem": "3.3.0",
|
|
28
29
|
"memory-pager": "1.5.0",
|
|
29
30
|
"mongodb": "7.2.0",
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"sparse-bitfield": "3.0.3",
|
|
42
43
|
"tailwindcss": "4.2.2",
|
|
43
44
|
"tr46": "5.1.1",
|
|
44
|
-
"ufo": "1.6.
|
|
45
|
+
"ufo": "1.6.4",
|
|
45
46
|
"unhead": "2.1.12",
|
|
46
47
|
"vue": "3.5.32",
|
|
47
48
|
"vue-bundle-renderer": "2.2.0",
|
package/README.md
CHANGED
|
@@ -1,23 +1,51 @@
|
|
|
1
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/Harm-Nullix/zod-mongoose/HEAD/logo.svg" width="200" alt="Logo">
|
|
3
|
+
</div>
|
|
4
|
+
<div align="center">
|
|
2
5
|
|
|
3
6
|
[](https://github.com/Harm-Nullix/zod-mongoose/actions/workflows/release.yml)
|
|
4
|
-
[](https://www.npmjs.com/package/@nullix/zod-mongoose-studio)
|
|
5
|
-
[](https://www.npmjs.com/package/@nullix/zod-mongoose-studio)
|
|
8
|
+
[](https://www.npmjs.com/package/@nullix/zod-mongoose-studio)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
[](https://www.npmjs.com/package/@nullix/zod-mongoose-studio)
|
|
11
|
+
[](https://github.com/Harm-Nullix/zod-mongoose/blob/main/packages/studio/LICENSE.md)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
6
14
|
|
|
7
15
|
|
|
8
16
|
# @nullix/zod-mongoose-studio
|
|
9
17
|
|
|
10
18
|
A Monaco-powered TypeScript playground for [@nullix/zod-mongoose](https://github.com/Harm-Nullix/zod-mongoose).
|
|
11
19
|
|
|
12
|
-
The Studio provides a
|
|
20
|
+
The Studio provides a web-integrated interface to experiment with Zod validation and Zod-to-Mongoose transformations. It supports local development via a CLI and an embedded documentation mode.
|
|
13
21
|
|
|
14
22
|
## Goal
|
|
15
23
|
|
|
16
24
|
Create a CLI tool and web-integrated "Studio" that provides:
|
|
17
|
-
- A Monaco-powered TypeScript editor for Zod schemas.
|
|
18
|
-
-
|
|
25
|
+
- A Monaco-powered TypeScript editor for Zod schemas and a separate JSON data editor.
|
|
26
|
+
- Parsed Zod output or field-level validation issues next to Mongoose conversion output.
|
|
27
|
+
- Schema discovery, valid example data, and Run shortcuts.
|
|
19
28
|
- **Local Mode**: Runs via `npx` with full filesystem bridge for IntelliSense in your project.
|
|
20
|
-
- **Docs Mode**:
|
|
29
|
+
- **Docs Mode**: An embeddable playground that sends Run requests to a separate container runner through a Unix socket.
|
|
30
|
+
|
|
31
|
+
## Studio workflow
|
|
32
|
+
|
|
33
|
+
Define one or more Zod schemas in the TypeScript editor. `z` from `zod/v4` and the runtime exports of `@nullix/zod-mongoose` are available without import lines:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const UserSchema = z.object({
|
|
37
|
+
name: z.string().trim().min(2),
|
|
38
|
+
role: z.enum(['reader', 'admin']).default('reader'),
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Studio discovers top-level schemas automatically. When there are several, choose one from **Active schema**. Existing snippets using explicit imports and `export default` still work.
|
|
43
|
+
|
|
44
|
+
Use the expand button in any panel header for a full Studio workspace, then press Escape or the button again to restore the grid. The schema code, JSON input, and selected schema survive reloads in the same browser tab through `sessionStorage`; they are not saved on the server.
|
|
45
|
+
|
|
46
|
+
Enter JSON in **Try some data** and select **Run studio**. The validation result shows parsed data, including defaults and transforms, or Zod issues with their paths. Mongoose output remains available under **Definition**, **.obj**, **.tree**, and **.paths**. Use `⌘/Ctrl+S` or `⌘/Ctrl+R` to run while Studio has focus. Local mode also reruns after a short pause when schema code changes.
|
|
47
|
+
|
|
48
|
+
**Load valid example** generates JSON input and checks it against the selected schema before inserting it. For a custom refinement that cannot be generated automatically, provide a top-level `const exampleInput = { ... }` in the code editor; Studio checks that value too.
|
|
21
49
|
|
|
22
50
|
## Technical Stack
|
|
23
51
|
|
|
@@ -79,22 +107,21 @@ export default defineNuxtConfig({
|
|
|
79
107
|
<UContainer>
|
|
80
108
|
<h1 class="text-2xl font-bold my-4">Try it live!</h1>
|
|
81
109
|
|
|
82
|
-
<!--
|
|
83
|
-
<ZodMongooseStudio class="
|
|
110
|
+
<!-- Run uses the isolated runner configured on the docs host. -->
|
|
111
|
+
<ZodMongooseStudio class="border rounded-lg shadow-sm" style="--studio-height: 600px" />
|
|
84
112
|
</UContainer>
|
|
85
113
|
</template>
|
|
86
114
|
```
|
|
87
115
|
|
|
88
116
|
## Features & Configuration
|
|
89
117
|
|
|
90
|
-
### Transformation Engine (`/api/parse`)
|
|
118
|
+
### Transformation Engine (`/api/parse` locally, `/api/studio/run` in docs)
|
|
91
119
|
|
|
92
|
-
The
|
|
120
|
+
The runner exposes `z` and the public runtime helpers from `@nullix/zod-mongoose` as editor globals. Explicit imports of `zod/v4`, `@nullix/zod-mongoose`, and `mongoose` are also supported. The API accepts schema code, selected schema name, and JSON input; it returns validation and conversion results separately.
|
|
93
121
|
|
|
94
122
|
```ts
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
import { toMongooseScheme, extractMongooseDefinition } from '@nullix/zod-mongoose';
|
|
123
|
+
const UserSchema = z.object({ name: z.string() });
|
|
124
|
+
const exampleInput = { name: 'Ada' }; // Optional for custom validation rules
|
|
98
125
|
```
|
|
99
126
|
|
|
100
127
|
### Filesystem Bridge (`/api/resolve`)
|
|
@@ -103,12 +130,28 @@ Available only in **Local Mode** (`LOCAL_MODE=true`). It uses Node's `fs` or `ts
|
|
|
103
130
|
|
|
104
131
|
### Sandboxing & Security
|
|
105
132
|
|
|
106
|
-
|
|
133
|
+
Node's `vm` is **not a security boundary for untrusted code**. In Docs Mode, `/api/studio/run` forwards requests to a warm container through `STUDIO_RUNNER_SOCKET`; `/api/parse` remains restricted to the local CLI. Without the socket, the docs route returns 503. The docs process never evaluates visitor code. The runner container has no network and is read-only with CPU, memory, and process limits in `docker/compose.yaml`. Its small root supervisor accepts requests over the socket and starts a **new process with a fresh, unprivileged UID for every run**. No session retains a worker; at most two requests execute at once and eight wait in the queue. The three-second deadline kills the worker process group. The socket is owned by UID/GID 1000 and cannot be opened by workers. The supervisor needs only CHOWN, SETUID, SETGID and KILL capabilities. This reduces cross-request exposure, but does not make arbitrary code execution risk-free: malicious code could still try to exhaust the runner container or escape a process group. Keep Docker and the VPS patched and retain edge-level rate limits. Do not mount the Docker daemon socket into the docs server or runner.
|
|
134
|
+
|
|
135
|
+
To run this on a VPS, create `/run/zod-studio` owned by root and group 1000. The root supervisor creates the socket, then gives socket access to UID/GID 1000. Put the docs service in group 1000. Then build and start the runner from the repository root:
|
|
136
|
+
|
|
137
|
+
```shell
|
|
138
|
+
sudo install -d -m 0770 -o 0 -g 1000 /run/zod-studio
|
|
139
|
+
docker compose -f packages/studio/docker/compose.yaml up -d --build
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Set `STUDIO_RUNNER_SOCKET=/run/zod-studio/runner.sock` in the docs server environment, make that socket path visible to its process, and restart the docs server. If the docs server itself runs in a container, mount only `/run/zod-studio`, never the Docker socket. The docs UI enables Run through its Nuxt configuration. The runner has no TCP listener; only the docs server's H3 route is exposed publicly. Keep the existing public rate limit or add an edge-level limit when running multiple docs instances.
|
|
143
|
+
|
|
144
|
+
After deployment, verify the process boundary from the repository root:
|
|
145
|
+
|
|
146
|
+
```shell
|
|
147
|
+
docker compose -f packages/studio/docker/compose.yaml exec -T --user 1000:1000 studio-runner node - < packages/studio/docker/smoke-test.cjs
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This checks separate UIDs for concurrent runs, worker denial of socket access, timeout handling, and a successful request after timeout. A fresh process adds startup time to each Run request; no process or server-side session remains allocated between requests.
|
|
151
|
+
|
|
152
|
+
Local CLI mode continues to run directly, binds to `127.0.0.1`, and checks API hosts and origins. Browser session data stays in `sessionStorage` and is not kept by the runner.
|
|
107
153
|
|
|
108
|
-
-
|
|
109
|
-
- **Disabled Resolvers**: The `/api/resolve` endpoint is completely disabled.
|
|
110
|
-
- **Rate Limiting**: Built-in Nitro middleware tracks IP addresses and limits requests (default: 2 per second) to prevent abuse.
|
|
111
|
-
- **UI Hardening**: Elements related to the local filesystem are automatically hidden.
|
|
154
|
+
Running `pnpm --filter @nullix/zod-mongoose-studio dev` also uses the local parse endpoint, without Docker. In docs mode the editors remain usable without a runner, but Run reports that the runner is unavailable until the container and `STUDIO_RUNNER_SOCKET` are configured.
|
|
112
155
|
|
|
113
156
|
## Project Structure
|
|
114
157
|
|
package/app/assets/css/main.css
CHANGED