Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd50cab7

Browse files
authored
feat(api)!: use neverthrow for error handling (#937)
1 parente628d1d commitd50cab7

File tree

24 files changed

+1474
-1219
lines changed

24 files changed

+1474
-1219
lines changed

‎cspell.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"interface",
3434
"monoman",
3535
"mousemove",
36+
"neverthrow",
3637
"nolebase",
3738
"nuxt",
3839
"onwarn",

‎packages/api/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
},
5252
"dependencies": {
5353
"@vue-macros/common":"workspace:*",
54+
"neverthrow":"catalog:",
5455
"oxc-resolver":"catalog:"
5556
},
5657
"engines": {

‎packages/api/src/error.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
importtype{TransformError}from'@vue-macros/common'
2+
3+
exporttypeErrorVueSFC='<script> is not supported, only <script setup>.'
4+
exporttypeErrorResolveTS=
5+
|'Cannot resolve TS definition.'
6+
|'Cannot resolve TS definition. Union type contains different types of results.'
7+
| `Cannot resolve TS definition: ${string}`
8+
| `Cannot resolve TS type: ${string}`
9+
exporttypeErrorWithDefaults=
10+
'withDefaults: first argument must be a defineProps call.'
11+
exporttypeErrorUnknownNode=
12+
| `Unknown node: ${string}`
13+
| `Unknown ${'import'|'export'} type: ${string}`
14+
exporttypeError=TransformError<
15+
ErrorVueSFC|ErrorResolveTS|ErrorWithDefaults|ErrorUnknownNode
16+
>
17+
18+
exporttypeResultAsync<T>=import('neverthrow').ResultAsync<T,Error>

‎packages/api/src/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export*from'@vue-macros/common'
22

3+
export*from'./error'
34
export*from'./vue'
45
export*from'./ts'

‎packages/api/src/ts/namespace.ts‎

Lines changed: 128 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import{TransformError}from'@vue-macros/common'
2+
import{err,ok,safeTry,typeResultAsync}from'neverthrow'
3+
importtype{ErrorUnknownNode}from'../error'
14
import{isTSDeclaration}from'./is'
25
import{resolveDts}from'./resolve-file'
36
import{
@@ -20,124 +23,143 @@ export function isTSNamespace(val: unknown): val is TSNamespace {
2023
*
2124
*@limitation don't support non-TS declaration (e.g. class, function...)
2225
*/
23-
exportasyncfunctionresolveTSNamespace(scope:TSScope):Promise<void>{
24-
if(scope.exports)return
25-
26-
constexports:TSNamespace={
27-
[namespaceSymbol]:true,
28-
}
29-
scope.exports=exports
30-
31-
constdeclarations:TSNamespace={
32-
[namespaceSymbol]:true,
33-
...scope.declarations,
34-
}
35-
scope.declarations=declarations
36-
37-
const{ body, file}=resolveTSScope(scope)
38-
for(conststmtofbody||[]){
39-
if(
40-
stmt.type==='ExportDefaultDeclaration'&&
41-
isTSDeclaration(stmt.declaration)
42-
){
43-
exports.default=awaitresolveTSReferencedType({
44-
scope,
45-
type:stmt.declaration,
46-
})
47-
}elseif(stmt.type==='ExportAllDeclaration'){
48-
constresolved=awaitresolveDts(stmt.source.value,file.filePath)
49-
if(!resolved)continue
50-
51-
constsourceScope=awaitgetTSFile(resolved)
52-
awaitresolveTSNamespace(sourceScope)
53-
54-
Object.assign(exports,sourceScope.exports!)
55-
}elseif(stmt.type==='ExportNamedDeclaration'){
56-
letsourceExports:TSNamespace
57-
58-
if(stmt.source){
26+
exportfunctionresolveTSNamespace(
27+
scope:TSScope,
28+
):ResultAsync<void,TransformError<ErrorUnknownNode>>{
29+
returnsafeTry(asyncfunction*(){
30+
if(scope.exports)returnok()
31+
32+
constexports:TSNamespace={
33+
[namespaceSymbol]:true,
34+
}
35+
scope.exports=exports
36+
37+
constdeclarations:TSNamespace={
38+
[namespaceSymbol]:true,
39+
...scope.declarations,
40+
}
41+
scope.declarations=declarations
42+
43+
const{ body, file}=resolveTSScope(scope)
44+
for(conststmtofbody||[]){
45+
if(
46+
stmt.type==='ExportDefaultDeclaration'&&
47+
isTSDeclaration(stmt.declaration)
48+
){
49+
exports.default=yield*resolveTSReferencedType({
50+
scope,
51+
type:stmt.declaration,
52+
})
53+
}elseif(stmt.type==='ExportAllDeclaration'){
5954
constresolved=awaitresolveDts(stmt.source.value,file.filePath)
6055
if(!resolved)continue
6156

62-
constscope=awaitgetTSFile(resolved)
63-
awaitresolveTSNamespace(scope)
64-
sourceExports=scope.exports!
65-
}else{
66-
sourceExports=declarations
67-
}
57+
constsourceScope=awaitgetTSFile(resolved)
58+
yield*resolveTSNamespace(sourceScope)
59+
60+
Object.assign(exports,sourceScope.exports!)
61+
}elseif(stmt.type==='ExportNamedDeclaration'){
62+
letsourceExports:TSNamespace
6863

69-
for(constspecifierofstmt.specifiers){
70-
letexported:TSNamespace[string]
71-
if(specifier.type==='ExportDefaultSpecifier'){
72-
// export x from 'xxx'
73-
exported=sourceExports.default
74-
}elseif(specifier.type==='ExportNamespaceSpecifier'){
75-
// export * as x from 'xxx'
76-
exported=sourceExports
77-
}elseif(specifier.type==='ExportSpecifier'){
78-
// export { x } from 'xxx'
79-
exported=sourceExports![specifier.local.name]
64+
if(stmt.source){
65+
constresolved=awaitresolveDts(stmt.source.value,file.filePath)
66+
if(!resolved)continue
67+
68+
constscope=awaitgetTSFile(resolved)
69+
yield*resolveTSNamespace(scope)
70+
sourceExports=scope.exports!
8071
}else{
81-
thrownewError(`Unknown export type:${(specifierasany).type}`)
72+
sourceExports=declarations
8273
}
8374

84-
constname=
85-
specifier.exported.type==='Identifier'
86-
?specifier.exported.name
87-
:specifier.exported.value
88-
exports[name]=exported
89-
}
75+
for(constspecifierofstmt.specifiers){
76+
letexported:TSNamespace[string]
77+
if(specifier.type==='ExportDefaultSpecifier'){
78+
// export x from 'xxx'
79+
exported=sourceExports.default
80+
}elseif(specifier.type==='ExportNamespaceSpecifier'){
81+
// export * as x from 'xxx'
82+
exported=sourceExports
83+
}elseif(specifier.type==='ExportSpecifier'){
84+
// export { x } from 'xxx'
85+
exported=sourceExports![specifier.local.name]
86+
}else{
87+
returnerr(
88+
newTransformError(
89+
`Unknown export type:${
90+
//@ts-expect-error unknown type
91+
specifier.typeasstring
92+
}`,
93+
),
94+
)
95+
}
9096

91-
// export interface A {}
92-
if(isTSDeclaration(stmt.declaration)){
93-
constdecl=stmt.declaration
94-
95-
if(decl.id?.type==='Identifier'){
96-
constexportedName=decl.id.name
97-
declarations[exportedName]=exports[exportedName]=
98-
awaitresolveTSReferencedType({
99-
scope,
100-
type:decl,
101-
})
97+
constname=
98+
specifier.exported.type==='Identifier'
99+
?specifier.exported.name
100+
:specifier.exported.value
101+
exports[name]=exported
102+
}
103+
104+
// export interface A {}
105+
if(isTSDeclaration(stmt.declaration)){
106+
constdecl=stmt.declaration
107+
108+
if(decl.id?.type==='Identifier'){
109+
constexportedName=decl.id.name
110+
declarations[exportedName]=exports[exportedName]=
111+
yield*resolveTSReferencedType({
112+
scope,
113+
type:decl,
114+
})
115+
}
102116
}
103117
}
104-
}
105118

106-
// declarations
107-
elseif(isTSDeclaration(stmt)){
108-
if(stmt.id?.type!=='Identifier')continue
109-
110-
declarations[stmt.id.name]=awaitresolveTSReferencedType({
111-
scope,
112-
type:stmt,
113-
})
114-
}elseif(stmt.type==='ImportDeclaration'){
115-
constresolved=awaitresolveDts(stmt.source.value,file.filePath)
116-
if(!resolved)continue
117-
118-
constimportScope=awaitgetTSFile(resolved)
119-
awaitresolveTSNamespace(importScope)
120-
constexports=importScope.exports!
121-
122-
for(constspecifierofstmt.specifiers){
123-
constlocal=specifier.local.name
124-
125-
letimported:TSNamespace[string]
126-
if(specifier.type==='ImportDefaultSpecifier'){
127-
imported=exports.default
128-
}elseif(specifier.type==='ImportNamespaceSpecifier'){
129-
imported=exports
130-
}elseif(specifier.type==='ImportSpecifier'){
131-
constname=
132-
specifier.imported.type==='Identifier'
133-
?specifier.imported.name
134-
:specifier.imported.value
135-
imported=exports[name]
136-
}else{
137-
thrownewError(`Unknown import type:${(specifierasany).type}`)
119+
// declarations
120+
elseif(isTSDeclaration(stmt)){
121+
if(stmt.id?.type!=='Identifier')continue
122+
123+
declarations[stmt.id.name]=yield*resolveTSReferencedType({
124+
scope,
125+
type:stmt,
126+
})
127+
}elseif(stmt.type==='ImportDeclaration'){
128+
constresolved=awaitresolveDts(stmt.source.value,file.filePath)
129+
if(!resolved)continue
130+
131+
constimportScope=awaitgetTSFile(resolved)
132+
yield*resolveTSNamespace(importScope)
133+
constexports=importScope.exports!
134+
135+
for(constspecifierofstmt.specifiers){
136+
constlocal=specifier.local.name
137+
138+
letimported:TSNamespace[string]
139+
if(specifier.type==='ImportDefaultSpecifier'){
140+
imported=exports.default
141+
}elseif(specifier.type==='ImportNamespaceSpecifier'){
142+
imported=exports
143+
}elseif(specifier.type==='ImportSpecifier'){
144+
constname=
145+
specifier.imported.type==='Identifier'
146+
?specifier.imported.name
147+
:specifier.imported.value
148+
imported=exports[name]
149+
}else{
150+
returnerr(
151+
newTransformError(
152+
`Unknown import type:${
153+
//@ts-expect-error unknown type
154+
specifier.typeasstring
155+
}`,
156+
),
157+
)
158+
}
159+
declarations[local]=imported
138160
}
139-
declarations[local]=imported
140161
}
141162
}
142-
}
163+
returnok()
164+
})
143165
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp