6 puan yazan honglu 2025-01-08 | 2 yorum | WhatsApp'ta paylaş

"Kendi zevkime uygun, tip güvenli bir kütüphane yapalım" düşüncesiyle başlayan bir proje.

Bu proje, tip güvenli bir JSON Schema uygulamasıyla başladı ve geliştirme sürecinde ihtiyaç duyulan çeşitli araçlara doğal biçimde genişledi.

Şu anda iş arayışı nedeniyle ilk etapta buna bir nokta koymuş oldum.

Proje ilkeleri

Geliştirme sürecinde şu temel ilkelere bağlı kalındı:

  • Katı tip sisteminden yararlanma
  • Dış bağımlılıkları asgari düzeyde tutma
  • Yeniden kullanılabilir tip sistemi tasarlama
  • API dokümantasyonu
  • Yüksek test kapsamını koruma
  • Saf TypeScript implementasyonu

Kütüphaneler

@imhonglu/json-schema

JSON Schema 2020-12 draft spesifikasyonuna uyan bir TypeScript implementasyonudur.

[IMG] demo-1

import { Schema, SchemaDefinition } from "@imhonglu/json-schema";  
  
export const Address = new Schema({  
  type: "object",  
  properties: {  
    street: { type: "string" },  
    city: { type: "string" },  
    zip: { type: "string" },  
  },  
  required: ["street"] as const,  
});  
  
export type Address = SchemaDefinition.Instance<typeof Address>;  
// {  
//   street: string;  
//   city?: string;  
//   zip?: string;  
// }  

@imhonglu/format

JSON Schema'nın format anahtar sözcüğünü uygulamak için başlatılmış bir projedir.

import { FullTime } from '@imhonglu/format';  
  
const time = FullTime.parse('00:00:00.000Z');  
// { hour: 0, minute: 0, second: 0, secfrac: '.000', offset: undefined }  
  
console.log(time.toString()); // '00:00:00.000Z'  
console.log(JSON.stringify(time)); // '"00:00:00.000Z"'  
  
const result = FullTime.safeParse('invalid');  
if (!result.ok) {  
  console.error(result.error);  
}  

@imhonglu/pattern-builder

RFC spesifikasyonlarındaki ABNF dil bilgisini uygularken regex'in okunabilirliğini artırmak için oluşturulmuş bir regex builder'dır.

import { characterSet, concat, hexDigit } from "@imhonglu/pattern-builder";  
  
// pct-encoded = "%" HEXDIG HEXDIG  
export const pctEncoded = concat(  
  "%",  
  hexDigit.clone().exact(2),  
);  
  
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"  
export const unreserved = characterSet(  
  alpha,  
  digit,  
  /[\-._~]/,  
);  

@imhonglu/type-guard

Tip guard'ların okunabilirliğini artırmak için oluşturulmuş bir type guard kütüphanesidir.

import { composeGuards } from "@imhonglu/type-guard";  
  
const is = composeGuards({  
  string: (value: unknown): value is string => typeof value === "string",  
  number: (value: unknown): value is number => typeof value === "number"  
});  
  
is.string("hello"); // true  
is.not.string(42);  // true  
  
let value: string | number | undefined;  
  
if (is.number(value)) {  
  value.toFixed(2); // 'value' is number  
}  
  
if (is.not.number(value)) {  
  value.toFixed(2); // error: Property 'toFixed' does not exist on type 'undefined'.  
}  

@imhonglu/type-object

Yerel Object API'si için tip güvenli bir wrapper kütüphanesidir. Yerel davranışa yakın tipler sunar.

import * as TypeObject from '@imhonglu/type-object';  
  
const data = { a: 1, b: 2, c: 3 };  
for (const key of TypeObject.keys(data)) {  
  // key: "a" | "b" | "c"  
  console.log(data[key]); // number  
}  
  
const string = 'hello';  
for (const index of TypeObject.keys(string)) {  
  // index: number & keyof string  
  console.log(string[index]); // string  
}  

@imhonglu/toolkit

Proje içinde kullanılan utility type ve utility function'ların bir koleksiyonudur.

import type { Fn } from '@imhonglu/toolkit';  
  
// Fonksiyon tipi '(...args: any[]) => any' için bir tip takma adı sunar.  
Fn.Callable // (...args: any[]) => any  
  
// Generic aracılığıyla yalnızca argüman türlerini tanımlayabilirsiniz.  
Fn.Callable<{ args: [number, number] }> // (...args: [number, number]) => any  
  
// Generic aracılığıyla yalnızca dönüş türünü tanımlayabilirsiniz.  
Fn.Callable<{ return: string }> // (...args: any[]) => string  
  
// Generic aracılığıyla hem argüman türünü hem de dönüş türünü tanımlayabilirsiniz.  
Fn.Callable<{ args: [number, number], return: string }> // (...args: [number, number]) => string  

Gelecek planları ve iş arayışı

Devam eden projenin bir sonraki aşamasında JSON Schema spesifikasyonu implementasyonunu tamamlayıp
bir backend framework yazmak istiyorum.

Şu anda iş arıyorum; ilginizi bekliyorum.
Okuduğunuz için teşekkür ederim.

Mutlu bir gün dilerim!

2 yorum

 
jjpark78 2025-01-09

Bu tarafta zod diye çok güçlü bir seçenek olduğu için üründe onu kullanıyoruz, ama ilginçmiş.

 
honglu 2025-01-09

ajv, typia, zod gibi mevcut projeler benim de ilgiyle takip ettiğim projeler.

@imhonglu/format içindeki safeParse da zod API'sinden etkilenmiş bir özellik.

İlginiz için teşekkür ederim!