@nestia/editor 11.0.0-dev.20260316 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +93 -93
- package/dist/assets/{index-CwCzW6vi.js → index-DUWBgT-P.js} +3823 -3823
- package/dist/index.html +19 -19
- package/package.json +4 -4
- package/src/NestiaEditorApplication.tsx +94 -94
- package/src/NestiaEditorIframe.tsx +245 -245
- package/src/NestiaEditorModule.ts +136 -136
- package/src/NestiaEditorUploader.tsx +154 -154
- package/src/internal/NestiaEditorComposer.ts +90 -90
- package/src/internal/NestiaEditorFileUploader.tsx +68 -68
- package/src/main.tsx +10 -10
|
@@ -1,245 +1,245 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Alert,
|
|
3
|
-
AlertTitle,
|
|
4
|
-
CircularProgress,
|
|
5
|
-
Step,
|
|
6
|
-
StepContent,
|
|
7
|
-
StepLabel,
|
|
8
|
-
Stepper,
|
|
9
|
-
Typography,
|
|
10
|
-
} from "@mui/material";
|
|
11
|
-
import StackBlitzSDK from "@stackblitz/sdk";
|
|
12
|
-
import { OpenApiV3, OpenApiV3_1, SwaggerV2 } from "@typia/interface";
|
|
13
|
-
import { load } from "js-yaml";
|
|
14
|
-
import React from "react";
|
|
15
|
-
import { IValidation } from "typia";
|
|
16
|
-
|
|
17
|
-
import { NestiaEditorComposer } from "./internal/NestiaEditorComposer";
|
|
18
|
-
|
|
19
|
-
export function NestiaEditorIframe(props: NestiaEditorIframe.IProps) {
|
|
20
|
-
const [id] = React.useState(
|
|
21
|
-
`reactia-editor-div-${Math.random().toString().substring(2)}`,
|
|
22
|
-
);
|
|
23
|
-
const [step, setStep] = React.useState(0);
|
|
24
|
-
const [fetchError, setFetchError] = React.useState<string | null>(null);
|
|
25
|
-
const [operations, setOperationCount] = React.useState<
|
|
26
|
-
Record<string, number>
|
|
27
|
-
>({});
|
|
28
|
-
const [composerError, setComposerError] = React.useState<any | null>(null);
|
|
29
|
-
|
|
30
|
-
React.useEffect(() => {
|
|
31
|
-
(async () => {
|
|
32
|
-
// LOADING OPENAPI DOCUMENTS
|
|
33
|
-
setStep(0);
|
|
34
|
-
const document:
|
|
35
|
-
| SwaggerV2.IDocument
|
|
36
|
-
| OpenApiV3.IDocument
|
|
37
|
-
| OpenApiV3_1.IDocument
|
|
38
|
-
| string =
|
|
39
|
-
typeof props.swagger === "string"
|
|
40
|
-
? await getDocument(props.swagger)
|
|
41
|
-
: props.swagger;
|
|
42
|
-
if (typeof document === "string") {
|
|
43
|
-
setFetchError(document);
|
|
44
|
-
return;
|
|
45
|
-
} else setOperationCount(aggregateOperation(document));
|
|
46
|
-
|
|
47
|
-
// GENERATING SOFTWARE DEVELOPMENT KIT
|
|
48
|
-
setStep(1);
|
|
49
|
-
const result: IValidation<NestiaEditorComposer.IOutput> =
|
|
50
|
-
await (async () => {
|
|
51
|
-
try {
|
|
52
|
-
return await NestiaEditorComposer[props.mode ?? "sdk"]({
|
|
53
|
-
document,
|
|
54
|
-
keyword: props.keyword ?? true,
|
|
55
|
-
simulate: props.simulate ?? true,
|
|
56
|
-
e2e: props.e2e ?? true,
|
|
57
|
-
package: props.package ?? "@ORGANIZATION/PROJECT",
|
|
58
|
-
});
|
|
59
|
-
} catch (exp) {
|
|
60
|
-
return {
|
|
61
|
-
success: false,
|
|
62
|
-
errors: exp as any,
|
|
63
|
-
data: undefined,
|
|
64
|
-
} satisfies IValidation.IFailure;
|
|
65
|
-
}
|
|
66
|
-
})();
|
|
67
|
-
if (result.success === false) {
|
|
68
|
-
setComposerError(result.errors);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// COMPOSING STACKBLITZ PROJECT
|
|
73
|
-
setStep(2);
|
|
74
|
-
StackBlitzSDK.embedProject(
|
|
75
|
-
id,
|
|
76
|
-
{
|
|
77
|
-
title: document.info?.title ?? "Nestia Editor",
|
|
78
|
-
template: "node",
|
|
79
|
-
files: result.data.files,
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
width: "100%",
|
|
83
|
-
height: "100%",
|
|
84
|
-
openFile: result.data.openFile,
|
|
85
|
-
startScript: result.data.startScript as any, // no problem
|
|
86
|
-
},
|
|
87
|
-
);
|
|
88
|
-
})().catch((exp) => {
|
|
89
|
-
console.error("unknown error", exp);
|
|
90
|
-
});
|
|
91
|
-
}, []);
|
|
92
|
-
return (
|
|
93
|
-
<div
|
|
94
|
-
id={id}
|
|
95
|
-
style={{
|
|
96
|
-
width: "100%",
|
|
97
|
-
height: "100%",
|
|
98
|
-
overflow: "hidden",
|
|
99
|
-
}}
|
|
100
|
-
>
|
|
101
|
-
<div
|
|
102
|
-
style={{
|
|
103
|
-
padding: 25,
|
|
104
|
-
overflow: "auto",
|
|
105
|
-
}}
|
|
106
|
-
>
|
|
107
|
-
<Typography variant="h4">Nestia Editor</Typography>
|
|
108
|
-
<hr />
|
|
109
|
-
<br />
|
|
110
|
-
<Stepper activeStep={step} orientation="vertical" nonLinear={true}>
|
|
111
|
-
<Step key={0}>
|
|
112
|
-
<StepLabel>
|
|
113
|
-
<Typography variant="h5">Loading OpenAPI Document</Typography>
|
|
114
|
-
</StepLabel>
|
|
115
|
-
<StepContent>
|
|
116
|
-
<br />
|
|
117
|
-
<CircularProgress size={100} color="success" />
|
|
118
|
-
<br />
|
|
119
|
-
<br />
|
|
120
|
-
{typeof props.swagger === "string" ? (
|
|
121
|
-
<>
|
|
122
|
-
<p>Fetching OpenAPI Document from</p>
|
|
123
|
-
<p>
|
|
124
|
-
<a href={props.swagger} target="_blank">
|
|
125
|
-
{props.swagger}
|
|
126
|
-
</a>
|
|
127
|
-
</p>
|
|
128
|
-
</>
|
|
129
|
-
) : (
|
|
130
|
-
"Delivering OpenAPI Document to the composer"
|
|
131
|
-
)}
|
|
132
|
-
{fetchError !== null ? (
|
|
133
|
-
<Alert severity="error">
|
|
134
|
-
<AlertTitle>Fetch Error</AlertTitle>
|
|
135
|
-
{fetchError}
|
|
136
|
-
</Alert>
|
|
137
|
-
) : null}
|
|
138
|
-
</StepContent>
|
|
139
|
-
</Step>
|
|
140
|
-
<Step key={1}>
|
|
141
|
-
<StepLabel>
|
|
142
|
-
<Typography variant="h5">
|
|
143
|
-
Generating Software Development Kit
|
|
144
|
-
</Typography>
|
|
145
|
-
</StepLabel>
|
|
146
|
-
<StepContent>
|
|
147
|
-
<br />
|
|
148
|
-
<CircularProgress size={100} color="success" />
|
|
149
|
-
<br />
|
|
150
|
-
<br />
|
|
151
|
-
Generating SDK functions...
|
|
152
|
-
<br />
|
|
153
|
-
<ul>
|
|
154
|
-
<li>
|
|
155
|
-
total operations: #
|
|
156
|
-
{Object.values(operations)
|
|
157
|
-
.reduce((a, b) => a + b, 0)
|
|
158
|
-
.toLocaleString()}
|
|
159
|
-
</li>
|
|
160
|
-
{Object.entries(operations).map(([method, count]) => (
|
|
161
|
-
<li>
|
|
162
|
-
{method}: #{count.toLocaleString()}
|
|
163
|
-
</li>
|
|
164
|
-
))}
|
|
165
|
-
</ul>
|
|
166
|
-
{composerError !== null ? (
|
|
167
|
-
<>
|
|
168
|
-
<br />
|
|
169
|
-
<Alert severity="error">
|
|
170
|
-
<AlertTitle>Composition Error</AlertTitle>
|
|
171
|
-
<pre>{JSON.stringify(composerError, null, 2)}</pre>
|
|
172
|
-
</Alert>
|
|
173
|
-
</>
|
|
174
|
-
) : null}
|
|
175
|
-
</StepContent>
|
|
176
|
-
</Step>
|
|
177
|
-
<Step key={2}>
|
|
178
|
-
<StepLabel>
|
|
179
|
-
<Typography variant="h5">Composing TypeScript Project</Typography>
|
|
180
|
-
</StepLabel>
|
|
181
|
-
<StepContent></StepContent>
|
|
182
|
-
</Step>
|
|
183
|
-
</Stepper>
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
export namespace NestiaEditorIframe {
|
|
189
|
-
export interface IProps {
|
|
190
|
-
swagger:
|
|
191
|
-
| string
|
|
192
|
-
| SwaggerV2.IDocument
|
|
193
|
-
| OpenApiV3.IDocument
|
|
194
|
-
| OpenApiV3_1.IDocument;
|
|
195
|
-
package?: string;
|
|
196
|
-
keyword?: boolean;
|
|
197
|
-
simulate?: boolean;
|
|
198
|
-
e2e?: boolean;
|
|
199
|
-
|
|
200
|
-
/** @internal */
|
|
201
|
-
mode?: "nest" | "sdk";
|
|
202
|
-
|
|
203
|
-
/** @internal */
|
|
204
|
-
files?: Record<string, string>;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const getDocument = async (
|
|
209
|
-
url: string,
|
|
210
|
-
): Promise<
|
|
211
|
-
SwaggerV2.IDocument | OpenApiV3.IDocument | OpenApiV3_1.IDocument | string
|
|
212
|
-
> => {
|
|
213
|
-
try {
|
|
214
|
-
const response: Response = await fetch(url);
|
|
215
|
-
if (response.status !== 200) return await response.text();
|
|
216
|
-
else if (url.endsWith(".yaml")) {
|
|
217
|
-
const text: string = await response.text();
|
|
218
|
-
return load(text) as OpenApiV3.IDocument;
|
|
219
|
-
}
|
|
220
|
-
return await response.json();
|
|
221
|
-
} catch (error) {
|
|
222
|
-
if (error instanceof Error) return error.message;
|
|
223
|
-
return "Unknown error";
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const aggregateOperation = (
|
|
228
|
-
document: SwaggerV2.IDocument | OpenApiV3.IDocument | OpenApiV3_1.IDocument,
|
|
229
|
-
): Record<string, number> => {
|
|
230
|
-
const map: Record<string, number> = {};
|
|
231
|
-
if (!(typeof document === "object" && document !== null)) return map;
|
|
232
|
-
for (const collection of Object.values(document.paths ?? {}))
|
|
233
|
-
if (typeof collection === "object" && collection !== null)
|
|
234
|
-
for (const [method] of Object.entries(collection))
|
|
235
|
-
if (
|
|
236
|
-
method === "head" ||
|
|
237
|
-
method === "get" ||
|
|
238
|
-
method === "post" ||
|
|
239
|
-
method === "patch" ||
|
|
240
|
-
method === "put" ||
|
|
241
|
-
method === "delete"
|
|
242
|
-
)
|
|
243
|
-
map[method] = (map[method] ?? 0) + 1;
|
|
244
|
-
return map;
|
|
245
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
Alert,
|
|
3
|
+
AlertTitle,
|
|
4
|
+
CircularProgress,
|
|
5
|
+
Step,
|
|
6
|
+
StepContent,
|
|
7
|
+
StepLabel,
|
|
8
|
+
Stepper,
|
|
9
|
+
Typography,
|
|
10
|
+
} from "@mui/material";
|
|
11
|
+
import StackBlitzSDK from "@stackblitz/sdk";
|
|
12
|
+
import { OpenApiV3, OpenApiV3_1, SwaggerV2 } from "@typia/interface";
|
|
13
|
+
import { load } from "js-yaml";
|
|
14
|
+
import React from "react";
|
|
15
|
+
import { IValidation } from "typia";
|
|
16
|
+
|
|
17
|
+
import { NestiaEditorComposer } from "./internal/NestiaEditorComposer";
|
|
18
|
+
|
|
19
|
+
export function NestiaEditorIframe(props: NestiaEditorIframe.IProps) {
|
|
20
|
+
const [id] = React.useState(
|
|
21
|
+
`reactia-editor-div-${Math.random().toString().substring(2)}`,
|
|
22
|
+
);
|
|
23
|
+
const [step, setStep] = React.useState(0);
|
|
24
|
+
const [fetchError, setFetchError] = React.useState<string | null>(null);
|
|
25
|
+
const [operations, setOperationCount] = React.useState<
|
|
26
|
+
Record<string, number>
|
|
27
|
+
>({});
|
|
28
|
+
const [composerError, setComposerError] = React.useState<any | null>(null);
|
|
29
|
+
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
(async () => {
|
|
32
|
+
// LOADING OPENAPI DOCUMENTS
|
|
33
|
+
setStep(0);
|
|
34
|
+
const document:
|
|
35
|
+
| SwaggerV2.IDocument
|
|
36
|
+
| OpenApiV3.IDocument
|
|
37
|
+
| OpenApiV3_1.IDocument
|
|
38
|
+
| string =
|
|
39
|
+
typeof props.swagger === "string"
|
|
40
|
+
? await getDocument(props.swagger)
|
|
41
|
+
: props.swagger;
|
|
42
|
+
if (typeof document === "string") {
|
|
43
|
+
setFetchError(document);
|
|
44
|
+
return;
|
|
45
|
+
} else setOperationCount(aggregateOperation(document));
|
|
46
|
+
|
|
47
|
+
// GENERATING SOFTWARE DEVELOPMENT KIT
|
|
48
|
+
setStep(1);
|
|
49
|
+
const result: IValidation<NestiaEditorComposer.IOutput> =
|
|
50
|
+
await (async () => {
|
|
51
|
+
try {
|
|
52
|
+
return await NestiaEditorComposer[props.mode ?? "sdk"]({
|
|
53
|
+
document,
|
|
54
|
+
keyword: props.keyword ?? true,
|
|
55
|
+
simulate: props.simulate ?? true,
|
|
56
|
+
e2e: props.e2e ?? true,
|
|
57
|
+
package: props.package ?? "@ORGANIZATION/PROJECT",
|
|
58
|
+
});
|
|
59
|
+
} catch (exp) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
errors: exp as any,
|
|
63
|
+
data: undefined,
|
|
64
|
+
} satisfies IValidation.IFailure;
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
if (result.success === false) {
|
|
68
|
+
setComposerError(result.errors);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// COMPOSING STACKBLITZ PROJECT
|
|
73
|
+
setStep(2);
|
|
74
|
+
StackBlitzSDK.embedProject(
|
|
75
|
+
id,
|
|
76
|
+
{
|
|
77
|
+
title: document.info?.title ?? "Nestia Editor",
|
|
78
|
+
template: "node",
|
|
79
|
+
files: result.data.files,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
width: "100%",
|
|
83
|
+
height: "100%",
|
|
84
|
+
openFile: result.data.openFile,
|
|
85
|
+
startScript: result.data.startScript as any, // no problem
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
})().catch((exp) => {
|
|
89
|
+
console.error("unknown error", exp);
|
|
90
|
+
});
|
|
91
|
+
}, []);
|
|
92
|
+
return (
|
|
93
|
+
<div
|
|
94
|
+
id={id}
|
|
95
|
+
style={{
|
|
96
|
+
width: "100%",
|
|
97
|
+
height: "100%",
|
|
98
|
+
overflow: "hidden",
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
<div
|
|
102
|
+
style={{
|
|
103
|
+
padding: 25,
|
|
104
|
+
overflow: "auto",
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
<Typography variant="h4">Nestia Editor</Typography>
|
|
108
|
+
<hr />
|
|
109
|
+
<br />
|
|
110
|
+
<Stepper activeStep={step} orientation="vertical" nonLinear={true}>
|
|
111
|
+
<Step key={0}>
|
|
112
|
+
<StepLabel>
|
|
113
|
+
<Typography variant="h5">Loading OpenAPI Document</Typography>
|
|
114
|
+
</StepLabel>
|
|
115
|
+
<StepContent>
|
|
116
|
+
<br />
|
|
117
|
+
<CircularProgress size={100} color="success" />
|
|
118
|
+
<br />
|
|
119
|
+
<br />
|
|
120
|
+
{typeof props.swagger === "string" ? (
|
|
121
|
+
<>
|
|
122
|
+
<p>Fetching OpenAPI Document from</p>
|
|
123
|
+
<p>
|
|
124
|
+
<a href={props.swagger} target="_blank">
|
|
125
|
+
{props.swagger}
|
|
126
|
+
</a>
|
|
127
|
+
</p>
|
|
128
|
+
</>
|
|
129
|
+
) : (
|
|
130
|
+
"Delivering OpenAPI Document to the composer"
|
|
131
|
+
)}
|
|
132
|
+
{fetchError !== null ? (
|
|
133
|
+
<Alert severity="error">
|
|
134
|
+
<AlertTitle>Fetch Error</AlertTitle>
|
|
135
|
+
{fetchError}
|
|
136
|
+
</Alert>
|
|
137
|
+
) : null}
|
|
138
|
+
</StepContent>
|
|
139
|
+
</Step>
|
|
140
|
+
<Step key={1}>
|
|
141
|
+
<StepLabel>
|
|
142
|
+
<Typography variant="h5">
|
|
143
|
+
Generating Software Development Kit
|
|
144
|
+
</Typography>
|
|
145
|
+
</StepLabel>
|
|
146
|
+
<StepContent>
|
|
147
|
+
<br />
|
|
148
|
+
<CircularProgress size={100} color="success" />
|
|
149
|
+
<br />
|
|
150
|
+
<br />
|
|
151
|
+
Generating SDK functions...
|
|
152
|
+
<br />
|
|
153
|
+
<ul>
|
|
154
|
+
<li>
|
|
155
|
+
total operations: #
|
|
156
|
+
{Object.values(operations)
|
|
157
|
+
.reduce((a, b) => a + b, 0)
|
|
158
|
+
.toLocaleString()}
|
|
159
|
+
</li>
|
|
160
|
+
{Object.entries(operations).map(([method, count]) => (
|
|
161
|
+
<li>
|
|
162
|
+
{method}: #{count.toLocaleString()}
|
|
163
|
+
</li>
|
|
164
|
+
))}
|
|
165
|
+
</ul>
|
|
166
|
+
{composerError !== null ? (
|
|
167
|
+
<>
|
|
168
|
+
<br />
|
|
169
|
+
<Alert severity="error">
|
|
170
|
+
<AlertTitle>Composition Error</AlertTitle>
|
|
171
|
+
<pre>{JSON.stringify(composerError, null, 2)}</pre>
|
|
172
|
+
</Alert>
|
|
173
|
+
</>
|
|
174
|
+
) : null}
|
|
175
|
+
</StepContent>
|
|
176
|
+
</Step>
|
|
177
|
+
<Step key={2}>
|
|
178
|
+
<StepLabel>
|
|
179
|
+
<Typography variant="h5">Composing TypeScript Project</Typography>
|
|
180
|
+
</StepLabel>
|
|
181
|
+
<StepContent></StepContent>
|
|
182
|
+
</Step>
|
|
183
|
+
</Stepper>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
export namespace NestiaEditorIframe {
|
|
189
|
+
export interface IProps {
|
|
190
|
+
swagger:
|
|
191
|
+
| string
|
|
192
|
+
| SwaggerV2.IDocument
|
|
193
|
+
| OpenApiV3.IDocument
|
|
194
|
+
| OpenApiV3_1.IDocument;
|
|
195
|
+
package?: string;
|
|
196
|
+
keyword?: boolean;
|
|
197
|
+
simulate?: boolean;
|
|
198
|
+
e2e?: boolean;
|
|
199
|
+
|
|
200
|
+
/** @internal */
|
|
201
|
+
mode?: "nest" | "sdk";
|
|
202
|
+
|
|
203
|
+
/** @internal */
|
|
204
|
+
files?: Record<string, string>;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const getDocument = async (
|
|
209
|
+
url: string,
|
|
210
|
+
): Promise<
|
|
211
|
+
SwaggerV2.IDocument | OpenApiV3.IDocument | OpenApiV3_1.IDocument | string
|
|
212
|
+
> => {
|
|
213
|
+
try {
|
|
214
|
+
const response: Response = await fetch(url);
|
|
215
|
+
if (response.status !== 200) return await response.text();
|
|
216
|
+
else if (url.endsWith(".yaml")) {
|
|
217
|
+
const text: string = await response.text();
|
|
218
|
+
return load(text) as OpenApiV3.IDocument;
|
|
219
|
+
}
|
|
220
|
+
return await response.json();
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (error instanceof Error) return error.message;
|
|
223
|
+
return "Unknown error";
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const aggregateOperation = (
|
|
228
|
+
document: SwaggerV2.IDocument | OpenApiV3.IDocument | OpenApiV3_1.IDocument,
|
|
229
|
+
): Record<string, number> => {
|
|
230
|
+
const map: Record<string, number> = {};
|
|
231
|
+
if (!(typeof document === "object" && document !== null)) return map;
|
|
232
|
+
for (const collection of Object.values(document.paths ?? {}))
|
|
233
|
+
if (typeof collection === "object" && collection !== null)
|
|
234
|
+
for (const [method] of Object.entries(collection))
|
|
235
|
+
if (
|
|
236
|
+
method === "head" ||
|
|
237
|
+
method === "get" ||
|
|
238
|
+
method === "post" ||
|
|
239
|
+
method === "patch" ||
|
|
240
|
+
method === "put" ||
|
|
241
|
+
method === "delete"
|
|
242
|
+
)
|
|
243
|
+
map[method] = (map[method] ?? 0) + 1;
|
|
244
|
+
return map;
|
|
245
|
+
};
|