mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
feat: validate embedded data structure
This commit is contained in:
parent
d29f935e64
commit
b606a4bb7d
5 changed files with 97 additions and 14 deletions
|
|
@ -45,6 +45,7 @@
|
|||
"react-use": "^17.3.2",
|
||||
"react-window": "^1.8.7",
|
||||
"styled-components": "^5.3.5",
|
||||
"superstruct": "^1.0.3",
|
||||
"webext-domain-permission-toggle": "^3.0.0",
|
||||
"webext-dynamic-content-scripts": "^8.1.1",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import { raiseError } from 'analytics'
|
||||
import { Clippy, ClippyClassName } from 'components/Clippy'
|
||||
import * as React from 'react'
|
||||
import * as s from 'superstruct'
|
||||
import { $ } from 'utils/$'
|
||||
import { formatClass, parseIntFromElement } from 'utils/DOMHelper'
|
||||
import { renderReact } from 'utils/general'
|
||||
import { embeddedDataStruct } from './embeddedDataStructures'
|
||||
|
||||
const selectors = {
|
||||
normal: {
|
||||
|
|
@ -44,16 +46,11 @@ const getDOMJSON = (selector: string) =>
|
|||
}
|
||||
})
|
||||
|
||||
function getMetaFromPayload(payload: any) {
|
||||
function getMetaFromPayload(payload: s.Infer<typeof embeddedDataStruct.repoPayload>) {
|
||||
const { repo, refInfo } = payload
|
||||
if (!repo || !refInfo) return
|
||||
|
||||
const { defaultBranch, name: repoName, ownerLogin: userName } = repo
|
||||
const { name: branchName } = refInfo
|
||||
|
||||
// TODO: use runtime type check
|
||||
if (!defaultBranch || !repoName || !userName || !branchName) return
|
||||
|
||||
return {
|
||||
defaultBranch,
|
||||
metaData: {
|
||||
|
|
@ -66,15 +63,14 @@ function getMetaFromPayload(payload: any) {
|
|||
|
||||
// in code page, there is a JSON script tag in DOM with meta data
|
||||
function resolveEmbeddedAppData() {
|
||||
const appData = getDOMJSON(selectors.globalNavigation.embeddedData.app)
|
||||
const payload = appData?.payload
|
||||
if (payload) return getMetaFromPayload(payload)
|
||||
const data = getDOMJSON(selectors.globalNavigation.embeddedData.app)
|
||||
if (s.is(data, embeddedDataStruct.app)) return getMetaFromPayload(data.payload)
|
||||
}
|
||||
|
||||
function resolveEmbeddedReposOverviewData() {
|
||||
const reposOverviewData = getDOMJSON(selectors.globalNavigation.embeddedData.reposOverview)
|
||||
const payload = reposOverviewData?.props?.initialPayload
|
||||
if (payload) return getMetaFromPayload(payload)
|
||||
const data = getDOMJSON(selectors.globalNavigation.embeddedData.reposOverview)
|
||||
if (s.is(data, embeddedDataStruct.reposOverview))
|
||||
return getMetaFromPayload(data.props.initialPayload)
|
||||
}
|
||||
|
||||
export function resolveEmbeddedData(): {
|
||||
|
|
|
|||
81
src/platforms/GitHub/embeddedDataStructures.ts
Normal file
81
src/platforms/GitHub/embeddedDataStructures.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import * as s from 'superstruct'
|
||||
|
||||
const repo = s.object({
|
||||
id: s.number(),
|
||||
defaultBranch: s.string(),
|
||||
name: s.string(),
|
||||
ownerLogin: s.string(),
|
||||
currentUserCanPush: s.boolean(),
|
||||
isFork: s.boolean(),
|
||||
isEmpty: s.boolean(),
|
||||
createdAt: s.string(),
|
||||
ownerAvatar: s.string(),
|
||||
public: s.boolean(),
|
||||
private: s.boolean(),
|
||||
isOrgOwned: s.boolean(),
|
||||
})
|
||||
|
||||
const user = s.object({
|
||||
id: s.number(),
|
||||
login: s.string(),
|
||||
userEmail: s.string(),
|
||||
})
|
||||
|
||||
const rel = s.object({
|
||||
name: s.string(),
|
||||
listCacheKey: s.string(),
|
||||
canEdit: s.boolean(),
|
||||
refType: s.string(),
|
||||
currentOid: s.string(),
|
||||
})
|
||||
|
||||
const treeItem = s.object({
|
||||
name: s.string(),
|
||||
path: s.string(),
|
||||
contentType: s.string(),
|
||||
})
|
||||
|
||||
const tree = s.object({
|
||||
items: s.array(treeItem),
|
||||
templateDirectorySuggestionUrl: s.nullable(s.never()),
|
||||
readme: s.nullable(s.never()),
|
||||
totalCount: s.number(),
|
||||
showBranchInfobar: s.boolean(),
|
||||
})
|
||||
|
||||
const repoPayload = s.object({
|
||||
allShortcutsEnabled: s.boolean(),
|
||||
path: s.string(),
|
||||
repo: repo,
|
||||
currentUser: user,
|
||||
refInfo: rel,
|
||||
tree: tree,
|
||||
fileTree: s.nullable(s.never()),
|
||||
fileTreeProcessingTime: s.nullable(s.never()),
|
||||
foldersToFetch: s.array(s.unknown()),
|
||||
treeExpanded: s.boolean(),
|
||||
symbolsExpanded: s.boolean(),
|
||||
isOverview: s.boolean(),
|
||||
overview: s.unknown(),
|
||||
})
|
||||
|
||||
const reposOverview = s.object({
|
||||
props: s.object({
|
||||
initialPayload: repoPayload,
|
||||
appPayload: s.unknown(),
|
||||
}),
|
||||
})
|
||||
const app = s.object({
|
||||
payload: repoPayload,
|
||||
})
|
||||
|
||||
export const embeddedDataStruct = {
|
||||
repo,
|
||||
user,
|
||||
rel,
|
||||
treeItem,
|
||||
tree,
|
||||
repoPayload,
|
||||
reposOverview,
|
||||
app,
|
||||
}
|
||||
|
|
@ -113,10 +113,10 @@ module.exports = {
|
|||
sideEffects: false,
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
test: /\.m?js$/,
|
||||
loader: 'babel-loader',
|
||||
// Transpile as least files under node_modules
|
||||
include: /node_modules\/(webext-content-scripts|webext-detect-page)\/.*\.js$/,
|
||||
include: /node_modules\/(webext-content-scripts|webext-detect-page|superstruct)\/.*\.m?js$/,
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11325,6 +11325,11 @@ stylis@^4.0.6:
|
|||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.1.tgz#e46c6a9bbf7c58db1e65bb730be157311ae1fe12"
|
||||
integrity sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ==
|
||||
|
||||
superstruct@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmmirror.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046"
|
||||
integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==
|
||||
|
||||
supports-color@6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
|
||||
|
|
|
|||
Loading…
Reference in a new issue