@@ -9,11 +9,13 @@ import (
99 "path"
1010 "path/filepath"
1111 "runtime"
12+ "slices"
1213 "strconv"
1314 "strings"
1415
1516 "github.com/esm-dev/esm.sh/internal/storage"
1617 "github.com/ije/gox/term"
18+ "github.com/ije/gox/utils"
1719)
1820
1921var (
@@ -68,12 +70,8 @@ type BanScope struct {
6870}
6971
7072type AllowList struct {
71- Packages []string `json:"packages"`
72- Scopes []AllowScope `json:"scopes"`
73- }
74-
75- type AllowScope struct {
76- Name string `json:"name"`
73+ Packages []string `json:"packages"`
74+ Scopes []string `json:"scopes"`
7775}
7876
7977// LoadConfig loads config from the given file. Panic if failed to load.
@@ -248,77 +246,73 @@ func normalizeConfig(config *Config) {
248246
249247// extractPackageName Will take a packageName as input extract key parts and return them
250248//
251- // fullNameWithoutVersion e.g. @github/faker
252- // scope e.g. @github
253- // nameWithoutVersionScope e.g. faker
254- func extractPackageName (packageName string ) (fullNameWithoutVersion string , scope string , nameWithoutVersionScope string ) {
255- paths := strings .Split (packageName , "/" )
256- if strings .HasPrefix (packageName , "@" ) {
249+ // moduleName e.g. @github/faker[@1.0.0]/submodule
250+ // packageId e.g. @github/faker[@1.0.0]
251+ // scope e.g. @github
252+ // name e.g. faker
253+ // version e.g. [@1.0.0]
254+ func extractPackageName (moduleName string ) (packageId string , scope string , name string , version string ) {
255+ paths := strings .Split (moduleName , "/" )
256+ if strings .HasPrefix (moduleName , "@" ) && len (paths ) > 1 {
257+ packageId = paths [0 ] + "/" + paths [1 ]
257258 scope = paths [0 ]
258- nameWithoutVersionScope = strings .Split (paths [1 ], "@" )[0 ]
259- fullNameWithoutVersion = fmt .Sprintf ("%s/%s" , scope , nameWithoutVersionScope )
259+ name , version = utils .SplitByFirstByte (paths [1 ], '@' )
260260 } else {
261261 // the package has no scope prefix
262- nameWithoutVersionScope = strings . Split ( paths [ 0 ], "@" ) [0 ]
263- fullNameWithoutVersion = nameWithoutVersionScope
262+ packageId = paths [0 ]
263+ name , version = utils . SplitByFirstByte ( packageId , '@' )
264264 }
265-
266- return fullNameWithoutVersion , scope , nameWithoutVersionScope
265+ return
267266}
268267
269- // IsPackageBanned Checking if the package is banned.
270- // The `packages` list is the highest priority ban rule to match,
271- // so the `excludes` list in the `scopes` list won't take effect if the package is banned in `packages` list
272- func (banList * BanList ) IsPackageBanned (fullName string ) bool {
273- fullNameWithoutVersion , scope , nameWithoutVersionScope := extractPackageName (fullName )
268+ func (allowList * AllowList ) IsEmpty () bool {
269+ return len (allowList .Packages ) == 0 && len (allowList .Scopes ) == 0
270+ }
274271
275- for _ , p := range banList .Packages {
276- if fullNameWithoutVersion == p {
277- return true
278- }
272+ // IsPackageAllowed Checking if the package is allowed.
273+ // The `packages` list is the highest priority allow rule to match,
274+ // so the `includes` list in the `scopes` list won't take effect if the package is allowed in `packages` list
275+ func (allowList * AllowList ) IsPackageAllowed (moduleName string ) bool {
276+ if allowList .IsEmpty () {
277+ return true
279278 }
280279
281- for _ , s := range banList . Scopes {
282- if scope == s . Name {
283- return ! isPackageExcluded ( nameWithoutVersionScope , s . Excludes )
284- }
280+ packageId , scope , name , _ := extractPackageName ( moduleName )
281+
282+ if slices . Contains ( allowList . Packages , packageId ) || ( scope != "" && slices . Contains ( allowList . Packages , scope + "/" + name )) || ( scope == "" && slices . Contains ( allowList . Packages , name )) {
283+ return true
285284 }
286285
287- return false
286+ return slices . Contains ( allowList . Scopes , scope )
288287}
289288
290- // IsPackageAllowed Checking if the package is allowed .
291- // The `packages` list is the highest priority allow rule to match,
292- // so the `includes ` list in the `scopes` list won't take effect if the package is allowed in `packages` list
293- func (allowList * AllowList ) IsPackageAllowed ( fullName string ) bool {
294- if len ( allowList . Packages ) == 0 && len ( allowList . Scopes ) == 0 {
295- return true
289+ // IsPackageBanned Checking if the package is banned .
290+ // The `packages` list is the highest priority ban rule to match,
291+ // so the `excludes ` list in the `scopes` list won't take effect if the package is banned in `packages` list
292+ func (banList * BanList ) IsPackageBanned ( moduleName string ) bool {
293+ if banList . IsEmpty () {
294+ return false
296295 }
297296
298- fullNameWithoutVersion , scope , _ := extractPackageName (fullName )
297+ packageId , scope , name , version := extractPackageName (moduleName )
299298
300- for _ , p := range allowList .Packages {
301- if fullNameWithoutVersion == p {
302- return true
303- }
299+ if slices .Contains (banList .Packages , packageId ) || (scope != "" && slices .Contains (banList .Packages , scope + "/" + name )) || (scope == "" && slices .Contains (banList .Packages , name )) {
300+ return true
304301 }
305302
306- for _ , s := range allowList .Scopes {
307- if scope == s .Name {
308- return true
303+ if scope != "" {
304+ for _ , s := range banList .Scopes {
305+ if scope == s .Name {
306+ return ! slices .Contains (s .Excludes , name ) && ! (version != "" && slices .Contains (s .Excludes , name + "@" + version ))
307+ }
309308 }
310309 }
311310
312311 return false
313312}
314313
315- func isPackageExcluded (name string , excludes []string ) bool {
316- for _ , exclude := range excludes {
317- if name == exclude {
318- return true
319- }
320- }
321- return false
314+ func (banList * BanList ) IsEmpty () bool {
315+ return len (banList .Packages ) == 0 && len (banList .Scopes ) == 0
322316}
323317
324318func init () {
0 commit comments