灵符lingfu
F

fu.ling-lang.org

↓ 0 downloads

ทะเบียนแพ็กเกจ fu.ling-lang.org — เขียนด้วยภาษา Ling (ไทย) ทั้งหมด

Keywords registry, packages, web, ling, thai
lingfu install fu.ling-lang.org
LicenseApache-2.0 OR MIT
Authorsลิงลิน
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (22)

controllers/publish.ling
// controllers/publish.ling — เผยแพร่ผ่านกุญแจ API + ตรวจสอบ + ระงับ + สำรอง

// แยก bearer token จากส่วนหัว Authorization: "Bearer lfu_xxx" → "lfu_xxx"
ฟังก์ชัน ดึงกุญแจ(คำขอ) {
    ผูก หัว = คำขอ.authorization
    ถ้า หัว == "" {
        คืน ""
    }
    // รูปแบบ "Bearer <key>" — ตัดคำนำหน้าออก (เก็บทั้งสตริงถ้าไม่มีคำนำหน้า)
    คืน str_strip_prefix(หัว, "Bearer ")
}

// POST /api/v1/packages/publish
// body (form): name, version, description, artifact_b64
// header: Authorization: Bearer lfu_...
ฟังก์ชัน ทำเผยแพร่(คำขอ) {
    ผูก กุญแจ = ดึงกุญแจ(คำขอ)
    ผูก ไอดีผู้ใช้ = กุญแจตรวจ(กุญแจ)
    ถ้า ไอดีผู้ใช้ == 0 {
        คืน เจสัน(401, "{\"error\":\"invalid or missing API key\"}")
    }

    ผูก ชื่อ = query_param(คำขอ.body, "name", "")
    ผูก รุ่น = query_param(คำขอ.body, "version", "")
    ผูก คำอธิบาย = query_param(คำขอ.body, "description", "")
    ผูก อาร์ติแฟกต์ = query_param(คำขอ.body, "artifact_b64", "")

    ถ้า ชื่อ == "" {
        คืน เจสัน(400, "{\"error\":\"missing package name\"}")
    }
    ถ้า รุ่น == "" {
        คืน เจสัน(400, "{\"error\":\"missing version\"}")
    }
    ถ้า อาร์ติแฟกต์ == "" {
        คืน เจสัน(400, "{\"error\":\"missing built artifact — only built software may be uploaded\"}")
    }

    // ── ตรวจสิทธิ์: ต้องเป็นเจ้าของ (หรือแพ็กเกจใหม่) ──
    ผูก เจ้าของเดิม = แพ็กเกจเจ้าของ(ชื่อ)
    ถ้า เจ้าของเดิม > 0 {
        ถ้า เจ้าของเดิม != ไอดีผู้ใช้ {
            คืน เจสัน(403, "{\"error\":\"you are not an owner of this package\"}")
        }
    }

    // ── เขียนอาร์ติแฟกต์ที่ build แล้วลงดิสก์ ──
    make_dir("storage/packages")
    ผูก ที่เก็บ = "storage/packages/" + ชื่อ + "-" + รุ่น + ".tgz"
    ผูก เขียนได้ = base64_decode_to_file(อาร์ติแฟกต์, ที่เก็บ)
    ถ้า เขียนได้ == เท็จ {
        คืน เจสัน(400, "{\"error\":\"artifact is not valid base64\"}")
    }

    // ── ประตูตรวจสอบ: ต้องเป็นซอฟต์แวร์ที่ build แล้วจริง ──
    ถ้า อาร์ติแฟกต์ตรวจ(ที่เก็บ) == เท็จ {
        คืน เจสัน(422, "{\"error\":\"artifact failed verification: not a valid built (gzip/zip) archive\"}")
    }

    ผูก ไอดีแพ็กเกจ = แพ็กเกจเผยแพร่(ชื่อ, คำอธิบาย, ไอดีผู้ใช้)
    ถ้า รุ่นมีอยู่(ไอดีแพ็กเกจ, รุ่น) {
        คืน เจสัน(409, "{\"error\":\"version already exists — bump the version\"}")
    }

    // ── เมทาดาทาเสริม (ถ้าไคลเอนต์ส่งมา) — คีย์เวิร์ด/โฮมเพจ/ที่เก็บ/ใบอนุญาต/ผู้เขียน/README ──
    ผูก คีย์เวิร์ด = query_param(คำขอ.body, "keywords", "")
    ผูก โฮมเพจ = query_param(คำขอ.body, "homepage", "")
    ผูก ที่เก็บโค้ด = query_param(คำขอ.body, "repository", "")
    ผูก ใบอนุญาต = query_param(คำขอ.body, "license", "")
    ผูก ผู้เขียน = query_param(คำขอ.body, "authors", "")
    ผูก รีดมี = query_param(คำขอ.body, "readme", "")
    แพ็กเกจข้อมูล(ชื่อ, คีย์เวิร์ด, โฮมเพจ, ที่เก็บโค้ด, ใบอนุญาต, ผู้เขียน, รีดมี)

    ผูก เช็คซัม = file_hash(ที่เก็บ)
    รุ่นบันทึก(ไอดีแพ็กเกจ, รุ่น, เช็คซัม)

    // ── สำรองถาวรทันทีที่เผยแพร่ (เก็บตลอดไป แม้ถูกระงับ) ──
    make_dir("storage/backup")
    copy_file(ที่เก็บ, "storage/backup/" + ชื่อ + "-" + รุ่น + ".tgz")

    คืน เจสัน(200, "{\"ok\":true,\"package\":\"" + ชื่อ + "\",\"version\":\"" + รุ่น + "\",\"checksum\":\"" + เช็คซัม + "\"}")
}

