FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
opencode/packages/opencode/src/plugin/meta.ts at dev · argszero/opencode · GitHub
argszero
/
opencode
Public
forked from
anomalyco/opencode
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
opencode
/
packages
/
opencode
/
src
/
plugin
/
meta.ts
Copy path
More file actions
More file actions
Latest commit
History
History
History
188 lines (162 loc) · 4.92 KB
Breadcrumbs
opencode
/
packages
/
opencode
/
src
/
plugin
/
meta.ts
Copy path
File metadata and controls
188 lines (162 loc) · 4.92 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import
path
from
"path"
import
{
fileURLToPath
}
from
"url"
import
{
Flag
}
from
"@opencode-ai/core/flag/flag"
import
{
Global
}
from
"@opencode-ai/core/global"
import
{
Filesystem
}
from
"@/util/filesystem"
import
{
Flock
}
from
"@opencode-ai/core/util/flock"
import
{
parsePluginSpecifier
,
pluginSource
}
from
"./shared"
type
Source
=
"file"
|
"npm"
export
type
Theme
=
{
src
:
string
dest
:
string
mtime
?:
number
size
?:
number
}
export
type
Entry
=
{
id
:
string
source
:
Source
spec
:
string
target
:
string
requested
?:
string
version
?:
string
modified
?:
number
first_time
:
number
last_time
:
number
time_changed
:
number
load_count
:
number
fingerprint
:
string
themes
?:
Record
<
string
,
Theme
>
}
export
type
State
=
"first"
|
"updated"
|
"same"
export
type
Touch
=
{
spec
:
string
target
:
string
id
:
string
}
type
Store
=
Record
<
string
,
Entry
>
type
Core
=
Omit
<
Entry
,
"first_time"
|
"last_time"
|
"time_changed"
|
"load_count"
|
"fingerprint"
|
"themes"
>
type
Row
=
Touch
&
{
core
:
Core
}
function
storePath
(
)
{
return
Flag
.
OPENCODE_PLUGIN_META_FILE
??
path
.
join
(
Global
.
Path
.
state
,
"plugin-meta.json"
)
}
function
lock
(
file
:
string
)
{
return
`plugin-meta:
${
file
}
`
}
function
fileTarget
(
spec
:
string
,
target
:
string
)
{
if
(
spec
.
startsWith
(
"file://"
)
)
return
fileURLToPath
(
spec
)
if
(
target
.
startsWith
(
"file://"
)
)
return
fileURLToPath
(
target
)
return
}
async
function
modifiedAt
(
file
:
string
)
{
const
stat
=
await
Filesystem
.
statAsync
(
file
)
if
(
!
stat
)
return
const
mtime
=
stat
.
mtimeMs
return
Math
.
floor
(
typeof
mtime
===
"bigint"
?
Number
(
mtime
)
:
mtime
)
}
function
resolvedTarget
(
target
:
string
)
{
if
(
target
.
startsWith
(
"file://"
)
)
return
fileURLToPath
(
target
)
return
target
}
async
function
npmVersion
(
target
:
string
)
{
const
resolved
=
resolvedTarget
(
target
)
const
stat
=
await
Filesystem
.
statAsync
(
resolved
)
const
dir
=
stat
?.
isDirectory
(
)
?
resolved
:
path
.
dirname
(
resolved
)
return
Filesystem
.
readJson
<
{
version
?:
string
}
>
(
path
.
join
(
dir
,
"package.json"
)
)
.
then
(
(
item
)
=>
item
.
version
)
.
catch
(
(
)
=>
undefined
)
}
async
function
entryCore
(
item
:
Touch
)
:
Promise
<
Core
>
{
const
spec
=
item
.
spec
const
target
=
item
.
target
const
source
=
pluginSource
(
spec
)
if
(
source
===
"file"
)
{
const
file
=
fileTarget
(
spec
,
target
)
return
{
id
:
item
.
id
,
source
,
spec
,
target
,
modified
:
file
?
await
modifiedAt
(
file
)
:
undefined
,
}
}
return
{
id
:
item
.
id
,
source
,
spec
,
target
,
requested
:
parsePluginSpecifier
(
spec
)
.
version
,
version
:
await
npmVersion
(
target
)
,
}
}
function
fingerprint
(
value
:
Core
)
{
if
(
value
.
source
===
"file"
)
return
[
value
.
target
,
value
.
modified
??
""
]
.
join
(
"|"
)
return
[
value
.
target
,
value
.
requested
??
""
,
value
.
version
??
""
]
.
join
(
"|"
)
}
async
function
read
(
file
:
string
)
:
Promise
<
Store
>
{
return
Filesystem
.
readJson
<
Store
>
(
file
)
.
catch
(
(
)
=>
(
{
}
)
as
Store
)
}
async
function
row
(
item
:
Touch
)
:
Promise
<
Row
>
{
return
{
...
item
,
core
:
await
entryCore
(
item
)
,
}
}
function
next
(
prev
:
Entry
|
undefined
,
core
:
Core
,
now
:
number
)
:
{
state
:
State
;
entry
:
Entry
}
{
const
entry
:
Entry
=
{
...
core
,
first_time
:
prev
?.
first_time
??
now
,
last_time
:
now
,
time_changed
:
prev
?.
time_changed
??
now
,
load_count
:
(
prev
?.
load_count
??
0
)
+
1
,
fingerprint
:
fingerprint
(
core
)
,
themes
:
prev
?.
themes
,
}
const
state
:
State
=
!
prev
?
"first"
:
prev
.
fingerprint
===
entry
.
fingerprint
?
"same"
:
"updated"
if
(
state
===
"updated"
)
entry
.
time_changed
=
now
return
{
state
,
entry
,
}
}
export
async
function
touchMany
(
items
:
Touch
[
]
)
:
Promise
<
Array
<
{
state
:
State
;
entry
:
Entry
}
>
>
{
if
(
!
items
.
length
)
return
[
]
const
file
=
storePath
(
)
const
rows
=
await
Promise
.
all
(
items
.
map
(
(
item
)
=>
row
(
item
)
)
)
return
Flock
.
withLock
(
lock
(
file
)
,
async
(
)
=>
{
const
store
=
await
read
(
file
)
const
now
=
Date
.
now
(
)
const
out
:
Array
<
{
state
:
State
;
entry
:
Entry
}
>
=
[
]
for
(
const
item
of
rows
)
{
const
hit
=
next
(
store
[
item
.
id
]
,
item
.
core
,
now
)
store
[
item
.
id
]
=
hit
.
entry
out
.
push
(
hit
)
}
await
Filesystem
.
writeJson
(
file
,
store
)
return
out
}
)
}
export
async
function
touch
(
spec
:
string
,
target
:
string
,
id
:
string
)
:
Promise
<
{
state
:
State
;
entry
:
Entry
}
>
{
return
touchMany
(
[
{
spec
,
target
,
id
}
]
)
.
then
(
(
item
)
=>
{
const
hit
=
item
[
0
]
if
(
hit
)
return
hit
throw
new
Error
(
"Failed to touch plugin metadata."
)
}
)
}
export
async
function
setTheme
(
id
:
string
,
name
:
string
,
theme
:
Theme
)
:
Promise
<
void
>
{
const
file
=
storePath
(
)
await
Flock
.
withLock
(
lock
(
file
)
,
async
(
)
=>
{
const
store
=
await
read
(
file
)
const
entry
=
store
[
id
]
if
(
!
entry
)
return
entry
.
themes
=
{
...
entry
.
themes
,
[
name
]
:
theme
,
}
await
Filesystem
.
writeJson
(
file
,
store
)
}
)
}
export
async
function
list
(
)
:
Promise
<
Store
>
{
const
file
=
storePath
(
)
return
Flock
.
withLock
(
lock
(
file
)
,
async
(
)
=>
read
(
file
)
)
}
export
*
as
PluginMeta
from
"./meta"
Back
|
FazBrowse Home
|
New Git URL