( input: unknown, )
| 101 | } |
| 102 | |
| 103 | function validateFilesystem( |
| 104 | input: unknown, |
| 105 | ): |
| 106 | | { ok: true; entries: AdditionalFileSystemPermission[] } |
| 107 | | Extract<AdditionalPermissionValidationResult, { ok: false }> { |
| 108 | if (input === undefined) return { ok: true, entries: [] }; |
| 109 | if (!isRecord(input) || hasUnexpectedKeys(input, ['entries']) || !Array.isArray(input.entries)) { |
| 110 | return invalid('invalid_profile', 'fileSystem must contain an entries array.'); |
| 111 | } |
| 112 | if (input.entries.length > MAX_ADDITIONAL_FILESYSTEM_ENTRIES) { |
| 113 | return invalid( |
| 114 | 'too_many_entries', |
| 115 | `Additional filesystem permissions are limited to ${MAX_ADDITIONAL_FILESYSTEM_ENTRIES} entries.`, |
| 116 | ); |
| 117 | } |
| 118 | const entries: AdditionalFileSystemPermission[] = []; |
| 119 | for (const candidate of input.entries) { |
| 120 | if (!isRecord(candidate) || hasUnexpectedKeys(candidate, ['path', 'access', 'scope'])) { |
| 121 | return invalid( |
| 122 | 'invalid_entry', |
| 123 | 'Additional filesystem permission contains unsupported fields.', |
| 124 | ); |
| 125 | } |
| 126 | if ( |
| 127 | typeof candidate.path !== 'string' || |
| 128 | !ADDITIONAL_PERMISSION_ACCESS_MODES.includes( |
| 129 | candidate.access as AdditionalPermissionAccess, |
| 130 | ) || |
| 131 | !ADDITIONAL_PERMISSION_SCOPES.includes(candidate.scope as AdditionalPermissionScope) |
| 132 | ) { |
| 133 | return invalid( |
| 134 | 'invalid_entry', |
| 135 | 'Additional filesystem permission must contain path, access, and scope.', |
| 136 | ); |
| 137 | } |
| 138 | if (!isNormalizedAbsolutePath(candidate.path)) { |
| 139 | return invalid( |
| 140 | 'invalid_path', |
| 141 | 'Additional filesystem permission path must be a normalized absolute path.', |
| 142 | ); |
| 143 | } |
| 144 | if (candidate.path.length > MAX_ADDITIONAL_PERMISSION_PATH_CHARS) { |
| 145 | return invalid( |
| 146 | 'path_too_long', |
| 147 | 'Additional filesystem permission path exceeds the length limit.', |
| 148 | ); |
| 149 | } |
| 150 | entries.push({ |
| 151 | path: trimTrailingSlashes(candidate.path), |
| 152 | access: candidate.access as AdditionalPermissionAccess, |
| 153 | scope: candidate.scope as AdditionalPermissionScope, |
| 154 | }); |
| 155 | } |
| 156 | return { ok: true, entries }; |
| 157 | } |
| 158 | |
| 159 | function validateNetwork( |
| 160 | input: unknown, |
no test coverage detected