// ตรวจว่าไฟล์เป็น archive ที่ build แล้ว: gzip (1f 8b) หรือ zip (PK) และไม่ว่าง
ฟังก์ชัน อาร์ติแฟกต์ตรวจ(เส้นทาง) {
    ถ้า file_exists(เส้นทาง) == เท็จ {
        คืน เท็จ
    }
    ผูก มายา = file_magic(เส้นทาง)
    ถ้า มายา == "gzip" {
        คืน จริง
    }
    ถ้า มายา == "zip" {
        คืน จริง
    }
    คืน เท็จ
}

// POST /api/v1/packages/suspend  (form: name)  — เจ้าของหรือกุญแจของเจ้าของ
ฟังก์ชัน ทำระงับ(คำขอ) {
    ผูก กุญแจ = ดึงกุญแจ(คำขอ)
    ผูก ไอดีผู้ใช้ = กุญแจตรวจ(กุญแจ)
    ถ้า ไอดีผู้ใช้ == 0 {
        คืน เจสัน(401, "{\"error\":\"invalid or missing API key\"}")
    }
    ผูก ชื่อ = query_param(คำขอ.body, "name", "")
    ผูก เจ้าของ = แพ็กเกจเจ้าของ(ชื่อ)
    ถ้า เจ้าของ != ไอดีผู้ใช้ {
        คืน เจสัน(403, "{\"error\":\"not your package\"}")
    }
    // สำรองถาวรก่อนระงับ (การสำรองยังอยู่แม้ระงับแล้ว)
    make_dir("storage/suspended-backup")
    ผูก รุ่นๆ = รุ่นของชื่อ(ชื่อ)
    ผูก ก = 0
    ขณะที่ ก < รุ่นๆ.len {
        ผูก ร = รับรายการ(รุ่นๆ, ก)
        ผูก ต้นทาง = "storage/packages/" + ชื่อ + "-" + ร.version + ".tgz"
        ถ้า file_exists(ต้นทาง) {
            copy_file(ต้นทาง, "storage/suspended-backup/" + ชื่อ + "-" + ร.version + ".tgz")
        }
        ผูก ก = ก + 1
    }
    แพ็กเกจระงับ(ชื่อ)
    คืน เจสัน(200, "{\"ok\":true,\"suspended\":\"" + ชื่อ + "\",\"backup\":\"permanent\"}")
}

ฟังก์ชัน เจสัน(สถานะ, เนื้อ) {
    คืน ตอบ(สถานะ, เนื้อ, "application/json")
}

← Back to index