@@ -61,4 +61,79 @@ describe('createResolver', () => {
6161 ] ,
6262 )
6363 } )
64+
65+ it ( 'resolves valid scoped name through validation' , async ( ) => {
66+ const resolver = createResolver ( 'theme' , { } )
67+
68+ const res = await resolver ( '@slidev/theme-official' , '/' )
69+
70+ expect ( res ) . toEqual ( [
71+ '@slidev/theme-official' ,
72+ '/user/project/node_modules/@slidev/theme-official' ,
73+ ] )
74+ } )
75+
76+ it ( 'passes through "none" without validation' , async ( ) => {
77+ const resolver = createResolver ( 'theme' , { } )
78+
79+ const res = await resolver ( 'none' , '/' )
80+
81+ expect ( res ) . toEqual ( [ '' , null ] )
82+ } )
83+
84+ it ( 'rejects names with shell metacharacters' , async ( ) => {
85+ const resolver = createResolver ( 'theme' , { } )
86+
87+ await expect ( resolver ( 'evil$(rm -rf)' , '/' ) ) . rejects . toThrowError (
88+ 'Invalid theme name "evil$(rm -rf)". Only valid npm package names are allowed.' ,
89+ )
90+ } )
91+
92+ it ( 'rejects names with backslashes' , async ( ) => {
93+ const resolver = createResolver ( 'theme' , { } )
94+
95+ await expect ( resolver ( 'evil\\package' , '/' ) ) . rejects . toThrowError (
96+ / I n v a l i d t h e m e n a m e / ,
97+ )
98+ } )
99+
100+ it ( 'rejects names with uppercase letters' , async ( ) => {
101+ const resolver = createResolver ( 'theme' , { } )
102+
103+ await expect ( resolver ( 'EvilTheme' , '/' ) ) . rejects . toThrowError (
104+ / I n v a l i d t h e m e n a m e / ,
105+ )
106+ } )
107+
108+ it ( 'rejects scoped names with extra slash segments' , async ( ) => {
109+ const resolver = createResolver ( 'theme' , { } )
110+
111+ await expect ( resolver ( '@scope/foo/bar' , '/' ) ) . rejects . toThrowError (
112+ / I n v a l i d t h e m e n a m e / ,
113+ )
114+ } )
115+
116+ it ( 'rejects scoped names with parent traversal segment' , async ( ) => {
117+ const resolver = createResolver ( 'theme' , { } )
118+
119+ await expect ( resolver ( '@evil/../escape' , '/' ) ) . rejects . toThrowError (
120+ / I n v a l i d t h e m e n a m e / ,
121+ )
122+ } )
123+
124+ it ( 'rejects empty string' , async ( ) => {
125+ const resolver = createResolver ( 'theme' , { } )
126+
127+ await expect ( resolver ( '' , '/' ) ) . rejects . toThrowError (
128+ / I n v a l i d t h e m e n a m e / ,
129+ )
130+ } )
131+
132+ it ( 'reflects the resolver type in the error message' , async ( ) => {
133+ const resolver = createResolver ( 'addon' , { } )
134+
135+ await expect ( resolver ( 'evil$(rm -rf)' , '/' ) ) . rejects . toThrowError (
136+ 'Invalid addon name "evil$(rm -rf)". Only valid npm package names are allowed.' ,
137+ )
138+ } )
64139} )
0 commit comments