2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 | https://swiftfiddle.com
18 |
19 | ## Supporters & Sponsors
20 |
21 | Open source projects thrive on the generosity and support of people like you. If you find this project valuable, please consider extending your support. Contributing to the project not only sustains its growth, but also helps drive innovation and improve its features.
22 |
23 | To support this project, you can become a sponsor through [GitHub Sponsors](https://github.com/sponsors/kishikawakatsumi). Your contribution will be greatly appreciated and will help keep the project alive and thriving. Thanks for your consideration! :heart:
24 |
25 | ### Related Projects
26 |
27 | - [SwiftFiddle LSP](https://github.com/swiftfiddle/swiftfiddle-lsp) (Provide Code Completion powered by [SourceKit-LSP](https://github.com/apple/sourcekit-lsp))
28 |
--------------------------------------------------------------------------------
/Sources/App/Models/VersionGroup.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | final class VersionGroup: Encodable {
4 | let majorVersion: String
5 | var versions: [String]
6 |
7 | init(majorVersion: String, versions: [String]) {
8 | self.majorVersion = majorVersion
9 | self.versions = versions
10 | }
11 |
12 | static func grouped(versions: [String]) -> [VersionGroup] {
13 | versions.reduce(into: [VersionGroup]()) { (versionGroup, version) in
14 | let nightlyVersion = version.split(separator: "-")
15 | if nightlyVersion.count == 2 {
16 | let majorVersion = String(nightlyVersion[0])
17 | if majorVersion != versionGroup.last?.majorVersion {
18 | versionGroup.append(VersionGroup(majorVersion: majorVersion, versions: [version]))
19 | } else {
20 | versionGroup.last?.versions.append(version)
21 | }
22 | } else if nightlyVersion.count == 4 {
23 | let majorVersion = "snapshot"
24 | if majorVersion != versionGroup.last?.majorVersion {
25 | versionGroup.append(VersionGroup(majorVersion: majorVersion, versions: [nightlyVersion.joined(separator: "-")]))
26 | } else {
27 | versionGroup.last?.versions.append(nightlyVersion.joined(separator: "-"))
28 | }
29 | } else {
30 | let majorVersion = "Swift \(version.split(separator: ".")[0])"
31 | if majorVersion != versionGroup.last?.majorVersion {
32 | versionGroup.append(VersionGroup(majorVersion: majorVersion, versions: [version]))
33 | } else {
34 | versionGroup.last?.versions.append(version)
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Sources/App/versions.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | func latestVersion() throws -> String { try availableVersions()[0] }
4 | func stableVersion() -> String { "6.2.1" }
5 |
6 | func availableVersions() throws -> [String] {
7 | [
8 | "nightly-main",
9 | "nightly-6.2",
10 | "nightly-6.1",
11 | "nightly-6.0",
12 | "nightly-5.10",
13 | "nightly-5.9",
14 | "nightly-5.8",
15 | "nightly-5.7",
16 | "nightly-5.6",
17 | "nightly-5.5",
18 | "nightly-5.4",
19 | "nightly-5.3",
20 | "6.2.1",
21 | "6.2",
22 | "6.1.3",
23 | "6.1.2",
24 | "6.1.1",
25 | "6.1",
26 | "6.0.3",
27 | "6.0.2",
28 | "6.0.1",
29 | "6.0",
30 | "5.10.1",
31 | "5.10",
32 | "5.9.2",
33 | "5.9.1",
34 | "5.9",
35 | "5.8.1",
36 | "5.8",
37 | "5.7.3",
38 | "5.7.2",
39 | "5.7.1",
40 | "5.7",
41 | "5.6.3",
42 | "5.6.2",
43 | "5.6.1",
44 | "5.6",
45 | "5.5.3",
46 | "5.5.2",
47 | "5.5.1",
48 | "5.5",
49 | "5.4.3",
50 | "5.4.2",
51 | "5.4.1",
52 | "5.4",
53 | "5.3.3",
54 | "5.3.2",
55 | "5.3.1",
56 | "5.3",
57 | "5.2.5",
58 | "5.2.4",
59 | "5.2.3",
60 | "5.2.2",
61 | "5.2.1",
62 | "5.2",
63 | "5.1.5",
64 | "5.1.4",
65 | "5.1.3",
66 | "5.1.2",
67 | "5.1.1",
68 | "5.1",
69 | "5.0.3",
70 | "5.0.2",
71 | "5.0.1",
72 | "5.0",
73 | "4.2.4",
74 | "4.2.3",
75 | "4.2.2",
76 | "4.2.1",
77 | "4.2",
78 | "4.1.3",
79 | "4.1.2",
80 | "4.1.1",
81 | "4.1",
82 | "4.0.3",
83 | "4.0.2",
84 | "4.0",
85 | "3.1.1",
86 | "3.1",
87 | "3.0.2",
88 | "3.0.1",
89 | "3.0",
90 | "2.2.1",
91 | "2.2",
92 | ]
93 | }
94 |
--------------------------------------------------------------------------------
/Public/js/snackbar.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | import { Toast } from "bootstrap";
4 |
5 | const infoContainerBlock = document.getElementById("snackbar-info-container");
6 | const infoBlock = document.getElementById("snackbar-info");
7 | const alertContainerBlock = document.getElementById("snackbar-alert-container");
8 | const alertBlock = document.getElementById("snackbar-alert");
9 |
10 | export class Snackbar {
11 | static info(message) {
12 | const messageContainer = document.getElementById("snackbar-info-message");
13 | messageContainer.textContent = message;
14 | infoContainerBlock.classList.remove("d-none");
15 | infoBlock.classList.remove("d-none");
16 | new Toast(infoBlock).show();
17 | }
18 |
19 | static alert(message) {
20 | const messageContainer = document.getElementById("snackbar-alert-message");
21 | messageContainer.textContent = message;
22 | alertContainerBlock.classList.remove("d-none");
23 | alertBlock.classList.remove("d-none");
24 | new Toast(alertBlock).show();
25 | }
26 | }
27 |
28 | if (infoBlock) {
29 | infoBlock.addEventListener("hidden.bs.toast", () => {
30 | infoContainerBlock.classList.add("d-none");
31 | infoBlock.classList.add("d-none");
32 | });
33 | infoBlock.addEventListener("hidden.bs.toast", () => {
34 | infoContainerBlock.classList.add("d-none");
35 | infoBlock.classList.add("d-none");
36 | });
37 | }
38 | if (alertBlock) {
39 | alertBlock.addEventListener("hidden.bs.toast", () => {
40 | alertContainerBlock.classList.add("d-none");
41 | alertBlock.classList.add("d-none");
42 | });
43 | alertBlock.addEventListener("hidden.bs.toast", () => {
44 | alertContainerBlock.classList.add("d-none");
45 | alertBlock.classList.add("d-none");
46 | });
47 | }
48 |
--------------------------------------------------------------------------------
/Public/images/icon_swiftfiddle.com.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Sources/App/Middlewares/CommonErrorMiddleware.swift:
--------------------------------------------------------------------------------
1 | import Vapor
2 |
3 | final class CommonErrorMiddleware: Middleware {
4 | func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture#(reason)
339 |Language Server Status:
Ready
" 404 | ); 405 | const tooltip = Tooltip.getInstance(statusContainer); 406 | tooltip.hide(); 407 | } 408 | } else { 409 | statusIcon.src = "/images/lsp.svg"; 410 | if (statusContainer) { 411 | statusContainer.setAttribute( 412 | "data-bs-original-title", 413 | "Language Server Status:
Initializing...
" 414 | ); 415 | const tooltip = Tooltip.getInstance(statusContainer); 416 | tooltip.hide(); 417 | } 418 | } 419 | } 420 | } 421 | } 422 | -------------------------------------------------------------------------------- /Public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 42 | 43 |