(input: {
readonly core: CoreDb;
readonly pluginId: string;
readonly owner: OwnerBinding;
})
| 1147 | }; |
| 1148 | |
| 1149 | const makePluginStorageFacade = (input: { |
| 1150 | readonly core: CoreDb; |
| 1151 | readonly pluginId: string; |
| 1152 | readonly owner: OwnerBinding; |
| 1153 | }): PluginStorageFacade => { |
| 1154 | // Owner partitions: org always, plus this subject's user partition. |
| 1155 | const readOwners: readonly Owner[] = input.owner.subject == null ? ["org"] : ["user", "org"]; |
| 1156 | |
| 1157 | const ownerSubject = (owner: Owner): { owner: Owner; subject: string } | null => { |
| 1158 | if (owner === "org") return { owner: "org", subject: ORG_SUBJECT }; |
| 1159 | if (input.owner.subject == null) return null; |
| 1160 | return { owner: "user", subject: String(input.owner.subject) }; |
| 1161 | }; |
| 1162 | |
| 1163 | const tenant = String(input.owner.tenant); |
| 1164 | |
| 1165 | const whereFor = |
| 1166 | (collection: string, key?: string): CoreWhere => |
| 1167 | (b: AnyCb) => |
| 1168 | b.and( |
| 1169 | b("plugin_id", "=", input.pluginId), |
| 1170 | b("collection", "=", collection), |
| 1171 | key === undefined ? true : b("key", "=", key), |
| 1172 | ); |
| 1173 | |
| 1174 | const whereOwner = (owner: Owner, collection: string, key: string): CoreWhere => { |
| 1175 | const os = ownerSubject(owner); |
| 1176 | return (b: AnyCb) => |
| 1177 | b.and( |
| 1178 | b("plugin_id", "=", input.pluginId), |
| 1179 | b("collection", "=", collection), |
| 1180 | b("key", "=", key), |
| 1181 | b("owner", "=", owner), |
| 1182 | b("subject", "=", os ? os.subject : ORG_SUBJECT), |
| 1183 | ); |
| 1184 | }; |
| 1185 | |
| 1186 | const ownerRank = (owner: Owner): number => readOwners.indexOf(owner); |
| 1187 | |
| 1188 | const sortByOwnerPrecedence = (rows: readonly CoreRow<"plugin_storage">[]) => |
| 1189 | [...rows].sort((left, right) => { |
| 1190 | const l = ownerRank(left.owner as Owner); |
| 1191 | const r = ownerRank(right.owner as Owner); |
| 1192 | return l - r || left.key.localeCompare(right.key); |
| 1193 | }); |
| 1194 | |
| 1195 | const getVisible = <T>(collection: string, key: string) => |
| 1196 | input.core.findMany("plugin_storage", { where: whereFor(collection, key) }).pipe( |
| 1197 | Effect.map((rows) => sortByOwnerPrecedence(rows)[0] ?? null), |
| 1198 | Effect.map((row) => (row ? pluginStorageEntryFromRow<T>(row) : null)), |
| 1199 | ); |
| 1200 | |
| 1201 | const getForOwnerImpl = <T>(owner: Owner, collection: string, key: string) => |
| 1202 | input.core |
| 1203 | .findFirst("plugin_storage", { |
| 1204 | where: whereOwner(owner, collection, key), |
| 1205 | }) |
| 1206 | .pipe(Effect.map((row) => (row ? pluginStorageEntryFromRow<T>(row) : null))); |
no test coverage detected