From 10b29e1f781b55b901a667f20328b56c479e2738 Mon Sep 17 00:00:00 2001 From: Fityan Date: Thu, 9 May 2024 14:32:21 +0700 Subject: [PATCH] docs: add usage examples (#166) --- examples/mysql/.env.example | 5 + examples/mysql/.gitignore | 1 + examples/mysql/README.md | 24 + examples/mysql/db/migration.ts | 56 ++ examples/mysql/db/seeder.ts | 53 ++ examples/mysql/index.ts | 26 + examples/mysql/package.json | 22 + examples/mysql/utils/db.ts | 13 + examples/mysql/utils/env.ts | 14 + examples/postgres/.env.example | 5 + examples/postgres/.gitignore | 1 + examples/postgres/README.md | 24 + examples/postgres/db/migration.ts | 55 ++ examples/postgres/db/seeder.ts | 38 + examples/postgres/index.ts | 26 + examples/postgres/package.json | 22 + examples/postgres/utils/db.ts | 14 + examples/postgres/utils/env.ts | 14 + examples/prisma/.env.exxample | 7 + examples/prisma/.gitignore | 2 + examples/prisma/README.md | 22 + examples/prisma/index.ts | 28 + .../20240509070623_init/migration.sql | 58 ++ .../prisma/migrations/migration_lock.toml | 3 + examples/prisma/package.json | 27 + examples/prisma/schema.prisma | 64 ++ examples/prisma/seed.ts | 32 + package-lock.json | 710 ++++++++++++++++++ package.json | 3 + 29 files changed, 1369 insertions(+) create mode 100644 examples/mysql/.env.example create mode 100644 examples/mysql/.gitignore create mode 100644 examples/mysql/README.md create mode 100644 examples/mysql/db/migration.ts create mode 100644 examples/mysql/db/seeder.ts create mode 100644 examples/mysql/index.ts create mode 100644 examples/mysql/package.json create mode 100644 examples/mysql/utils/db.ts create mode 100644 examples/mysql/utils/env.ts create mode 100644 examples/postgres/.env.example create mode 100644 examples/postgres/.gitignore create mode 100644 examples/postgres/README.md create mode 100644 examples/postgres/db/migration.ts create mode 100644 examples/postgres/db/seeder.ts create mode 100644 examples/postgres/index.ts create mode 100644 examples/postgres/package.json create mode 100644 examples/postgres/utils/db.ts create mode 100644 examples/postgres/utils/env.ts create mode 100644 examples/prisma/.env.exxample create mode 100644 examples/prisma/.gitignore create mode 100644 examples/prisma/README.md create mode 100644 examples/prisma/index.ts create mode 100644 examples/prisma/migrations/20240509070623_init/migration.sql create mode 100644 examples/prisma/migrations/migration_lock.toml create mode 100644 examples/prisma/package.json create mode 100644 examples/prisma/schema.prisma create mode 100644 examples/prisma/seed.ts diff --git a/examples/mysql/.env.example b/examples/mysql/.env.example new file mode 100644 index 0000000..bf2f991 --- /dev/null +++ b/examples/mysql/.env.example @@ -0,0 +1,5 @@ +DB_HOST=localhost +DB_PORT=3306 +DB_USERNAME= +DB_PASSWORD= +DB_NAME=idn_area diff --git a/examples/mysql/.gitignore b/examples/mysql/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/examples/mysql/.gitignore @@ -0,0 +1 @@ +.env diff --git a/examples/mysql/README.md b/examples/mysql/README.md new file mode 100644 index 0000000..586a2d0 --- /dev/null +++ b/examples/mysql/README.md @@ -0,0 +1,24 @@ +# idn-area-data with MySQL example + +This example shows how to use the `idn-area-data` package with MySQL using [`mysql2`](https://www.npmjs.com/package/mysql2) driver. + +Database migration and seeding are provided (see [`db/migration.ts`](./db/migration.ts) and [`db/seeder.ts`](./db/seeder.ts)). + +In the project directory, you can run: + +- Database migration: + + ```bash + npm run db:migrate + ``` + +- Database seeding: + + ```bash + npm run db:seed + ``` + +- Start the application: + ```bash + npm start + ``` diff --git a/examples/mysql/db/migration.ts b/examples/mysql/db/migration.ts new file mode 100644 index 0000000..2af95e4 --- /dev/null +++ b/examples/mysql/db/migration.ts @@ -0,0 +1,56 @@ +import { pool } from '../utils/db.js'; + +// Create tables +await pool.query(` + CREATE TABLE IF NOT EXISTS provinces ( + code VARCHAR(2), + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code) + ); +`); + +await pool.query(` + CREATE TABLE IF NOT EXISTS regencies ( + code VARCHAR(5), + province_code VARCHAR(2) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (province_code) REFERENCES provinces(code) + ); +`); + +await pool.query(` + CREATE TABLE IF NOT EXISTS districts ( + code VARCHAR(8), + regency_code VARCHAR(5) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (regency_code) REFERENCES regencies(code) + ); +`); + +await pool.query(` + CREATE TABLE IF NOT EXISTS villages ( + code VARCHAR(13), + district_code VARCHAR(8) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (district_code) REFERENCES districts(code) + ); +`); + +await pool.query(` + CREATE TABLE IF NOT EXISTS islands ( + code VARCHAR(11), + regency_code VARCHAR(5), + name VARCHAR(255) NOT NULL, + coordinate VARCHAR(255) NOT NULL, + is_outermost_small BOOLEAN NOT NULL, + is_populated BOOLEAN NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (regency_code) REFERENCES regencies(code) + ); +`); + +console.log('Migration successful'); +pool.end(); diff --git a/examples/mysql/db/seeder.ts b/examples/mysql/db/seeder.ts new file mode 100644 index 0000000..dd89f93 --- /dev/null +++ b/examples/mysql/db/seeder.ts @@ -0,0 +1,53 @@ +import { + getProvinces, + getRegencies, + getDistricts, + getVillages, + getIslands, +} from 'idn-area-data'; +import { pool } from '../utils/db.js'; + +await pool.query('INSERT INTO provinces (code, name) VALUES ?', [ + (await getProvinces()).map((province) => [province.code, province.name]), +]); + +await pool.query('INSERT INTO regencies (code, province_code, name) VALUES ?', [ + (await getRegencies({ transform: true })).map((regency) => [ + regency.code, + regency.provinceCode, + regency.name, + ]), +]); + +await pool.query('INSERT INTO districts (code, regency_code, name) VALUES ?', [ + (await getDistricts({ transform: true })).map((district) => [ + district.code, + district.regencyCode, + district.name, + ]), +]); + +await pool.query('INSERT INTO villages (code, district_code, name) VALUES ?', [ + (await getVillages({ transform: true })).map((village) => [ + village.code, + village.districtCode, + village.name, + ]), +]); + +await pool.query( + 'INSERT INTO islands (code, regency_code, name, coordinate, is_outermost_small, is_populated) VALUES ?', + [ + (await getIslands({ transform: true })).map((island) => [ + island.code, + island.regencyCode, + island.name, + island.coordinate, + island.isOutermostSmall, + island.isPopulated, + ]), + ], +); + +console.log('Seeding successful'); +pool.end(); diff --git a/examples/mysql/index.ts b/examples/mysql/index.ts new file mode 100644 index 0000000..8766630 --- /dev/null +++ b/examples/mysql/index.ts @@ -0,0 +1,26 @@ +import { pool } from './utils/db.js'; + +// After migration and seeding, you can query the database. For example: +// Get all provinces with count of regencies, districts, villages, and islands +const timeStart = performance.now(); +const [result] = await pool.query(` + SELECT + provinces.code AS province_code, + provinces.name AS province_name, + COUNT(DISTINCT regencies.code) AS regency_count, + COUNT(DISTINCT districts.code) AS district_count, + COUNT(DISTINCT villages.code) AS village_count, + COUNT(DISTINCT islands.code) AS island_count + FROM provinces + LEFT JOIN regencies ON regencies.province_code = provinces.code + LEFT JOIN districts ON districts.regency_code = regencies.code + LEFT JOIN villages ON villages.district_code = districts.code + LEFT JOIN islands ON islands.regency_code = regencies.code + GROUP BY provinces.code +`); +const timeEnd = performance.now(); + +console.log(`Query executed in ${timeEnd - timeStart}ms`); +console.table(result); + +pool.end(); diff --git a/examples/mysql/package.json b/examples/mysql/package.json new file mode 100644 index 0000000..712e1a6 --- /dev/null +++ b/examples/mysql/package.json @@ -0,0 +1,22 @@ +{ + "name": "idn-area-data-usage-example", + "version": "1.0.0", + "description": "Example of using idn-area-data with MySQL", + "main": "index.js", + "type": "module", + "scripts": { + "db:migrate": "tsx db/migration.ts", + "db:seed": "tsx db/seeder.ts", + "start": "tsx index.ts" + }, + "devDependencies": { + "idn-area-data": "^3.1.1", + "tsx": "^4.9.3", + "typescript": "^5.4.5" + }, + "dependencies": { + "dotenv": "^16.4.5", + "mysql2": "^3.9.7", + "zod": "^3.23.7" + } +} diff --git a/examples/mysql/utils/db.ts b/examples/mysql/utils/db.ts new file mode 100644 index 0000000..8236d5a --- /dev/null +++ b/examples/mysql/utils/db.ts @@ -0,0 +1,13 @@ +import mysql from 'mysql2/promise'; +import env from './env.js'; + +/** + * MySQL database pool + */ +export const pool = mysql.createPool({ + host: env.DB_HOST, + port: env.DB_PORT, + user: env.DB_USERNAME, + password: env.DB_PASSWORD, + database: env.DB_NAME, +}); diff --git a/examples/mysql/utils/env.ts b/examples/mysql/utils/env.ts new file mode 100644 index 0000000..b1b7675 --- /dev/null +++ b/examples/mysql/utils/env.ts @@ -0,0 +1,14 @@ +import 'dotenv/config'; +import { z } from 'zod'; + +const envSchema = z + .object({ + DB_HOST: z.string(), + DB_PORT: z.coerce.number(), + DB_USERNAME: z.string(), + DB_PASSWORD: z.string(), + DB_NAME: z.string(), + }) + .required(); + +export default envSchema.parse(process.env); diff --git a/examples/postgres/.env.example b/examples/postgres/.env.example new file mode 100644 index 0000000..8f2bc5d --- /dev/null +++ b/examples/postgres/.env.example @@ -0,0 +1,5 @@ +DB_HOST=localhost +DB_PORT=5432 +DB_USERNAME= +DB_PASSWORD= +DB_NAME=idn_area diff --git a/examples/postgres/.gitignore b/examples/postgres/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/examples/postgres/.gitignore @@ -0,0 +1 @@ +.env diff --git a/examples/postgres/README.md b/examples/postgres/README.md new file mode 100644 index 0000000..c90b4a8 --- /dev/null +++ b/examples/postgres/README.md @@ -0,0 +1,24 @@ +# idn-area-data with PostgreSQL example + +This example shows how to use the `idn-area-data` package with PostgreSQL using [`postgres`](https://www.npmjs.com/package/postgres) driver. + +Database migration and seeding are provided (see [`db/migration.ts`](./db/migration.ts) and [`db/seeder.ts`](./db/seeder.ts)). + +In the project directory, you can run: + +- Database migration: + + ```bash + npm run db:migrate + ``` + +- Database seeding: + + ```bash + npm run db:seed + ``` + +- Start the application: + ```bash + npm start + ``` diff --git a/examples/postgres/db/migration.ts b/examples/postgres/db/migration.ts new file mode 100644 index 0000000..86229f1 --- /dev/null +++ b/examples/postgres/db/migration.ts @@ -0,0 +1,55 @@ +import { sql } from '../utils/db.js'; + +await sql` + CREATE TABLE IF NOT EXISTS provinces ( + code VARCHAR(2), + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code) + ) +`; + +await sql` + CREATE TABLE IF NOT EXISTS regencies ( + code VARCHAR(5), + province_code VARCHAR(2) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (province_code) REFERENCES provinces(code) + ) +`; + +await sql` + CREATE TABLE IF NOT EXISTS districts ( + code VARCHAR(8), + regency_code VARCHAR(5) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (regency_code) REFERENCES regencies(code) + ) +`; + +await sql` + CREATE TABLE IF NOT EXISTS villages ( + code VARCHAR(13), + district_code VARCHAR(8) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (district_code) REFERENCES districts(code) + ) +`; + +await sql` + CREATE TABLE IF NOT EXISTS islands ( + code VARCHAR(11), + regency_code VARCHAR(5) DEFAULT NULL, + name VARCHAR(255) NOT NULL, + coordinate VARCHAR(255) NOT NULL, + is_outermost_small BOOLEAN NOT NULL, + is_populated BOOLEAN NOT NULL, + PRIMARY KEY (code), + FOREIGN KEY (regency_code) REFERENCES regencies(code) + ) +`; + +sql.end(); +console.log('Migration completed'); diff --git a/examples/postgres/db/seeder.ts b/examples/postgres/db/seeder.ts new file mode 100644 index 0000000..33f2e78 --- /dev/null +++ b/examples/postgres/db/seeder.ts @@ -0,0 +1,38 @@ +import { + getDistricts, + getIslands, + getProvinces, + getRegencies, + getVillages, +} from 'idn-area-data'; +import { sql } from '../utils/db.js'; + +// Insert provinces +await sql`INSERT INTO provinces ${sql(await getProvinces())};`; + +// Insert regencies +await sql`INSERT INTO regencies ${sql(await getRegencies({ transform: true }))};`; + +// Insert districts +await sql`INSERT INTO districts ${sql(await getDistricts({ transform: true }))};`; + +const BATCH_SIZE = 1000; + +// Insert villages in batch +const villages = await getVillages({ transform: true }); + +for (let i = 0; i < villages.length; i += BATCH_SIZE) { + const batch = villages.slice(i, i + BATCH_SIZE); + await sql`INSERT INTO villages ${sql(batch)};`; +} + +// Insert islands in batch +const islands = await getIslands({ transform: true }); + +for (let i = 0; i < islands.length; i += BATCH_SIZE) { + const batch = islands.slice(i, i + BATCH_SIZE); + await sql`INSERT INTO islands ${sql(batch)};`; +} + +sql.end(); +console.log('Seed completed'); diff --git a/examples/postgres/index.ts b/examples/postgres/index.ts new file mode 100644 index 0000000..bb08ea1 --- /dev/null +++ b/examples/postgres/index.ts @@ -0,0 +1,26 @@ +import { sql } from './utils/db.js'; + +// After migration and seeding, you can query the database. For example: +// Get all provinces with count of regencies, districts, villages, and islands +const timeStart = performance.now(); +const result = await sql` + SELECT + provinces.code AS province_code, + provinces.name AS province_name, + COUNT(DISTINCT regencies.code) AS regency_count, + COUNT(DISTINCT districts.code) AS district_count, + COUNT(DISTINCT villages.code) AS village_count, + COUNT(DISTINCT islands.code) AS island_count + FROM provinces + LEFT JOIN regencies ON regencies.province_code = provinces.code + LEFT JOIN districts ON districts.regency_code = regencies.code + LEFT JOIN villages ON villages.district_code = districts.code + LEFT JOIN islands ON islands.regency_code = regencies.code + GROUP BY provinces.code +`; +const timeEnd = performance.now(); + +console.log(`Query executed in ${timeEnd - timeStart}ms`); +console.table(result); + +sql.end(); diff --git a/examples/postgres/package.json b/examples/postgres/package.json new file mode 100644 index 0000000..78d108b --- /dev/null +++ b/examples/postgres/package.json @@ -0,0 +1,22 @@ +{ + "name": "idn-area-data-usage-postgres", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "db:migrate": "tsx db/migration.ts", + "db:seed": "tsx db/seeder.ts", + "start": "tsx index.ts" + }, + "devDependencies": { + "idn-area-data": "^3.1.1", + "tsx": "^4.9.3", + "typescript": "^5.4.5" + }, + "dependencies": { + "dotenv": "^16.4.5", + "postgres": "^3.4.4", + "zod": "^3.23.8" + } +} diff --git a/examples/postgres/utils/db.ts b/examples/postgres/utils/db.ts new file mode 100644 index 0000000..ceaac7d --- /dev/null +++ b/examples/postgres/utils/db.ts @@ -0,0 +1,14 @@ +import postgres from 'postgres'; +import env from './env.js'; + +/** + * Postgres database + */ +export const sql = postgres({ + host: env.DB_HOST, + port: env.DB_PORT, + user: env.DB_USERNAME, + password: env.DB_PASSWORD, + database: env.DB_NAME, + transform: postgres.fromCamel, // Convert camelCase property names to snake_case database column names +}); diff --git a/examples/postgres/utils/env.ts b/examples/postgres/utils/env.ts new file mode 100644 index 0000000..b1b7675 --- /dev/null +++ b/examples/postgres/utils/env.ts @@ -0,0 +1,14 @@ +import 'dotenv/config'; +import { z } from 'zod'; + +const envSchema = z + .object({ + DB_HOST: z.string(), + DB_PORT: z.coerce.number(), + DB_USERNAME: z.string(), + DB_PASSWORD: z.string(), + DB_NAME: z.string(), + }) + .required(); + +export default envSchema.parse(process.env); diff --git a/examples/prisma/.env.exxample b/examples/prisma/.env.exxample new file mode 100644 index 0000000..5445d98 --- /dev/null +++ b/examples/prisma/.env.exxample @@ -0,0 +1,7 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public" diff --git a/examples/prisma/.gitignore b/examples/prisma/.gitignore new file mode 100644 index 0000000..37d7e73 --- /dev/null +++ b/examples/prisma/.gitignore @@ -0,0 +1,2 @@ +node_modules +.env diff --git a/examples/prisma/README.md b/examples/prisma/README.md new file mode 100644 index 0000000..8938913 --- /dev/null +++ b/examples/prisma/README.md @@ -0,0 +1,22 @@ +# idn-area-data with PostgreSQL example + +This example shows how to use the `idn-area-data` package with PostgreSQL database using [`Prisma` ORM](https://www.prisma.io/docs). + +In the project directory, you can run: + +- Database migration: + + ```bash + npm run db:migrate + ``` + +- Database seeding: + + ```bash + npm run db:seed + ``` + +- Start the application: + ```bash + npm start + ``` diff --git a/examples/prisma/index.ts b/examples/prisma/index.ts new file mode 100644 index 0000000..c9f4261 --- /dev/null +++ b/examples/prisma/index.ts @@ -0,0 +1,28 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +// You will write your Prisma Client queries here. For example: +// Get all provinces with count of regencies, districts, villages, and islands +const timeStart = performance.now(); +const result = await prisma.$queryRaw` + SELECT + provinces.code AS province_code, + provinces.name AS province_name, + COUNT(DISTINCT regencies.code) AS regency_count, + COUNT(DISTINCT districts.code) AS district_count, + COUNT(DISTINCT villages.code) AS village_count, + COUNT(DISTINCT islands.code) AS island_count + FROM provinces + LEFT JOIN regencies ON regencies.province_code = provinces.code + LEFT JOIN districts ON districts.regency_code = regencies.code + LEFT JOIN villages ON villages.district_code = districts.code + LEFT JOIN islands ON islands.regency_code = regencies.code + GROUP BY provinces.code +`; +const timeEnd = performance.now(); + +console.log(`Query executed in ${timeEnd - timeStart}ms`); +console.table(result); + +await prisma.$disconnect(); diff --git a/examples/prisma/migrations/20240509070623_init/migration.sql b/examples/prisma/migrations/20240509070623_init/migration.sql new file mode 100644 index 0000000..3d84e15 --- /dev/null +++ b/examples/prisma/migrations/20240509070623_init/migration.sql @@ -0,0 +1,58 @@ +-- CreateTable +CREATE TABLE "provinces" ( + "code" VARCHAR(2) NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "provinces_pkey" PRIMARY KEY ("code") +); + +-- CreateTable +CREATE TABLE "regencies" ( + "code" VARCHAR(5) NOT NULL, + "province_code" VARCHAR(2) NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "regencies_pkey" PRIMARY KEY ("code") +); + +-- CreateTable +CREATE TABLE "districts" ( + "code" VARCHAR(8) NOT NULL, + "regency_code" VARCHAR(5) NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "districts_pkey" PRIMARY KEY ("code") +); + +-- CreateTable +CREATE TABLE "villages" ( + "code" VARCHAR(13) NOT NULL, + "district_code" VARCHAR(8) NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "villages_pkey" PRIMARY KEY ("code") +); + +-- CreateTable +CREATE TABLE "islands" ( + "code" VARCHAR(11) NOT NULL, + "regency_code" VARCHAR(5), + "name" TEXT NOT NULL, + "coordinate" TEXT NOT NULL, + "is_outermost_small" BOOLEAN NOT NULL, + "is_populated" BOOLEAN NOT NULL, + + CONSTRAINT "islands_pkey" PRIMARY KEY ("code") +); + +-- AddForeignKey +ALTER TABLE "regencies" ADD CONSTRAINT "regencies_province_code_fkey" FOREIGN KEY ("province_code") REFERENCES "provinces"("code") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "districts" ADD CONSTRAINT "districts_regency_code_fkey" FOREIGN KEY ("regency_code") REFERENCES "regencies"("code") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "villages" ADD CONSTRAINT "villages_district_code_fkey" FOREIGN KEY ("district_code") REFERENCES "districts"("code") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "islands" ADD CONSTRAINT "islands_regency_code_fkey" FOREIGN KEY ("regency_code") REFERENCES "regencies"("code") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/examples/prisma/migrations/migration_lock.toml b/examples/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/examples/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/examples/prisma/package.json b/examples/prisma/package.json new file mode 100644 index 0000000..487bd92 --- /dev/null +++ b/examples/prisma/package.json @@ -0,0 +1,27 @@ +{ + "name": "idn-area-data-with-prisma", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "prisma:generate": "prisma generate", + "db:migrate": "prisma migrate dev", + "db:rollback": "prisma migrate reset", + "db:seed": "prisma db seed", + "start": "tsx index.ts" + }, + "prisma": { + "schema": "schema.prisma", + "seed": "tsx seed.ts" + }, + "dependencies": { + "@prisma/client": "^5.13.0" + }, + "devDependencies": { + "idn-area-data": "^3.1.1", + "prisma": "^5.13.0", + "tsx": "^4.9.3", + "typescript": "^5.4.5" + } +} diff --git a/examples/prisma/schema.prisma b/examples/prisma/schema.prisma new file mode 100644 index 0000000..b1e56ea --- /dev/null +++ b/examples/prisma/schema.prisma @@ -0,0 +1,64 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model Province { + code String @id @db.VarChar(2) + name String + regencies Regency[] + + @@map("provinces") +} + +model Regency { + code String @id @db.VarChar(5) + provinceCode String @map("province_code") @db.VarChar(2) + name String + province Province @relation(fields: [provinceCode], references: [code]) + districts District[] + islands Island[] + + @@map("regencies") +} + +model District { + code String @id @db.VarChar(8) + regencyCode String @map("regency_code") @db.VarChar(5) + name String + regency Regency @relation(fields: [regencyCode], references: [code]) + villages Village[] + + @@map("districts") +} + +model Village { + code String @id @db.VarChar(13) + districtCode String @map("district_code") @db.VarChar(8) + name String + district District @relation(fields: [districtCode], references: [code]) + + @@map("villages") +} + +model Island { + code String @id @db.VarChar(11) + regencyCode String? @map("regency_code") @db.VarChar(5) + name String + coordinate String + isOutermostSmall Boolean @map("is_outermost_small") + isPopulated Boolean @map("is_populated") + regency Regency? @relation(fields: [regencyCode], references: [code]) + + @@map("islands") +} diff --git a/examples/prisma/seed.ts b/examples/prisma/seed.ts new file mode 100644 index 0000000..1ea693a --- /dev/null +++ b/examples/prisma/seed.ts @@ -0,0 +1,32 @@ +import { PrismaClient } from '@prisma/client'; +import { + getDistricts, + getIslands, + getProvinces, + getRegencies, + getVillages, +} from 'idn-area-data'; + +const prisma = new PrismaClient(); + +await prisma.province.createMany({ + data: await getProvinces(), +}); + +await prisma.regency.createMany({ + data: await getRegencies({ transform: true }), +}); + +await prisma.district.createMany({ + data: await getDistricts({ transform: true }), +}); + +await prisma.village.createMany({ + data: await getVillages({ transform: true }), +}); + +await prisma.island.createMany({ + data: await getIslands({ transform: true }), +}); + +await prisma.$disconnect(); diff --git a/package-lock.json b/package-lock.json index 548bf61..cc4a5e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "idn-area-data", "version": "3.1.1", "license": "MIT", + "workspaces": [ + "./examples/*" + ], "dependencies": { "papaparse": "^5.4.1" }, @@ -31,6 +34,47 @@ "url": "https://github.com/sponsors/fityannugroho" } }, + "examples/mysql": { + "name": "idn-area-data-usage-example", + "version": "1.0.0", + "dependencies": { + "dotenv": "^16.4.5", + "mysql2": "^3.9.7", + "zod": "^3.23.7" + }, + "devDependencies": { + "idn-area-data": "^3.1.1", + "tsx": "^4.9.3", + "typescript": "^5.4.5" + } + }, + "examples/postgres": { + "name": "idn-area-data-usage-postgres", + "version": "1.0.0", + "dependencies": { + "dotenv": "^16.4.5", + "postgres": "^3.4.4", + "zod": "^3.23.8" + }, + "devDependencies": { + "idn-area-data": "^3.1.1", + "tsx": "^4.9.3", + "typescript": "^5.4.5" + } + }, + "examples/prisma": { + "name": "idn-area-data-with-prisma", + "version": "1.0.0", + "dependencies": { + "@prisma/client": "^5.13.0" + }, + "devDependencies": { + "idn-area-data": "^3.1.1", + "prisma": "^5.13.0", + "tsx": "^4.9.3", + "typescript": "^5.4.5" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -664,6 +708,68 @@ "node": ">= 8" } }, + "node_modules/@prisma/client": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.13.0.tgz", + "integrity": "sha512-uYdfpPncbZ/syJyiYBwGZS8Gt1PTNoErNYMuqHDa2r30rNSFtgTA/LXsSk55R7pdRTMi5pHkeP9B14K6nHmwkg==", + "hasInstallScript": true, + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.13.0.tgz", + "integrity": "sha512-699iqlEvzyCj9ETrXhs8o8wQc/eVW+FigSsHpiskSFydhjVuwTJEfj/nIYqTaWFYuxiWQRfm3r01meuW97SZaQ==", + "devOptional": true + }, + "node_modules/@prisma/engines": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.13.0.tgz", + "integrity": "sha512-hIFLm4H1boj6CBZx55P4xKby9jgDTeDG0Jj3iXtwaaHmlD5JmiDkZhh8+DYWkTGchu+rRF36AVROLnk0oaqhHw==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/debug": "5.13.0", + "@prisma/engines-version": "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b", + "@prisma/fetch-engine": "5.13.0", + "@prisma/get-platform": "5.13.0" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b.tgz", + "integrity": "sha512-AyUuhahTINGn8auyqYdmxsN+qn0mw3eg+uhkp8zwknXYIqoT3bChG4RqNY/nfDkPvzWAPBa9mrDyBeOnWSgO6A==", + "devOptional": true + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.13.0.tgz", + "integrity": "sha512-Yh4W+t6YKyqgcSEB3odBXt7QyVSm0OQlBSldQF2SNXtmOgMX8D7PF/fvH6E6qBCpjB/yeJLy/FfwfFijoHI6sA==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.13.0", + "@prisma/engines-version": "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b", + "@prisma/get-platform": "5.13.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.13.0.tgz", + "integrity": "sha512-B/WrQwYTzwr7qCLifQzYOmQhZcFmIFhR81xC45gweInSUn2hTEbfKUPd2keAog+y5WI5xLAFNJ3wkXplvSVkSw==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.13.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.14.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz", @@ -1600,6 +1706,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -1633,6 +1747,17 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/esbuild": { "version": "0.19.8", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.8.tgz", @@ -2041,6 +2166,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -2062,6 +2195,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-tsconfig": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.4.tgz", + "integrity": "sha512-ofbkKj+0pjXjhejr007J/fLf+sW+8H7K5GCm+msC8q3IpvgjobpyPqSRFemNyIMxklC0zeJpi7VDFna19FacvQ==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2159,6 +2304,44 @@ "node": ">=10.17.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idn-area-data": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/idn-area-data/-/idn-area-data-3.1.1.tgz", + "integrity": "sha512-70KqGmV1Bpa8Rjy4pMk3iJs4w9QLedOMRY3wKV7Jicnp5nVBaadzbOK40F4el7YZ2AYQvpJ2PUJJWBy8N2uxlg==", + "dev": true, + "dependencies": { + "papaparse": "^5.4.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/fityannugroho" + } + }, + "node_modules/idn-area-data-usage-example": { + "resolved": "examples/mysql", + "link": true + }, + "node_modules/idn-area-data-usage-postgres": { + "resolved": "examples/postgres", + "link": true + }, + "node_modules/idn-area-data-with-prisma": { + "resolved": "examples/prisma", + "link": true + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2260,6 +2443,11 @@ "node": ">=8" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2432,6 +2620,11 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", @@ -2555,6 +2748,32 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mysql2": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.7.tgz", + "integrity": "sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw==", + "dependencies": { + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "engines": { + "node": ">=16.14" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -2566,6 +2785,25 @@ "thenify-all": "^1.0.0" } }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -2839,6 +3077,18 @@ } } }, + "node_modules/postgres": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.4.tgz", + "integrity": "sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/porsager" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2889,6 +3139,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/prisma": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.13.0.tgz", + "integrity": "sha512-kGtcJaElNRAdAGsCNykFSZ7dBKpL14Cbs+VaQ8cECxQlRPDjBlMHNFYeYt0SKovAVy2Y65JXQwB3A5+zIQwnTg==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "5.13.0" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -2945,6 +3211,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3027,6 +3302,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -3042,6 +3322,11 @@ "node": ">=10" } }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3093,6 +3378,14 @@ "node": ">=0.10.0" } }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3396,6 +3689,415 @@ "node": ">= 8" } }, + "node_modules/tsx": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.9.3.tgz", + "integrity": "sha512-czVbetlILiyJZI5zGlj2kw9vFiSeyra9liPD4nG+Thh4pKTi0AmMEQ8zdV/L2xbIVKrIqif4sUNrsMAOksx9Zg==", + "dev": true, + "dependencies": { + "esbuild": "~0.20.2", + "get-tsconfig": "^4.7.3" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4235,6 +4937,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 3aaa11e..bfca7da 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,9 @@ "data", "lib" ], + "workspaces": [ + "./examples/*" + ], "scripts": { "test": "vitest run", "test:watch": "vitest",