From 87d7813b20b800b8e3ce0f9fe5c792d521dd9efa Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 07:38:41 +0100 Subject: [PATCH 01/16] Bootstrapped browser package --- browser/package.json | 26 ++++++++++++++++++++++++++ pnpm-lock.yaml | 2 ++ pnpm-workspace.yaml | 1 + ui/.keep | 0 4 files changed, 29 insertions(+) create mode 100644 browser/package.json delete mode 100644 ui/.keep diff --git a/browser/package.json b/browser/package.json new file mode 100644 index 00000000..f073e738 --- /dev/null +++ b/browser/package.json @@ -0,0 +1,26 @@ +{ + "name": "@dpkit/browser", + "type": "module", + "version": "0.0.0-dev", + "exports": "./build/index.js", + "sideEffects": false, + "license": "MIT", + "author": "Evgeny Karev", + "repository": "https://github.com/datisthq/dpkit", + "description": "Fast TypeScript data management framework built on top of the Data Package standard and Polars DataFrames", + "keywords": [ + "data", + "polars", + "dataframe", + "datapackage", + "tableschema", + "typescript", + "validation", + "quality", + "fair", + "browser" + ], + "scripts": { + "build": "tsc" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 365963e3..1b79bbea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -188,6 +188,8 @@ importers: specifier: workspace:* version: link:../test + browser: {} + ckan: dependencies: '@dpkit/core': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0d5269ec..aa13de15 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ dangerouslyAllowAllBuilds: true packages: - app - arrow + - browser - ckan - cli - core diff --git a/ui/.keep b/ui/.keep deleted file mode 100644 index e69de29b..00000000 From b556e5697447fe1a59fac4ff77bf4d87fa150c8e Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 07:40:03 +0100 Subject: [PATCH 02/16] Bootstrapped service package --- browser/README.md | 3 + browser/package.json | 1 + pnpm-lock.yaml | 193 +++++++++++++++++++++++++- pnpm-workspace.yaml | 1 + service/README.md | 3 + service/endpoints/package/validate.ts | 8 ++ service/logger.ts | 9 ++ service/main.ts | 0 service/package.json | 34 +++++ 9 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 browser/README.md create mode 100644 service/README.md create mode 100644 service/endpoints/package/validate.ts create mode 100644 service/logger.ts create mode 100644 service/main.ts create mode 100644 service/package.json diff --git a/browser/README.md b/browser/README.md new file mode 100644 index 00000000..d99e6749 --- /dev/null +++ b/browser/README.md @@ -0,0 +1,3 @@ +# @dpkit/browser + +dpkit is a fast data management framework built on top of the Data Package standard and Polars DataFrames. It supports various formats like CSV, JSON, and Parquet and integrates with data platforms such as CKAN, Zenodo, and GitHub. For more information, please visit the [documentation portal](https://dpkit.dev). diff --git a/browser/package.json b/browser/package.json index f073e738..442607c5 100644 --- a/browser/package.json +++ b/browser/package.json @@ -2,6 +2,7 @@ "name": "@dpkit/browser", "type": "module", "version": "0.0.0-dev", + "private": true, "exports": "./build/index.js", "sideEffects": false, "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b79bbea..8a8f8b40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,7 +121,7 @@ importers: version: 3.2.0(prop-types@15.8.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) remix-utils: specifier: 9.0.0 - version: 9.0.0(@oslojs/encoding@1.1.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0) + version: 9.0.0(@oslojs/encoding@1.1.0)(@standard-schema/spec@1.0.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0) ts-extras: specifier: ^0.14.0 version: 0.14.0 @@ -634,6 +634,24 @@ importers: specifier: workspace:* version: link:../test + service: + dependencies: + '@dpkit/lib': + specifier: workspace:* + version: link:../lib + '@loglayer/transport-tslog': + specifier: ^3.0.4 + version: 3.0.4(tslog@4.10.2) + '@orpc/server': + specifier: ^1.10.0 + version: 1.10.0(crossws@0.3.5)(ws@8.18.3) + loglayer: + specifier: 6.9.1 + version: 6.9.1 + tslog: + specifier: ^4.10.2 + version: 4.10.2 + site: devDependencies: '@astrojs/starlight': @@ -1673,6 +1691,12 @@ packages: resolution: {integrity: sha512-KT8ic1wWstCKOjZNR6Vqpk9rK7PPx/QPjGhfqePGYjo6l9R94mSHry+zdtYjIrIPvQHbnzsp/wd6lj6IvD3MvQ==} engines: {node: '>=18'} + '@loglayer/transport-tslog@3.0.4': + resolution: {integrity: sha512-ifF4vFVOb7nc9uGdI103B1MyFeSMw1YzEV4KbxcbkO8Bxt2ppxMpNC4LQj+jnoYmYNAC5k7NDn2BQB2TfwCWHw==} + engines: {node: '>=18'} + peerDependencies: + tslog: '*' + '@loglayer/transport@2.3.4': resolution: {integrity: sha512-SHvaex987nfqV9hNj/KEMEnE7SwtDa5YwxqXbZNEtWDSWimn6agHyce73/qJC86GVrtOJmLj2HMii9JdKeZozw==} engines: {node: '>=18'} @@ -1850,6 +1874,49 @@ packages: '@octokit/types@15.0.0': resolution: {integrity: sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ==} + '@orpc/client@1.10.0': + resolution: {integrity: sha512-5KDvC5eoZ3hCtn4lrWthXAXe+cV4UtWuAO96nRoMfJLBvGwARKbhK6mKZYq7xJuaRqpByzCAhbYAY5BNRxOK8Q==} + + '@orpc/contract@1.10.0': + resolution: {integrity: sha512-hbpYOTZBaA6dMY+Uo+xvfKCCX/2PCx4VWS4s5XT3vzrY5QocrNSFzqa7MwNXkAmJJVCYYJhd0vlur6K2n58gfw==} + + '@orpc/interop@1.10.0': + resolution: {integrity: sha512-8PHHb3IRzSWNhfeOjtcwTZD4BUsJMPsuRQpMTt1n2fwvcvupodtMPASg4LNK19dY+IZp8nuCxFhUutnBUuIDjA==} + + '@orpc/server@1.10.0': + resolution: {integrity: sha512-6aNHQaGG3nhByGezXcrns74f0kyTi0Cz0aDcH8DR7tsKtcxhADrNKVy5o3hz/gDvFU0eX8FGV41Fl750a8URyw==} + peerDependencies: + crossws: '>=0.3.4' + ws: '>=8.18.1' + peerDependenciesMeta: + crossws: + optional: true + ws: + optional: true + + '@orpc/shared@1.10.0': + resolution: {integrity: sha512-YzTcoM3fImeIqx+uelNrZGhQX88t+YHvaZSe3p05t4ZRkOOjxvfrx9gv9ivHPpZ3RI12Qc/GXWzcst99fD0/AQ==} + peerDependencies: + '@opentelemetry/api': '>=1.9.0' + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + + '@orpc/standard-server-aws-lambda@1.10.0': + resolution: {integrity: sha512-ScVS4wciV++8AfLXlBBt85IfSKk8RpCsmUQVAXBTXW63YE/8YDQOIaf0NZLtIfKsN8ZI+UCwahg/Yf/a6L7pNQ==} + + '@orpc/standard-server-fetch@1.10.0': + resolution: {integrity: sha512-cERB8pPOKtqqsykmIw/TxIEoJsqIROlpBXj2LFO5iPJ5gwso0QhDhBmiaOUj9Cz+xigjIHBJvzWWokyO+mVbZw==} + + '@orpc/standard-server-node@1.10.0': + resolution: {integrity: sha512-/JO4+gPL8ULycRuQI2mzmOT8WbWHvOThXv8RsarJD7/trrG0y/3k4YWY5mZFg7XMkUu+E8apOeUrlwi2SL1mqg==} + + '@orpc/standard-server-peer@1.10.0': + resolution: {integrity: sha512-km8lTZeykmvSmM8tcnH+eiZUfHCWSG061bXDyau7FJUoyFvYWVoHKbPzYDsoje9iU0BLDyDo37HHInqQ5bHiUA==} + + '@orpc/standard-server@1.10.0': + resolution: {integrity: sha512-VX+0PIivl+fdxhHqsKMAjBVOUg65bXD2QBnOZE73KVxFPfWs++h+E8GO9KvhBqQbmHO0tQl1gnHqIqd9ICGuPA==} + '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} @@ -2425,6 +2492,9 @@ packages: '@speed-highlight/core@1.2.7': resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} engines: {node: '>=14'} @@ -4743,6 +4813,9 @@ packages: oniguruma-to-es@4.3.3: resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + p-each-series@3.0.0: resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} engines: {node: '>=12'} @@ -5069,6 +5142,10 @@ packages: resolution: {integrity: sha512-fG4L8TlD1CacJiGMGPxM1/K8l/GaKL2eFQZ6DWAjxZYxSf07DkumbC/Mhh+u/NHvxkfQVL25By0pxBS8QE9ZrQ==} engines: {node: '>=18'} + radash@12.1.1: + resolution: {integrity: sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA==} + engines: {node: '>=14.18.0'} + radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} @@ -5715,6 +5792,10 @@ packages: tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + temp-dir@3.0.0: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} @@ -5814,6 +5895,10 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tslog@4.10.2: + resolution: {integrity: sha512-XuELoRpMR+sq8fuWwX7P0bcj+PRNiicOKDEb3fGNURhxWVyykCi9BNq7c4uVz7h7P0sj8qgBsr5SWS6yBClq3g==} + engines: {node: '>=16'} + tsx@4.20.3: resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==} engines: {node: '>=18.0.0'} @@ -5831,6 +5916,10 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-fest@5.1.0: + resolution: {integrity: sha512-wQ531tuWvB6oK+pchHIu5lHe5f5wpSCqB8Kf4dWQRbOYc9HTge7JL0G4Qd44bh6QuJCccIzL3bugb8GI0MwHrg==} + engines: {node: '>=20'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -7312,6 +7401,11 @@ snapshots: '@loglayer/shared@2.5.3': {} + '@loglayer/transport-tslog@3.0.4(tslog@4.10.2)': + dependencies: + '@loglayer/transport': 2.3.4 + tslog: 4.10.2 + '@loglayer/transport@2.3.4': dependencies: '@loglayer/shared': 2.5.3 @@ -7528,6 +7622,86 @@ snapshots: dependencies: '@octokit/openapi-types': 26.0.0 + '@orpc/client@1.10.0': + dependencies: + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + '@orpc/standard-server-fetch': 1.10.0 + '@orpc/standard-server-peer': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/contract@1.10.0': + dependencies: + '@orpc/client': 1.10.0 + '@orpc/shared': 1.10.0 + '@standard-schema/spec': 1.0.0 + openapi-types: 12.1.3 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/interop@1.10.0': {} + + '@orpc/server@1.10.0(crossws@0.3.5)(ws@8.18.3)': + dependencies: + '@orpc/client': 1.10.0 + '@orpc/contract': 1.10.0 + '@orpc/interop': 1.10.0 + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + '@orpc/standard-server-aws-lambda': 1.10.0 + '@orpc/standard-server-fetch': 1.10.0 + '@orpc/standard-server-node': 1.10.0 + '@orpc/standard-server-peer': 1.10.0 + cookie: 1.0.2 + optionalDependencies: + crossws: 0.3.5 + ws: 8.18.3 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/shared@1.10.0': + dependencies: + radash: 12.1.1 + type-fest: 5.1.0 + + '@orpc/standard-server-aws-lambda@1.10.0': + dependencies: + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + '@orpc/standard-server-fetch': 1.10.0 + '@orpc/standard-server-node': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/standard-server-fetch@1.10.0': + dependencies: + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/standard-server-node@1.10.0': + dependencies: + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + '@orpc/standard-server-fetch': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/standard-server-peer@1.10.0': + dependencies: + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/standard-server@1.10.0': + dependencies: + '@orpc/shared': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + '@oslojs/encoding@1.1.0': {} '@pagefind/darwin-arm64@1.4.0': @@ -8108,6 +8282,8 @@ snapshots: '@speed-highlight/core@1.2.7': {} + '@standard-schema/spec@1.0.0': {} + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -10849,6 +11025,8 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 + openapi-types@12.1.3: {} + p-each-series@3.0.0: {} p-filter@4.1.0: @@ -11141,6 +11319,8 @@ snapshots: quick-lru@7.2.0: {} + radash@12.1.1: {} + radix3@1.1.2: {} range-parser@1.2.1: {} @@ -11446,11 +11626,12 @@ snapshots: transitivePeerDependencies: - supports-color - remix-utils@9.0.0(@oslojs/encoding@1.1.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0): + remix-utils@9.0.0(@oslojs/encoding@1.1.0)(@standard-schema/spec@1.0.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0): dependencies: type-fest: 4.41.0 optionalDependencies: '@oslojs/encoding': 1.1.0 + '@standard-schema/spec': 1.0.0 react: 19.2.0 react-router: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -11951,6 +12132,8 @@ snapshots: tabbable@6.2.0: {} + tagged-tag@1.0.0: {} + temp-dir@3.0.0: {} tempy@3.1.0: @@ -12030,6 +12213,8 @@ snapshots: tslib@2.8.1: {} + tslog@4.10.2: {} + tsx@4.20.3: dependencies: esbuild: 0.25.10 @@ -12044,6 +12229,10 @@ snapshots: type-fest@4.41.0: {} + type-fest@5.1.0: + dependencies: + tagged-tag: 1.0.0 + type-is@1.6.18: dependencies: media-typer: 0.3.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index aa13de15..bd347c47 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -21,6 +21,7 @@ packages: - markdown - ods - parquet + - service - site - table - test diff --git a/service/README.md b/service/README.md new file mode 100644 index 00000000..aa77dbad --- /dev/null +++ b/service/README.md @@ -0,0 +1,3 @@ +# @dpkit/service + +dpkit is a fast data management framework built on top of the Data Package standard and Polars DataFrames. It supports various formats like CSV, JSON, and Parquet and integrates with data platforms such as CKAN, Zenodo, and GitHub. For more information, please visit the [documentation portal](https://dpkit.dev). diff --git a/service/endpoints/package/validate.ts b/service/endpoints/package/validate.ts new file mode 100644 index 00000000..1c822b7f --- /dev/null +++ b/service/endpoints/package/validate.ts @@ -0,0 +1,8 @@ +import * as dpkit from "@dpkit/lib" + +export async function validatePackage( + source: Parameters[0], +) { + const result = await dpkit.validatePackage(source) + return result +} diff --git a/service/logger.ts b/service/logger.ts new file mode 100644 index 00000000..64f73aff --- /dev/null +++ b/service/logger.ts @@ -0,0 +1,9 @@ +import { TsLogTransport } from "@loglayer/transport-tslog" +import { LogLayer } from "loglayer" +import { Logger } from "tslog" + +export const logger = new LogLayer({ + transport: new TsLogTransport({ + logger: new Logger(), + }), +}) diff --git a/service/main.ts b/service/main.ts new file mode 100644 index 00000000..e69de29b diff --git a/service/package.json b/service/package.json new file mode 100644 index 00000000..cd202706 --- /dev/null +++ b/service/package.json @@ -0,0 +1,34 @@ +{ + "name": "@dpkit/service", + "type": "module", + "version": "0.0.0-dev", + "private": true, + "exports": "./build/index.js", + "sideEffects": false, + "license": "MIT", + "author": "Evgeny Karev", + "repository": "https://github.com/datisthq/dpkit", + "description": "Fast TypeScript data management framework built on top of the Data Package standard and Polars DataFrames", + "keywords": [ + "data", + "polars", + "dataframe", + "datapackage", + "tableschema", + "typescript", + "validation", + "quality", + "fair", + "service" + ], + "scripts": { + "build": "tsc" + }, + "dependencies": { + "@dpkit/lib": "workspace:*", + "@loglayer/transport-tslog": "^3.0.4", + "@orpc/server": "^1.10.0", + "loglayer": "6.9.1", + "tslog": "^4.10.2" + } +} From 3a10e206379c88beaeed993371a794fa07f44a53 Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 08:43:10 +0100 Subject: [PATCH 03/16] Rebased on openapi/scalar --- pnpm-lock.yaml | 91 +++++++++++++++++++++++ service/endpoints/package/validate.ts | 19 +++-- service/index.ts | 1 + service/main.ts | 22 ++++++ service/package.json | 5 +- service/router.ts | 7 ++ service/sandbox.ts | 1 + service/server.ts | 103 ++++++++++++++++++++++++++ service/settings.ts | 1 + service/tsconfig.json | 3 + 10 files changed, 246 insertions(+), 7 deletions(-) create mode 100644 service/index.ts create mode 100644 service/router.ts create mode 100644 service/sandbox.ts create mode 100644 service/server.ts create mode 100644 service/settings.ts create mode 100644 service/tsconfig.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a8f8b40..ad9b7a1d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -642,15 +642,24 @@ importers: '@loglayer/transport-tslog': specifier: ^3.0.4 version: 3.0.4(tslog@4.10.2) + '@orpc/openapi': + specifier: ^1.10.0 + version: 1.10.0(crossws@0.3.5)(ws@8.18.3) '@orpc/server': specifier: ^1.10.0 version: 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/zod': + specifier: ^1.10.0 + version: 1.10.0(@orpc/contract@1.10.0)(@orpc/server@1.10.0(crossws@0.3.5)(ws@8.18.3))(crossws@0.3.5)(ws@8.18.3)(zod@4.1.12) loglayer: specifier: 6.9.1 version: 6.9.1 tslog: specifier: ^4.10.2 version: 4.10.2 + zod: + specifier: ^4.1.12 + version: 4.1.12 site: devDependencies: @@ -1883,6 +1892,15 @@ packages: '@orpc/interop@1.10.0': resolution: {integrity: sha512-8PHHb3IRzSWNhfeOjtcwTZD4BUsJMPsuRQpMTt1n2fwvcvupodtMPASg4LNK19dY+IZp8nuCxFhUutnBUuIDjA==} + '@orpc/json-schema@1.10.0': + resolution: {integrity: sha512-zEytOUTa52pYlIW768MsGQYRmUvD3HRcPSSKf/2FVBL0dg2fZqnDpel909YW/d2vjJcDae0+jLvdesCmxaZKjg==} + + '@orpc/openapi-client@1.10.0': + resolution: {integrity: sha512-6QgE9yfO/g3dmGRh2Rfe1f+oRqJgmcrrZR3dEfD9LU8Hvv2/VKZfNgBGUVGbSsvEV9pDK4y1mwuQaun/Nd8ldA==} + + '@orpc/openapi@1.10.0': + resolution: {integrity: sha512-YXHCRjN+pA+VSH4v3FdqavBEJVJycpjBJq1j6x5lyRAG22aP9faGbRshRC8mNi2Br3B93CCoWGLL6TYnkjHcvQ==} + '@orpc/server@1.10.0': resolution: {integrity: sha512-6aNHQaGG3nhByGezXcrns74f0kyTi0Cz0aDcH8DR7tsKtcxhADrNKVy5o3hz/gDvFU0eX8FGV41Fl750a8URyw==} peerDependencies: @@ -1917,6 +1935,13 @@ packages: '@orpc/standard-server@1.10.0': resolution: {integrity: sha512-VX+0PIivl+fdxhHqsKMAjBVOUg65bXD2QBnOZE73KVxFPfWs++h+E8GO9KvhBqQbmHO0tQl1gnHqIqd9ICGuPA==} + '@orpc/zod@1.10.0': + resolution: {integrity: sha512-2uYIkClwjQGrYc1S7m8QDX6mf+BlCgmeHboCfhIY6DZcKTvnqmksZ5blq6bM0Y24FxpQSw3Cc6JqU7zKYXDTrw==} + peerDependencies: + '@orpc/contract': 1.10.0 + '@orpc/server': 1.10.0 + zod: '>=3.25.0' + '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} @@ -5454,6 +5479,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rou3@0.7.8: + resolution: {integrity: sha512-21X/el5fdOaEsqwl3an/d9kpZ8hshVIyrwFCpsoleJ4ccAGRbN+PVoxyXzWXkHDxfMkVnLe4yzx+imz2qoem2Q==} + route-recognizer@0.3.4: resolution: {integrity: sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==} @@ -6375,6 +6403,9 @@ packages: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} + wildcard-match@5.1.4: + resolution: {integrity: sha512-wldeCaczs8XXq7hj+5d/F38JE2r7EXgb6WQDM84RVwxy81T/sxB5e9+uZLK9Q9oNz1mlvjut+QtvgaOQFPVq/g==} + wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} @@ -6531,6 +6562,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zustand@5.0.8: resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} engines: {node: '>=12.20.0'} @@ -7642,6 +7676,42 @@ snapshots: '@orpc/interop@1.10.0': {} + '@orpc/json-schema@1.10.0(crossws@0.3.5)(ws@8.18.3)': + dependencies: + '@orpc/contract': 1.10.0 + '@orpc/interop': 1.10.0 + '@orpc/openapi': 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/server': 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/shared': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + - crossws + - ws + + '@orpc/openapi-client@1.10.0': + dependencies: + '@orpc/client': 1.10.0 + '@orpc/contract': 1.10.0 + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + transitivePeerDependencies: + - '@opentelemetry/api' + + '@orpc/openapi@1.10.0(crossws@0.3.5)(ws@8.18.3)': + dependencies: + '@orpc/client': 1.10.0 + '@orpc/contract': 1.10.0 + '@orpc/interop': 1.10.0 + '@orpc/openapi-client': 1.10.0 + '@orpc/server': 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/shared': 1.10.0 + '@orpc/standard-server': 1.10.0 + rou3: 0.7.8 + transitivePeerDependencies: + - '@opentelemetry/api' + - crossws + - ws + '@orpc/server@1.10.0(crossws@0.3.5)(ws@8.18.3)': dependencies: '@orpc/client': 1.10.0 @@ -7702,6 +7772,21 @@ snapshots: transitivePeerDependencies: - '@opentelemetry/api' + '@orpc/zod@1.10.0(@orpc/contract@1.10.0)(@orpc/server@1.10.0(crossws@0.3.5)(ws@8.18.3))(crossws@0.3.5)(ws@8.18.3)(zod@4.1.12)': + dependencies: + '@orpc/contract': 1.10.0 + '@orpc/json-schema': 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/openapi': 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/server': 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/shared': 1.10.0 + escape-string-regexp: 5.0.0 + wildcard-match: 5.1.4 + zod: 4.1.12 + transitivePeerDependencies: + - '@opentelemetry/api' + - crossws + - ws + '@oslojs/encoding@1.1.0': {} '@pagefind/darwin-arm64@1.4.0': @@ -11710,6 +11795,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.52.4 fsevents: 2.3.3 + rou3@0.7.8: {} + route-recognizer@0.3.4: {} safe-buffer@5.1.2: {} @@ -12613,6 +12700,8 @@ snapshots: dependencies: string-width: 7.2.0 + wildcard-match@5.1.4: {} + wordwrap@1.0.0: {} workerd@1.20251008.0: @@ -12749,6 +12838,8 @@ snapshots: zod@3.25.76: {} + zod@4.1.12: {} + zustand@5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0): optionalDependencies: '@types/react': 19.2.2 diff --git a/service/endpoints/package/validate.ts b/service/endpoints/package/validate.ts index 1c822b7f..6d76417c 100644 --- a/service/endpoints/package/validate.ts +++ b/service/endpoints/package/validate.ts @@ -1,8 +1,15 @@ import * as dpkit from "@dpkit/lib" +import { os } from "@orpc/server" +import * as z from "zod" -export async function validatePackage( - source: Parameters[0], -) { - const result = await dpkit.validatePackage(source) - return result -} +export const validatePackage = os + .input( + z.object({ + source: z.string(), + }), + ) + .handler(async ({ input }) => { + const { source } = input + const result = await dpkit.validatePackage(source) + return result + }) diff --git a/service/index.ts b/service/index.ts new file mode 100644 index 00000000..990400b1 --- /dev/null +++ b/service/index.ts @@ -0,0 +1 @@ +export type { router } from "./router.ts" diff --git a/service/main.ts b/service/main.ts index e69de29b..237da3cb 100644 --- a/service/main.ts +++ b/service/main.ts @@ -0,0 +1,22 @@ +import { createServer } from "node:http" +import { RPCHandler } from "@orpc/server/node" +import { logger } from "./logger.ts" +import { router } from "./router.ts" +import * as settings from "./settings.ts" + +const handler = new RPCHandler(router) + +const server = createServer(async (req, res) => { + const result = await handler.handle(req, res, { + context: { headers: req.headers }, + }) + + if (!result.matched) { + res.statusCode = 404 + res.end() + } +}) + +server.listen(settings.PORT, () => + logger.info(`Listening on port ${settings.PORT}`), +) diff --git a/service/package.json b/service/package.json index cd202706..c0a687bb 100644 --- a/service/package.json +++ b/service/package.json @@ -27,8 +27,11 @@ "dependencies": { "@dpkit/lib": "workspace:*", "@loglayer/transport-tslog": "^3.0.4", + "@orpc/openapi": "^1.10.0", "@orpc/server": "^1.10.0", + "@orpc/zod": "^1.10.0", "loglayer": "6.9.1", - "tslog": "^4.10.2" + "tslog": "^4.10.2", + "zod": "^4.1.12" } } diff --git a/service/router.ts b/service/router.ts new file mode 100644 index 00000000..6a736731 --- /dev/null +++ b/service/router.ts @@ -0,0 +1,7 @@ +import { validatePackage } from "./endpoints/package/validate.ts" + +export const router = { + planet: { + validatePackage, + }, +} diff --git a/service/sandbox.ts b/service/sandbox.ts new file mode 100644 index 00000000..ebf465a0 --- /dev/null +++ b/service/sandbox.ts @@ -0,0 +1 @@ +// TODO: Implement disposable sandbox with size limit control diff --git a/service/server.ts b/service/server.ts new file mode 100644 index 00000000..35765786 --- /dev/null +++ b/service/server.ts @@ -0,0 +1,103 @@ +import * as http from "node:http" +import { OpenAPIGenerator } from "@orpc/openapi" +import { OpenAPIHandler } from "@orpc/openapi/node" +import type { Router } from "@orpc/server" +import { CORSPlugin } from "@orpc/server/plugins" +import { ZodSmartCoercionPlugin, ZodToJsonSchemaConverter } from "@orpc/zod" +import metadata from "./package.json" with { type: "json" } +import * as settings from "./settings.ts" + +export function createServer( + router: Router, + options: { + protocol: "http" | "https" + host: string + port: number + prefix: `/${string}` + withCors: boolean + withSpec: boolean + }, +) { + const url = new URL( + options.prefix, + `${options.protocol}://${options.host}:${options.port}`, + ) + + const openAPIHandler = new OpenAPIHandler(router, { + plugins: [ + new ZodSmartCoercionPlugin(), + new CORSPlugin({ + allowMethods: options.withCors ? settings.CORS_METHODS : [], + }), + ], + }) + + const openAPIGenerator = new OpenAPIGenerator({ + schemaConverters: [new ZodToJsonSchemaConverter()], + }) + + return http.createServer(async (req, res) => { + const { matched } = await openAPIHandler.handle(req, res, { + prefix: options.prefix, + }) + + if (matched) { + return + } + + if (req.url === "/spec.json") { + const spec = await openAPIGenerator.generate(router, { + info: { + title: "dpkit Service", + version: metadata.version, + }, + servers: [{ url: url.toString() }], + security: [{ bearerAuth: [] }], + components: { + securitySchemes: { + bearerAuth: { + type: "http", + scheme: "bearer", + }, + }, + }, + }) + + res.writeHead(200, { "Content-Type": "application/json" }) + res.end(JSON.stringify(spec)) + return + } + + const html = ` + + + + dpkit Service + + + + + +
+ + + + + + ` + + res.writeHead(200, { "Content-Type": "text/html" }) + res.end(html) + }) +} diff --git a/service/settings.ts b/service/settings.ts new file mode 100644 index 00000000..1d09c69f --- /dev/null +++ b/service/settings.ts @@ -0,0 +1 @@ +export const CORS_METHODS = ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"] diff --git a/service/tsconfig.json b/service/tsconfig.json new file mode 100644 index 00000000..3c43903c --- /dev/null +++ b/service/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.json" +} From cd5238dcde4672dc0bac8422f92eaa3c7153b74b Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 10:43:38 +0100 Subject: [PATCH 04/16] Fixed server --- service/index.ts | 1 + service/main.ts | 22 ++++------- service/router.ts | 4 +- service/server.ts | 92 +++++++++++++++++++-------------------------- service/settings.ts | 4 ++ 5 files changed, 54 insertions(+), 69 deletions(-) diff --git a/service/index.ts b/service/index.ts index 990400b1..ddbccab2 100644 --- a/service/index.ts +++ b/service/index.ts @@ -1 +1,2 @@ export type { router } from "./router.ts" +export { createServer } from "./server.ts" diff --git a/service/main.ts b/service/main.ts index 237da3cb..90470f24 100644 --- a/service/main.ts +++ b/service/main.ts @@ -1,20 +1,14 @@ -import { createServer } from "node:http" -import { RPCHandler } from "@orpc/server/node" import { logger } from "./logger.ts" -import { router } from "./router.ts" +import { createServer } from "./server.ts" import * as settings from "./settings.ts" -const handler = new RPCHandler(router) - -const server = createServer(async (req, res) => { - const result = await handler.handle(req, res, { - context: { headers: req.headers }, - }) - - if (!result.matched) { - res.statusCode = 404 - res.end() - } +const server = createServer({ + protocol: settings.PROTOCOL, + host: settings.HOST, + port: settings.PORT, + prefix: settings.PREFIX, + corsMethods: settings.CORS_METHODS, + withDocumentation: true, }) server.listen(settings.PORT, () => diff --git a/service/router.ts b/service/router.ts index 6a736731..cb90464d 100644 --- a/service/router.ts +++ b/service/router.ts @@ -1,7 +1,7 @@ import { validatePackage } from "./endpoints/package/validate.ts" export const router = { - planet: { - validatePackage, + package: { + validate: validatePackage, }, } diff --git a/service/server.ts b/service/server.ts index 35765786..1fea8a6f 100644 --- a/service/server.ts +++ b/service/server.ts @@ -1,23 +1,19 @@ import * as http from "node:http" import { OpenAPIGenerator } from "@orpc/openapi" import { OpenAPIHandler } from "@orpc/openapi/node" -import type { Router } from "@orpc/server" import { CORSPlugin } from "@orpc/server/plugins" import { ZodSmartCoercionPlugin, ZodToJsonSchemaConverter } from "@orpc/zod" import metadata from "./package.json" with { type: "json" } -import * as settings from "./settings.ts" +import { router } from "./router.ts" -export function createServer( - router: Router, - options: { - protocol: "http" | "https" - host: string - port: number - prefix: `/${string}` - withCors: boolean - withSpec: boolean - }, -) { +export function createServer(options: { + protocol: "http" | "https" + host: string + port: number + prefix: `/${string}` + corsMethods: string[] + withDocumentation: boolean +}) { const url = new URL( options.prefix, `${options.protocol}://${options.host}:${options.port}`, @@ -25,10 +21,8 @@ export function createServer( const openAPIHandler = new OpenAPIHandler(router, { plugins: [ + new CORSPlugin({ allowMethods: options.corsMethods }), new ZodSmartCoercionPlugin(), - new CORSPlugin({ - allowMethods: options.withCors ? settings.CORS_METHODS : [], - }), ], }) @@ -37,6 +31,8 @@ export function createServer( }) return http.createServer(async (req, res) => { + console.log(req.url) + const { matched } = await openAPIHandler.handle(req, res, { prefix: options.prefix, }) @@ -53,14 +49,6 @@ export function createServer( }, servers: [{ url: url.toString() }], security: [{ bearerAuth: [] }], - components: { - securitySchemes: { - bearerAuth: { - type: "http", - scheme: "bearer", - }, - }, - }, }) res.writeHead(200, { "Content-Type": "application/json" }) @@ -68,36 +56,34 @@ export function createServer( return } - const html = ` - - - - dpkit Service - - - - - -
+ if (req.url === "/") { + const html = ` + + + + dpkit Service + + + + + +
+ + + + + ` - - - - - ` + res.writeHead(200, { "Content-Type": "text/html" }) + res.end(html) + return + } - res.writeHead(200, { "Content-Type": "text/html" }) - res.end(html) + res.writeHead(404) + res.end() }) } diff --git a/service/settings.ts b/service/settings.ts index 1d09c69f..721bb752 100644 --- a/service/settings.ts +++ b/service/settings.ts @@ -1 +1,5 @@ +export const PORT = 8080 +export const HOST = "localhost" +export const PREFIX = "/api" +export const PROTOCOL = "http" export const CORS_METHODS = ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"] From 5a0cab79c9364847c11dcff08eaae32b80931ea0 Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 11:27:22 +0100 Subject: [PATCH 05/16] Added self-hosting docs --- docs/astro.config.ts | 1 - docs/components/Header/SiteTitle.astro | 59 -------------------------- docs/content/docs/guides/cloud.md | 33 ++++++++++++++ docs/content/docs/guides/service.md | 30 +++++++++++++ service/index.ts | 3 +- service/main.ts | 15 +------ service/server.ts | 56 ++++++++++++++++++------ service/settings.ts | 2 + 8 files changed, 110 insertions(+), 89 deletions(-) delete mode 100644 docs/components/Header/SiteTitle.astro create mode 100644 docs/content/docs/guides/cloud.md create mode 100644 docs/content/docs/guides/service.md diff --git a/docs/astro.config.ts b/docs/astro.config.ts index d3742118..0bd065f4 100644 --- a/docs/astro.config.ts +++ b/docs/astro.config.ts @@ -41,7 +41,6 @@ export default defineConfig({ "dpkit is a fast data management framework built on top of the Data Package standard and Polars DataFrames. It supports various formats like CSV, JSON, and Parquet and integrates with data platforms such as CKAN, Zenodo, and GitHub", customCss: ["/assets/styles.css"], components: { - SiteTitle: "./components/Header/SiteTitle.astro", SocialIcons: "./components/Header/SocialIcons.astro", }, logo: { diff --git a/docs/components/Header/SiteTitle.astro b/docs/components/Header/SiteTitle.astro deleted file mode 100644 index b98d3c36..00000000 --- a/docs/components/Header/SiteTitle.astro +++ /dev/null @@ -1,59 +0,0 @@ ---- -import config from "virtual:starlight/user-config" -import { logos } from "virtual:starlight/user-images" -const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute ---- - - - { - config.logo && logos.dark && ( - <> - {config.logo.alt} - {/* Show light alternate if a user configure both light and dark logos. */} - {!('src' in config.logo) && ( - {config.logo.alt} - )} - - ) - } - - {siteTitle} - - - - diff --git a/docs/content/docs/guides/cloud.md b/docs/content/docs/guides/cloud.md new file mode 100644 index 00000000..fa022afb --- /dev/null +++ b/docs/content/docs/guides/cloud.md @@ -0,0 +1,33 @@ +--- +title: Self-Hosting dpkit Cloud +sidebar: + label: dpkit Cloud + order: 11 +--- + +This document provides a brief overview of self-hosting [dpkit Cloud](https://cloud.dpkit.dev) on your own infrastructure. + +> [!TIP] +> dpkit Cloud is built on top of [Cloudflare Workers](https://workers.cloudflare.com/) but it is possible to use any other runtime that fits your needs e.g. Digital Ocean Apps or Docker. + +## Deployment + +1. Fork the [dpkit repository](https://github.com/datisthq/dpkit) to your GitHub account. +2. Clone the forked repository to your local machine. +3. Update the `wrangler.jsonc` with you application name e.g. `dpkit-cloud-custom`. +4. Setup a new CloudFlare worker with the following configuration: + - Name: e.g. `dpkit-cloud-custom` (should be the same as in `wrangler.jsonc`) + - Github repository: point to your forked repository + - Build command: `pnpm -F cloud build` + - Deploy command: `cd cloud && pnpm wrangler deploy` + - Branch deploy command: `cd cloud && pnpm wrangler versions upload` + - Variables ans secrets: `NODE_VERSION=24` +5. Push a new commit to your forked repository to trigger the build and deployment. + +## Usage + +Find a `workder.dev` subdomain in your CloudFlare dashboard and visit it in your browser or add a custom domain if it is desired. Now, you can use your custom dpkit Cloud the same way you use [dpkit Cloud](https://cloud.dpkit.dev). + +## Support + +We happy to help with a deployment of any complexity. Please [reach out to us to get a quote](https://www.linkedin.com/in/evgeny-karev/). diff --git a/docs/content/docs/guides/service.md b/docs/content/docs/guides/service.md new file mode 100644 index 00000000..5cd5a249 --- /dev/null +++ b/docs/content/docs/guides/service.md @@ -0,0 +1,30 @@ +--- +title: Self-Hosting dpkit Service +sidebar: + label: dpkit Service + order: 10 +--- + +This document provides a brief overview of self-hosting **dpkit Service** on your own infrastructure, a OpenAPI-compatible web-server powering [dpkit Cloud](https://cloud.dpkit.dev). + +## Instructions + +1. Install `@dpkit/service` package. +2. Within your project, create a `main.ts` file: + +```ts +import { createServer } from "@dpkit/service" + +createServer({ start: true }) +``` +``` +Listening on http://localhost:8080/api +``` + +## Usage + +Visit `http://localhost:8080` to see the OpenAPI documentation for using your service. You can use your new API as any other OpenAPI-compatible service. + +## Support + +We happy to help with a deployment of any complexity. Please [reach out to us to get a quote](https://www.linkedin.com/in/evgeny-karev/). diff --git a/service/index.ts b/service/index.ts index ddbccab2..ebb79d39 100644 --- a/service/index.ts +++ b/service/index.ts @@ -1,2 +1,3 @@ -export type { router } from "./router.ts" +export { router } from "./router.ts" +export { logger } from "./logger.ts" export { createServer } from "./server.ts" diff --git a/service/main.ts b/service/main.ts index 90470f24..368f6439 100644 --- a/service/main.ts +++ b/service/main.ts @@ -1,16 +1,3 @@ -import { logger } from "./logger.ts" import { createServer } from "./server.ts" -import * as settings from "./settings.ts" -const server = createServer({ - protocol: settings.PROTOCOL, - host: settings.HOST, - port: settings.PORT, - prefix: settings.PREFIX, - corsMethods: settings.CORS_METHODS, - withDocumentation: true, -}) - -server.listen(settings.PORT, () => - logger.info(`Listening on port ${settings.PORT}`), -) +createServer({ start: true }) diff --git a/service/server.ts b/service/server.ts index 1fea8a6f..735b839a 100644 --- a/service/server.ts +++ b/service/server.ts @@ -1,27 +1,47 @@ import * as http from "node:http" import { OpenAPIGenerator } from "@orpc/openapi" import { OpenAPIHandler } from "@orpc/openapi/node" +import type { Router } from "@orpc/server" import { CORSPlugin } from "@orpc/server/plugins" import { ZodSmartCoercionPlugin, ZodToJsonSchemaConverter } from "@orpc/zod" +import type { Logger } from "tslog" +import { logger } from "./logger.ts" import metadata from "./package.json" with { type: "json" } import { router } from "./router.ts" +import * as settings from "./settings.ts" -export function createServer(options: { - protocol: "http" | "https" - host: string - port: number - prefix: `/${string}` - corsMethods: string[] - withDocumentation: boolean +export function createServer(options?: { + start?: boolean + router?: Router + logger?: Logger + protocol?: "http" | "https" + host?: string + port?: number + prefix?: `/${string}` + corsMethods?: string[] + withDocumentation?: boolean }) { + const config = { + start: options?.start ?? settings.START, + router: options?.router ?? router, + logger: options?.logger ?? logger, + protocol: options?.protocol ?? settings.PROTOCOL, + host: options?.host ?? settings.HOST, + port: options?.port ?? settings.PORT, + prefix: options?.prefix ?? settings.PREFIX, + corsMethods: options?.corsMethods ?? settings.CORS_METHODS, + withDocumentation: + options?.withDocumentation ?? settings.WITH_DOCUMENTATION, + } + const url = new URL( - options.prefix, - `${options.protocol}://${options.host}:${options.port}`, + config.prefix, + `${config.protocol}://${config.host}:${config.port}`, ) - const openAPIHandler = new OpenAPIHandler(router, { + const openAPIHandler = new OpenAPIHandler(config.router, { plugins: [ - new CORSPlugin({ allowMethods: options.corsMethods }), + new CORSPlugin({ allowMethods: config.corsMethods }), new ZodSmartCoercionPlugin(), ], }) @@ -30,11 +50,11 @@ export function createServer(options: { schemaConverters: [new ZodToJsonSchemaConverter()], }) - return http.createServer(async (req, res) => { + const server = http.createServer(async (req, res) => { console.log(req.url) const { matched } = await openAPIHandler.handle(req, res, { - prefix: options.prefix, + prefix: config.prefix, }) if (matched) { @@ -42,7 +62,7 @@ export function createServer(options: { } if (req.url === "/spec.json") { - const spec = await openAPIGenerator.generate(router, { + const spec = await openAPIGenerator.generate(config.router, { info: { title: "dpkit Service", version: metadata.version, @@ -86,4 +106,12 @@ export function createServer(options: { res.writeHead(404) res.end() }) + + if (config.start) { + server.listen(config.port, () => + logger.info(`Listening on ${url.toString()}`), + ) + } + + return server } diff --git a/service/settings.ts b/service/settings.ts index 721bb752..07e376cf 100644 --- a/service/settings.ts +++ b/service/settings.ts @@ -1,5 +1,7 @@ +export const START = false export const PORT = 8080 export const HOST = "localhost" export const PREFIX = "/api" export const PROTOCOL = "http" export const CORS_METHODS = ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"] +export const WITH_DOCUMENTATION = true From 3697e1f6b26f5b3752c012abbe4bfd8a999cb768 Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 11:33:11 +0100 Subject: [PATCH 06/16] Updated self-hosting link --- app/locales/en.json | 4 ++-- app/routes/about/route.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/locales/en.json b/app/locales/en.json index 7d96d66e..a9f16fcb 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -97,9 +97,9 @@ "about-privacy-first-description": "dpkit Cloud is a competely open source project being under constant peer-review. The code is transparent and auditable, ensuring your data is never collected on our servers and remains accessible only to you during processing. dpkit Cloud does not collect your data or store your data after processing.", "about-self-hosting-title": "Self-hosting", "about-self-hosting-description": "dpkit Cloud is completely open source and can be self-hosted. Visit our GitHub repository to get started. For assistance with self-hosting or custom deployments, please get in touch with us.", - "about-github-repository": "GitHub repository", "about-get-in-touch": "get in touch with us", "about-description-intro": "dpkit Cloud provides free online privacy-first tools for converting and validating data. Unlike others, dpkit Cloud is free and completely", - "about-self-hosting-intro": "dpkit Cloud is completely open source and can be self-hosted. Visit our", + "about-self-hosting-docs": "the self-hosting documentation", + "about-self-hosting-intro": "dpkit Cloud is completely open source and can be self-hosted. Visit ", "about-self-hosting-middle": "to get started. For assistance with self-hosting or custom deployments, please" } diff --git a/app/routes/about/route.tsx b/app/routes/about/route.tsx index 58318247..d638c1c2 100644 --- a/app/routes/about/route.tsx +++ b/app/routes/about/route.tsx @@ -34,8 +34,8 @@ export default function Page(_props: Route.ComponentProps) { {t("about-self-hosting-title")} {t("about-self-hosting-intro")}{" "} - - {t("about-github-repository")} + + {t("about-self-hosting-docs")} {" "} {t("about-self-hosting-middle")}{" "} From e78976deeb14c4fe7839f03243082a66e0d4b69b Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 11:54:01 +0100 Subject: [PATCH 07/16] Updated dependencies --- app/package.json | 8 ++--- pnpm-lock.yaml | 70 ++++++++++++++++++-------------------------- service/package.json | 2 +- service/server.ts | 6 ++-- 4 files changed, 35 insertions(+), 51 deletions(-) diff --git a/app/package.json b/app/package.json index c124331b..33fd5ab6 100644 --- a/app/package.json +++ b/app/package.json @@ -14,14 +14,12 @@ "start": "react-router dev --port 4000 --host", "type": "tsc --noEmit" }, - "dependencies": { + "devDependencies": { "@cloudflare/containers": "0.0.28", - "@dpkit/lib": "workspace:*", "@mantine/core": "8.3.5", "@mantine/form": "8.3.5", "@mantine/hooks": "8.3.5", "@tanstack/react-query": "5.90.3", - "capnweb": "0.1.0", "es-toolkit": "1.39.10", "i18next": "25.6.0", "immer": "10.1.3", @@ -40,9 +38,7 @@ "ts-extras": "^0.14.0", "vaul": "1.1.2", "xml-js": "1.6.11", - "zustand": "5.0.8" - }, - "devDependencies": { + "zustand": "5.0.8", "@cloudflare/vite-plugin": "1.13.13", "@react-router/dev": "7.9.4", "@types/react": "19.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad9b7a1d..9a14ff40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,13 +55,13 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1) app: - dependencies: + devDependencies: '@cloudflare/containers': specifier: 0.0.28 version: 0.0.28 - '@dpkit/lib': - specifier: workspace:* - version: link:../lib + '@cloudflare/vite-plugin': + specifier: 1.13.13 + version: 1.13.13(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(workerd@1.20251008.0)(wrangler@4.43.0) '@mantine/core': specifier: 8.3.5 version: 8.3.5(@mantine/hooks@8.3.5(react@19.2.0))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -71,12 +71,18 @@ importers: '@mantine/hooks': specifier: 8.3.5 version: 8.3.5(react@19.2.0) + '@react-router/dev': + specifier: 7.9.4 + version: 7.9.4(@types/node@24.2.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(typescript@5.9.2)(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(wrangler@4.43.0)(yaml@2.8.1) '@tanstack/react-query': specifier: 5.90.3 version: 5.90.3(react@19.2.0) - capnweb: - specifier: 0.1.0 - version: 0.1.0 + '@types/react': + specifier: 19.2.2 + version: 19.2.2 + '@types/react-dom': + specifier: ^19.2.0 + version: 19.2.0(@types/react@19.2.2) es-toolkit: specifier: 1.39.10 version: 1.39.10 @@ -95,6 +101,15 @@ importers: lucide-react: specifier: 0.545.0 version: 0.545.0(react@19.2.0) + postcss: + specifier: 8.5.6 + version: 8.5.6 + postcss-preset-mantine: + specifier: 1.18.0 + version: 1.18.0(postcss@8.5.6) + postcss-simple-vars: + specifier: 7.0.1 + version: 7.0.1(postcss@8.5.6) react: specifier: 19.2.0 version: 19.2.0 @@ -128,34 +143,6 @@ importers: vaul: specifier: 1.1.2 version: 1.1.2(@types/react-dom@19.2.0(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - xml-js: - specifier: 1.6.11 - version: 1.6.11 - zustand: - specifier: 5.0.8 - version: 5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0) - devDependencies: - '@cloudflare/vite-plugin': - specifier: 1.13.13 - version: 1.13.13(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(workerd@1.20251008.0)(wrangler@4.43.0) - '@react-router/dev': - specifier: 7.9.4 - version: 7.9.4(@types/node@24.2.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(typescript@5.9.2)(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(wrangler@4.43.0)(yaml@2.8.1) - '@types/react': - specifier: 19.2.2 - version: 19.2.2 - '@types/react-dom': - specifier: ^19.2.0 - version: 19.2.0(@types/react@19.2.2) - postcss: - specifier: 8.5.6 - version: 8.5.6 - postcss-preset-mantine: - specifier: 1.18.0 - version: 1.18.0(postcss@8.5.6) - postcss-simple-vars: - specifier: 7.0.1 - version: 7.0.1(postcss@8.5.6) vite-plugin-devtools-json: specifier: 1.0.0 version: 1.0.0(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1)) @@ -165,6 +152,12 @@ importers: wrangler: specifier: 4.43.0 version: 4.43.0 + xml-js: + specifier: 1.6.11 + version: 1.6.11 + zustand: + specifier: 5.0.8 + version: 5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0) arrow: dependencies: @@ -635,7 +628,7 @@ importers: version: link:../test service: - dependencies: + devDependencies: '@dpkit/lib': specifier: workspace:* version: link:../lib @@ -2971,9 +2964,6 @@ packages: caniuse-lite@1.0.30001750: resolution: {integrity: sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==} - capnweb@0.1.0: - resolution: {integrity: sha512-+pygKx1JFTZTRdd1hHgaBRg5BwULEDZq8ZoHXkYP2GXNV3lrjXLj5qzlGz+SgBCJjWUmNBtlh7JPWdr0wIbY8w==} - ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -8938,8 +8928,6 @@ snapshots: caniuse-lite@1.0.30001750: {} - capnweb@0.1.0: {} - ccount@2.0.1: {} chai@5.3.3: diff --git a/service/package.json b/service/package.json index c0a687bb..96ed3e29 100644 --- a/service/package.json +++ b/service/package.json @@ -24,7 +24,7 @@ "scripts": { "build": "tsc" }, - "dependencies": { + "devDependencies": { "@dpkit/lib": "workspace:*", "@loglayer/transport-tslog": "^3.0.4", "@orpc/openapi": "^1.10.0", diff --git a/service/server.ts b/service/server.ts index 735b839a..0b4f7e72 100644 --- a/service/server.ts +++ b/service/server.ts @@ -61,7 +61,7 @@ export function createServer(options?: { return } - if (req.url === "/spec.json") { + if (req.url === `${config.prefix}/spec.json`) { const spec = await openAPIGenerator.generate(config.router, { info: { title: "dpkit Service", @@ -76,7 +76,7 @@ export function createServer(options?: { return } - if (req.url === "/") { + if (req.url === config.prefix) { const html = ` @@ -91,7 +91,7 @@ export function createServer(options?: { From fff0ede61c8b709813794691db5e6b717da8b81f Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 11:59:27 +0100 Subject: [PATCH 08/16] Renamed app to cloud --- {app => cloud}/Dockerfile | 2 +- {app => cloud}/README.md | 2 +- {app => cloud}/assets/about.png | Bin {app => cloud}/assets/logo.svg | 0 {app => cloud}/components/Alert/Alert.tsx | 0 .../components/Dialog/Dialog.module.css | 0 {app => cloud}/components/Dialog/Dialog.tsx | 0 {app => cloud}/components/Dialog/index.ts | 0 {app => cloud}/components/Form/Form.tsx | 0 {app => cloud}/components/Form/index.ts | 0 .../components/Layout/About.module.css | 0 {app => cloud}/components/Layout/About.tsx | 0 .../components/Layout/Banner.module.css | 0 {app => cloud}/components/Layout/Banner.tsx | 0 .../components/Layout/Breadcrumbs.tsx | 0 {app => cloud}/components/Layout/Content.tsx | 0 .../components/Layout/Footer.module.css | 0 {app => cloud}/components/Layout/Footer.tsx | 0 .../components/Layout/Header.module.css | 0 {app => cloud}/components/Layout/Header.tsx | 0 .../components/Layout/Language.module.css | 0 {app => cloud}/components/Layout/Language.tsx | 0 {app => cloud}/components/Layout/Layout.tsx | 0 .../components/Layout/Logo.module.css | 0 {app => cloud}/components/Layout/Logo.tsx | 0 {app => cloud}/components/Layout/Meta.tsx | 0 .../components/Layout/Navigation.tsx | 0 .../components/Layout/Repository.module.css | 0 .../components/Layout/Repository.tsx | 0 .../components/Layout/Share.module.css | 0 {app => cloud}/components/Layout/Share.tsx | 0 {app => cloud}/components/Layout/Sitemap.tsx | 0 .../components/Layout/Theme.module.css | 0 {app => cloud}/components/Layout/Theme.tsx | 0 {app => cloud}/components/Layout/index.ts | 0 .../components/Link/Link.module.css | 0 {app => cloud}/components/Link/Link.tsx | 0 {app => cloud}/components/Link/index.ts | 0 .../components/Report/Error/Cell.tsx | 0 .../components/Report/Error/Error.tsx | 0 .../components/Report/Error/Field.tsx | 0 .../components/Report/Error/Fields.tsx | 0 .../components/Report/Error/File.tsx | 0 .../components/Report/Error/Metadata.tsx | 0 .../components/Report/Error/Row.tsx | 0 {app => cloud}/components/Report/Report.tsx | 0 {app => cloud}/components/Report/index.ts | 0 .../components/Status/Status.module.css | 0 {app => cloud}/components/Status/Status.tsx | 0 {app => cloud}/components/Status/index.ts | 0 .../components/System/Error.module.css | 0 {app => cloud}/components/System/Error.tsx | 0 {app => cloud}/components/System/System.tsx | 0 {app => cloud}/components/System/context.ts | 0 {app => cloud}/components/System/index.ts | 0 {app => cloud}/components/System/selectors.ts | 0 {app => cloud}/constants/language.ts | 0 {app => cloud}/constants/page.ts | 0 {app => cloud}/helpers/context.ts | 0 {app => cloud}/helpers/link.ts | 0 {app => cloud}/helpers/media.ts | 0 {app => cloud}/helpers/platform.ts | 0 {app => cloud}/helpers/revision.ts | 0 {app => cloud}/helpers/rpc.ts | 0 {app => cloud}/helpers/store.ts | 0 {app => cloud}/i18n.ts | 0 {app => cloud}/icons.ts | 0 {app => cloud}/locales/de.json | 0 {app => cloud}/locales/en.json | 0 {app => cloud}/locales/es.json | 0 {app => cloud}/locales/fr.json | 0 {app => cloud}/locales/it.json | 0 {app => cloud}/locales/pt.json | 0 {app => cloud}/locales/ru.json | 0 {app => cloud}/locales/uk.json | 0 {app => cloud}/logger.ts | 0 {app => cloud}/main.ts | 0 {app => cloud}/package.json | 3 +- {app => cloud}/payload.ts | 0 {app => cloud}/postcss.config.ts | 0 {app => cloud}/public/favicon.png | Bin {app => cloud}/public/robots.txt | 0 {app => cloud}/react-router.config.ts | 0 {app => cloud}/routes/about/route.tsx | 0 {app => cloud}/routes/entry.client.tsx | 0 {app => cloud}/routes/entry.server.tsx | 0 {app => cloud}/routes/home/route.module.css | 0 {app => cloud}/routes/home/route.tsx | 0 .../routes/package/validate/Dialog.tsx | 0 .../routes/package/validate/Form.tsx | 0 .../routes/package/validate/queries.ts | 0 .../routes/package/validate/route.tsx | 0 .../routes/package/validate/services.ts | 0 .../routes/package/validate/store.ts | 0 {app => cloud}/routes/root.tsx | 0 {app => cloud}/routes/routes.ts | 0 {app => cloud}/routes/schema/infer/route.tsx | 0 {app => cloud}/routes/sitemap/page.ts | 0 {app => cloud}/routes/sitemap/root.ts | 0 {app => cloud}/routes/sitemap/services.ts | 0 .../routes/system/redirects/home.ts | 0 {app => cloud}/routes/table/convert/route.tsx | 0 .../routes/table/validate/route.tsx | 0 {app => cloud}/rpc.ts | 0 {app => cloud}/settings.ts | 0 {app => cloud}/styles/index.ts | 0 {app => cloud}/styles/main.css | 0 {app => cloud}/theme.ts | 0 {app => cloud}/tsconfig.json | 0 {app => cloud}/types/index.ts | 0 {app => cloud}/types/language.ts | 0 {app => cloud}/types/page.ts | 0 {app => cloud}/types/payload.ts | 0 {app => cloud}/types/rpc.ts | 0 {app => cloud}/vite.config.ts | 2 +- {app => cloud}/worker-configuration.d.ts | 0 {app => cloud}/wrangler.jsonc | 0 package.json | 2 +- pnpm-lock.yaml | 195 +++++++++--------- pnpm-workspace.yaml | 2 +- 120 files changed, 106 insertions(+), 102 deletions(-) rename {app => cloud}/Dockerfile (87%) rename {app => cloud}/README.md (95%) rename {app => cloud}/assets/about.png (100%) rename {app => cloud}/assets/logo.svg (100%) rename {app => cloud}/components/Alert/Alert.tsx (100%) rename {app => cloud}/components/Dialog/Dialog.module.css (100%) rename {app => cloud}/components/Dialog/Dialog.tsx (100%) rename {app => cloud}/components/Dialog/index.ts (100%) rename {app => cloud}/components/Form/Form.tsx (100%) rename {app => cloud}/components/Form/index.ts (100%) rename {app => cloud}/components/Layout/About.module.css (100%) rename {app => cloud}/components/Layout/About.tsx (100%) rename {app => cloud}/components/Layout/Banner.module.css (100%) rename {app => cloud}/components/Layout/Banner.tsx (100%) rename {app => cloud}/components/Layout/Breadcrumbs.tsx (100%) rename {app => cloud}/components/Layout/Content.tsx (100%) rename {app => cloud}/components/Layout/Footer.module.css (100%) rename {app => cloud}/components/Layout/Footer.tsx (100%) rename {app => cloud}/components/Layout/Header.module.css (100%) rename {app => cloud}/components/Layout/Header.tsx (100%) rename {app => cloud}/components/Layout/Language.module.css (100%) rename {app => cloud}/components/Layout/Language.tsx (100%) rename {app => cloud}/components/Layout/Layout.tsx (100%) rename {app => cloud}/components/Layout/Logo.module.css (100%) rename {app => cloud}/components/Layout/Logo.tsx (100%) rename {app => cloud}/components/Layout/Meta.tsx (100%) rename {app => cloud}/components/Layout/Navigation.tsx (100%) rename {app => cloud}/components/Layout/Repository.module.css (100%) rename {app => cloud}/components/Layout/Repository.tsx (100%) rename {app => cloud}/components/Layout/Share.module.css (100%) rename {app => cloud}/components/Layout/Share.tsx (100%) rename {app => cloud}/components/Layout/Sitemap.tsx (100%) rename {app => cloud}/components/Layout/Theme.module.css (100%) rename {app => cloud}/components/Layout/Theme.tsx (100%) rename {app => cloud}/components/Layout/index.ts (100%) rename {app => cloud}/components/Link/Link.module.css (100%) rename {app => cloud}/components/Link/Link.tsx (100%) rename {app => cloud}/components/Link/index.ts (100%) rename {app => cloud}/components/Report/Error/Cell.tsx (100%) rename {app => cloud}/components/Report/Error/Error.tsx (100%) rename {app => cloud}/components/Report/Error/Field.tsx (100%) rename {app => cloud}/components/Report/Error/Fields.tsx (100%) rename {app => cloud}/components/Report/Error/File.tsx (100%) rename {app => cloud}/components/Report/Error/Metadata.tsx (100%) rename {app => cloud}/components/Report/Error/Row.tsx (100%) rename {app => cloud}/components/Report/Report.tsx (100%) rename {app => cloud}/components/Report/index.ts (100%) rename {app => cloud}/components/Status/Status.module.css (100%) rename {app => cloud}/components/Status/Status.tsx (100%) rename {app => cloud}/components/Status/index.ts (100%) rename {app => cloud}/components/System/Error.module.css (100%) rename {app => cloud}/components/System/Error.tsx (100%) rename {app => cloud}/components/System/System.tsx (100%) rename {app => cloud}/components/System/context.ts (100%) rename {app => cloud}/components/System/index.ts (100%) rename {app => cloud}/components/System/selectors.ts (100%) rename {app => cloud}/constants/language.ts (100%) rename {app => cloud}/constants/page.ts (100%) rename {app => cloud}/helpers/context.ts (100%) rename {app => cloud}/helpers/link.ts (100%) rename {app => cloud}/helpers/media.ts (100%) rename {app => cloud}/helpers/platform.ts (100%) rename {app => cloud}/helpers/revision.ts (100%) rename {app => cloud}/helpers/rpc.ts (100%) rename {app => cloud}/helpers/store.ts (100%) rename {app => cloud}/i18n.ts (100%) rename {app => cloud}/icons.ts (100%) rename {app => cloud}/locales/de.json (100%) rename {app => cloud}/locales/en.json (100%) rename {app => cloud}/locales/es.json (100%) rename {app => cloud}/locales/fr.json (100%) rename {app => cloud}/locales/it.json (100%) rename {app => cloud}/locales/pt.json (100%) rename {app => cloud}/locales/ru.json (100%) rename {app => cloud}/locales/uk.json (100%) rename {app => cloud}/logger.ts (100%) rename {app => cloud}/main.ts (100%) rename {app => cloud}/package.json (95%) rename {app => cloud}/payload.ts (100%) rename {app => cloud}/postcss.config.ts (100%) rename {app => cloud}/public/favicon.png (100%) rename {app => cloud}/public/robots.txt (100%) rename {app => cloud}/react-router.config.ts (100%) rename {app => cloud}/routes/about/route.tsx (100%) rename {app => cloud}/routes/entry.client.tsx (100%) rename {app => cloud}/routes/entry.server.tsx (100%) rename {app => cloud}/routes/home/route.module.css (100%) rename {app => cloud}/routes/home/route.tsx (100%) rename {app => cloud}/routes/package/validate/Dialog.tsx (100%) rename {app => cloud}/routes/package/validate/Form.tsx (100%) rename {app => cloud}/routes/package/validate/queries.ts (100%) rename {app => cloud}/routes/package/validate/route.tsx (100%) rename {app => cloud}/routes/package/validate/services.ts (100%) rename {app => cloud}/routes/package/validate/store.ts (100%) rename {app => cloud}/routes/root.tsx (100%) rename {app => cloud}/routes/routes.ts (100%) rename {app => cloud}/routes/schema/infer/route.tsx (100%) rename {app => cloud}/routes/sitemap/page.ts (100%) rename {app => cloud}/routes/sitemap/root.ts (100%) rename {app => cloud}/routes/sitemap/services.ts (100%) rename {app => cloud}/routes/system/redirects/home.ts (100%) rename {app => cloud}/routes/table/convert/route.tsx (100%) rename {app => cloud}/routes/table/validate/route.tsx (100%) rename {app => cloud}/rpc.ts (100%) rename {app => cloud}/settings.ts (100%) rename {app => cloud}/styles/index.ts (100%) rename {app => cloud}/styles/main.css (100%) rename {app => cloud}/theme.ts (100%) rename {app => cloud}/tsconfig.json (100%) rename {app => cloud}/types/index.ts (100%) rename {app => cloud}/types/language.ts (100%) rename {app => cloud}/types/page.ts (100%) rename {app => cloud}/types/payload.ts (100%) rename {app => cloud}/types/rpc.ts (100%) rename {app => cloud}/vite.config.ts (85%) rename {app => cloud}/worker-configuration.d.ts (100%) rename {app => cloud}/wrangler.jsonc (100%) diff --git a/app/Dockerfile b/cloud/Dockerfile similarity index 87% rename from app/Dockerfile rename to cloud/Dockerfile index 4c70e45c..8b98debc 100644 --- a/app/Dockerfile +++ b/cloud/Dockerfile @@ -11,4 +11,4 @@ RUN pnpm install:ci RUN pnpm build EXPOSE 8080 -CMD ["node", "app/rpc.ts"] +CMD ["node", "cloud/rpc.ts"] diff --git a/app/README.md b/cloud/README.md similarity index 95% rename from app/README.md rename to cloud/README.md index 325fe3e9..fba11c2a 100644 --- a/app/README.md +++ b/cloud/README.md @@ -1,3 +1,3 @@ -# @dpkit/app +# @dpkit/cloud dpkit is a fast data management framework built on top of the Data Package standard and Polars DataFrames. It supports various formats like CSV, JSON, and Parquet and integrates with data platforms such as CKAN, Zenodo, and GitHub. For more information, please visit the [documentation portal](https://dpkit.dev). diff --git a/app/assets/about.png b/cloud/assets/about.png similarity index 100% rename from app/assets/about.png rename to cloud/assets/about.png diff --git a/app/assets/logo.svg b/cloud/assets/logo.svg similarity index 100% rename from app/assets/logo.svg rename to cloud/assets/logo.svg diff --git a/app/components/Alert/Alert.tsx b/cloud/components/Alert/Alert.tsx similarity index 100% rename from app/components/Alert/Alert.tsx rename to cloud/components/Alert/Alert.tsx diff --git a/app/components/Dialog/Dialog.module.css b/cloud/components/Dialog/Dialog.module.css similarity index 100% rename from app/components/Dialog/Dialog.module.css rename to cloud/components/Dialog/Dialog.module.css diff --git a/app/components/Dialog/Dialog.tsx b/cloud/components/Dialog/Dialog.tsx similarity index 100% rename from app/components/Dialog/Dialog.tsx rename to cloud/components/Dialog/Dialog.tsx diff --git a/app/components/Dialog/index.ts b/cloud/components/Dialog/index.ts similarity index 100% rename from app/components/Dialog/index.ts rename to cloud/components/Dialog/index.ts diff --git a/app/components/Form/Form.tsx b/cloud/components/Form/Form.tsx similarity index 100% rename from app/components/Form/Form.tsx rename to cloud/components/Form/Form.tsx diff --git a/app/components/Form/index.ts b/cloud/components/Form/index.ts similarity index 100% rename from app/components/Form/index.ts rename to cloud/components/Form/index.ts diff --git a/app/components/Layout/About.module.css b/cloud/components/Layout/About.module.css similarity index 100% rename from app/components/Layout/About.module.css rename to cloud/components/Layout/About.module.css diff --git a/app/components/Layout/About.tsx b/cloud/components/Layout/About.tsx similarity index 100% rename from app/components/Layout/About.tsx rename to cloud/components/Layout/About.tsx diff --git a/app/components/Layout/Banner.module.css b/cloud/components/Layout/Banner.module.css similarity index 100% rename from app/components/Layout/Banner.module.css rename to cloud/components/Layout/Banner.module.css diff --git a/app/components/Layout/Banner.tsx b/cloud/components/Layout/Banner.tsx similarity index 100% rename from app/components/Layout/Banner.tsx rename to cloud/components/Layout/Banner.tsx diff --git a/app/components/Layout/Breadcrumbs.tsx b/cloud/components/Layout/Breadcrumbs.tsx similarity index 100% rename from app/components/Layout/Breadcrumbs.tsx rename to cloud/components/Layout/Breadcrumbs.tsx diff --git a/app/components/Layout/Content.tsx b/cloud/components/Layout/Content.tsx similarity index 100% rename from app/components/Layout/Content.tsx rename to cloud/components/Layout/Content.tsx diff --git a/app/components/Layout/Footer.module.css b/cloud/components/Layout/Footer.module.css similarity index 100% rename from app/components/Layout/Footer.module.css rename to cloud/components/Layout/Footer.module.css diff --git a/app/components/Layout/Footer.tsx b/cloud/components/Layout/Footer.tsx similarity index 100% rename from app/components/Layout/Footer.tsx rename to cloud/components/Layout/Footer.tsx diff --git a/app/components/Layout/Header.module.css b/cloud/components/Layout/Header.module.css similarity index 100% rename from app/components/Layout/Header.module.css rename to cloud/components/Layout/Header.module.css diff --git a/app/components/Layout/Header.tsx b/cloud/components/Layout/Header.tsx similarity index 100% rename from app/components/Layout/Header.tsx rename to cloud/components/Layout/Header.tsx diff --git a/app/components/Layout/Language.module.css b/cloud/components/Layout/Language.module.css similarity index 100% rename from app/components/Layout/Language.module.css rename to cloud/components/Layout/Language.module.css diff --git a/app/components/Layout/Language.tsx b/cloud/components/Layout/Language.tsx similarity index 100% rename from app/components/Layout/Language.tsx rename to cloud/components/Layout/Language.tsx diff --git a/app/components/Layout/Layout.tsx b/cloud/components/Layout/Layout.tsx similarity index 100% rename from app/components/Layout/Layout.tsx rename to cloud/components/Layout/Layout.tsx diff --git a/app/components/Layout/Logo.module.css b/cloud/components/Layout/Logo.module.css similarity index 100% rename from app/components/Layout/Logo.module.css rename to cloud/components/Layout/Logo.module.css diff --git a/app/components/Layout/Logo.tsx b/cloud/components/Layout/Logo.tsx similarity index 100% rename from app/components/Layout/Logo.tsx rename to cloud/components/Layout/Logo.tsx diff --git a/app/components/Layout/Meta.tsx b/cloud/components/Layout/Meta.tsx similarity index 100% rename from app/components/Layout/Meta.tsx rename to cloud/components/Layout/Meta.tsx diff --git a/app/components/Layout/Navigation.tsx b/cloud/components/Layout/Navigation.tsx similarity index 100% rename from app/components/Layout/Navigation.tsx rename to cloud/components/Layout/Navigation.tsx diff --git a/app/components/Layout/Repository.module.css b/cloud/components/Layout/Repository.module.css similarity index 100% rename from app/components/Layout/Repository.module.css rename to cloud/components/Layout/Repository.module.css diff --git a/app/components/Layout/Repository.tsx b/cloud/components/Layout/Repository.tsx similarity index 100% rename from app/components/Layout/Repository.tsx rename to cloud/components/Layout/Repository.tsx diff --git a/app/components/Layout/Share.module.css b/cloud/components/Layout/Share.module.css similarity index 100% rename from app/components/Layout/Share.module.css rename to cloud/components/Layout/Share.module.css diff --git a/app/components/Layout/Share.tsx b/cloud/components/Layout/Share.tsx similarity index 100% rename from app/components/Layout/Share.tsx rename to cloud/components/Layout/Share.tsx diff --git a/app/components/Layout/Sitemap.tsx b/cloud/components/Layout/Sitemap.tsx similarity index 100% rename from app/components/Layout/Sitemap.tsx rename to cloud/components/Layout/Sitemap.tsx diff --git a/app/components/Layout/Theme.module.css b/cloud/components/Layout/Theme.module.css similarity index 100% rename from app/components/Layout/Theme.module.css rename to cloud/components/Layout/Theme.module.css diff --git a/app/components/Layout/Theme.tsx b/cloud/components/Layout/Theme.tsx similarity index 100% rename from app/components/Layout/Theme.tsx rename to cloud/components/Layout/Theme.tsx diff --git a/app/components/Layout/index.ts b/cloud/components/Layout/index.ts similarity index 100% rename from app/components/Layout/index.ts rename to cloud/components/Layout/index.ts diff --git a/app/components/Link/Link.module.css b/cloud/components/Link/Link.module.css similarity index 100% rename from app/components/Link/Link.module.css rename to cloud/components/Link/Link.module.css diff --git a/app/components/Link/Link.tsx b/cloud/components/Link/Link.tsx similarity index 100% rename from app/components/Link/Link.tsx rename to cloud/components/Link/Link.tsx diff --git a/app/components/Link/index.ts b/cloud/components/Link/index.ts similarity index 100% rename from app/components/Link/index.ts rename to cloud/components/Link/index.ts diff --git a/app/components/Report/Error/Cell.tsx b/cloud/components/Report/Error/Cell.tsx similarity index 100% rename from app/components/Report/Error/Cell.tsx rename to cloud/components/Report/Error/Cell.tsx diff --git a/app/components/Report/Error/Error.tsx b/cloud/components/Report/Error/Error.tsx similarity index 100% rename from app/components/Report/Error/Error.tsx rename to cloud/components/Report/Error/Error.tsx diff --git a/app/components/Report/Error/Field.tsx b/cloud/components/Report/Error/Field.tsx similarity index 100% rename from app/components/Report/Error/Field.tsx rename to cloud/components/Report/Error/Field.tsx diff --git a/app/components/Report/Error/Fields.tsx b/cloud/components/Report/Error/Fields.tsx similarity index 100% rename from app/components/Report/Error/Fields.tsx rename to cloud/components/Report/Error/Fields.tsx diff --git a/app/components/Report/Error/File.tsx b/cloud/components/Report/Error/File.tsx similarity index 100% rename from app/components/Report/Error/File.tsx rename to cloud/components/Report/Error/File.tsx diff --git a/app/components/Report/Error/Metadata.tsx b/cloud/components/Report/Error/Metadata.tsx similarity index 100% rename from app/components/Report/Error/Metadata.tsx rename to cloud/components/Report/Error/Metadata.tsx diff --git a/app/components/Report/Error/Row.tsx b/cloud/components/Report/Error/Row.tsx similarity index 100% rename from app/components/Report/Error/Row.tsx rename to cloud/components/Report/Error/Row.tsx diff --git a/app/components/Report/Report.tsx b/cloud/components/Report/Report.tsx similarity index 100% rename from app/components/Report/Report.tsx rename to cloud/components/Report/Report.tsx diff --git a/app/components/Report/index.ts b/cloud/components/Report/index.ts similarity index 100% rename from app/components/Report/index.ts rename to cloud/components/Report/index.ts diff --git a/app/components/Status/Status.module.css b/cloud/components/Status/Status.module.css similarity index 100% rename from app/components/Status/Status.module.css rename to cloud/components/Status/Status.module.css diff --git a/app/components/Status/Status.tsx b/cloud/components/Status/Status.tsx similarity index 100% rename from app/components/Status/Status.tsx rename to cloud/components/Status/Status.tsx diff --git a/app/components/Status/index.ts b/cloud/components/Status/index.ts similarity index 100% rename from app/components/Status/index.ts rename to cloud/components/Status/index.ts diff --git a/app/components/System/Error.module.css b/cloud/components/System/Error.module.css similarity index 100% rename from app/components/System/Error.module.css rename to cloud/components/System/Error.module.css diff --git a/app/components/System/Error.tsx b/cloud/components/System/Error.tsx similarity index 100% rename from app/components/System/Error.tsx rename to cloud/components/System/Error.tsx diff --git a/app/components/System/System.tsx b/cloud/components/System/System.tsx similarity index 100% rename from app/components/System/System.tsx rename to cloud/components/System/System.tsx diff --git a/app/components/System/context.ts b/cloud/components/System/context.ts similarity index 100% rename from app/components/System/context.ts rename to cloud/components/System/context.ts diff --git a/app/components/System/index.ts b/cloud/components/System/index.ts similarity index 100% rename from app/components/System/index.ts rename to cloud/components/System/index.ts diff --git a/app/components/System/selectors.ts b/cloud/components/System/selectors.ts similarity index 100% rename from app/components/System/selectors.ts rename to cloud/components/System/selectors.ts diff --git a/app/constants/language.ts b/cloud/constants/language.ts similarity index 100% rename from app/constants/language.ts rename to cloud/constants/language.ts diff --git a/app/constants/page.ts b/cloud/constants/page.ts similarity index 100% rename from app/constants/page.ts rename to cloud/constants/page.ts diff --git a/app/helpers/context.ts b/cloud/helpers/context.ts similarity index 100% rename from app/helpers/context.ts rename to cloud/helpers/context.ts diff --git a/app/helpers/link.ts b/cloud/helpers/link.ts similarity index 100% rename from app/helpers/link.ts rename to cloud/helpers/link.ts diff --git a/app/helpers/media.ts b/cloud/helpers/media.ts similarity index 100% rename from app/helpers/media.ts rename to cloud/helpers/media.ts diff --git a/app/helpers/platform.ts b/cloud/helpers/platform.ts similarity index 100% rename from app/helpers/platform.ts rename to cloud/helpers/platform.ts diff --git a/app/helpers/revision.ts b/cloud/helpers/revision.ts similarity index 100% rename from app/helpers/revision.ts rename to cloud/helpers/revision.ts diff --git a/app/helpers/rpc.ts b/cloud/helpers/rpc.ts similarity index 100% rename from app/helpers/rpc.ts rename to cloud/helpers/rpc.ts diff --git a/app/helpers/store.ts b/cloud/helpers/store.ts similarity index 100% rename from app/helpers/store.ts rename to cloud/helpers/store.ts diff --git a/app/i18n.ts b/cloud/i18n.ts similarity index 100% rename from app/i18n.ts rename to cloud/i18n.ts diff --git a/app/icons.ts b/cloud/icons.ts similarity index 100% rename from app/icons.ts rename to cloud/icons.ts diff --git a/app/locales/de.json b/cloud/locales/de.json similarity index 100% rename from app/locales/de.json rename to cloud/locales/de.json diff --git a/app/locales/en.json b/cloud/locales/en.json similarity index 100% rename from app/locales/en.json rename to cloud/locales/en.json diff --git a/app/locales/es.json b/cloud/locales/es.json similarity index 100% rename from app/locales/es.json rename to cloud/locales/es.json diff --git a/app/locales/fr.json b/cloud/locales/fr.json similarity index 100% rename from app/locales/fr.json rename to cloud/locales/fr.json diff --git a/app/locales/it.json b/cloud/locales/it.json similarity index 100% rename from app/locales/it.json rename to cloud/locales/it.json diff --git a/app/locales/pt.json b/cloud/locales/pt.json similarity index 100% rename from app/locales/pt.json rename to cloud/locales/pt.json diff --git a/app/locales/ru.json b/cloud/locales/ru.json similarity index 100% rename from app/locales/ru.json rename to cloud/locales/ru.json diff --git a/app/locales/uk.json b/cloud/locales/uk.json similarity index 100% rename from app/locales/uk.json rename to cloud/locales/uk.json diff --git a/app/logger.ts b/cloud/logger.ts similarity index 100% rename from app/logger.ts rename to cloud/logger.ts diff --git a/app/main.ts b/cloud/main.ts similarity index 100% rename from app/main.ts rename to cloud/main.ts diff --git a/app/package.json b/cloud/package.json similarity index 95% rename from app/package.json rename to cloud/package.json index 33fd5ab6..e128c766 100644 --- a/app/package.json +++ b/cloud/package.json @@ -1,5 +1,5 @@ { - "name": "@dpkit/app", + "name": "@dpkit/cloud", "type": "module", "version": "0.0.0-dev", "private": true, @@ -15,6 +15,7 @@ "type": "tsc --noEmit" }, "devDependencies": { + "@dpkit/service": "workspace:*", "@cloudflare/containers": "0.0.28", "@mantine/core": "8.3.5", "@mantine/form": "8.3.5", diff --git a/app/payload.ts b/cloud/payload.ts similarity index 100% rename from app/payload.ts rename to cloud/payload.ts diff --git a/app/postcss.config.ts b/cloud/postcss.config.ts similarity index 100% rename from app/postcss.config.ts rename to cloud/postcss.config.ts diff --git a/app/public/favicon.png b/cloud/public/favicon.png similarity index 100% rename from app/public/favicon.png rename to cloud/public/favicon.png diff --git a/app/public/robots.txt b/cloud/public/robots.txt similarity index 100% rename from app/public/robots.txt rename to cloud/public/robots.txt diff --git a/app/react-router.config.ts b/cloud/react-router.config.ts similarity index 100% rename from app/react-router.config.ts rename to cloud/react-router.config.ts diff --git a/app/routes/about/route.tsx b/cloud/routes/about/route.tsx similarity index 100% rename from app/routes/about/route.tsx rename to cloud/routes/about/route.tsx diff --git a/app/routes/entry.client.tsx b/cloud/routes/entry.client.tsx similarity index 100% rename from app/routes/entry.client.tsx rename to cloud/routes/entry.client.tsx diff --git a/app/routes/entry.server.tsx b/cloud/routes/entry.server.tsx similarity index 100% rename from app/routes/entry.server.tsx rename to cloud/routes/entry.server.tsx diff --git a/app/routes/home/route.module.css b/cloud/routes/home/route.module.css similarity index 100% rename from app/routes/home/route.module.css rename to cloud/routes/home/route.module.css diff --git a/app/routes/home/route.tsx b/cloud/routes/home/route.tsx similarity index 100% rename from app/routes/home/route.tsx rename to cloud/routes/home/route.tsx diff --git a/app/routes/package/validate/Dialog.tsx b/cloud/routes/package/validate/Dialog.tsx similarity index 100% rename from app/routes/package/validate/Dialog.tsx rename to cloud/routes/package/validate/Dialog.tsx diff --git a/app/routes/package/validate/Form.tsx b/cloud/routes/package/validate/Form.tsx similarity index 100% rename from app/routes/package/validate/Form.tsx rename to cloud/routes/package/validate/Form.tsx diff --git a/app/routes/package/validate/queries.ts b/cloud/routes/package/validate/queries.ts similarity index 100% rename from app/routes/package/validate/queries.ts rename to cloud/routes/package/validate/queries.ts diff --git a/app/routes/package/validate/route.tsx b/cloud/routes/package/validate/route.tsx similarity index 100% rename from app/routes/package/validate/route.tsx rename to cloud/routes/package/validate/route.tsx diff --git a/app/routes/package/validate/services.ts b/cloud/routes/package/validate/services.ts similarity index 100% rename from app/routes/package/validate/services.ts rename to cloud/routes/package/validate/services.ts diff --git a/app/routes/package/validate/store.ts b/cloud/routes/package/validate/store.ts similarity index 100% rename from app/routes/package/validate/store.ts rename to cloud/routes/package/validate/store.ts diff --git a/app/routes/root.tsx b/cloud/routes/root.tsx similarity index 100% rename from app/routes/root.tsx rename to cloud/routes/root.tsx diff --git a/app/routes/routes.ts b/cloud/routes/routes.ts similarity index 100% rename from app/routes/routes.ts rename to cloud/routes/routes.ts diff --git a/app/routes/schema/infer/route.tsx b/cloud/routes/schema/infer/route.tsx similarity index 100% rename from app/routes/schema/infer/route.tsx rename to cloud/routes/schema/infer/route.tsx diff --git a/app/routes/sitemap/page.ts b/cloud/routes/sitemap/page.ts similarity index 100% rename from app/routes/sitemap/page.ts rename to cloud/routes/sitemap/page.ts diff --git a/app/routes/sitemap/root.ts b/cloud/routes/sitemap/root.ts similarity index 100% rename from app/routes/sitemap/root.ts rename to cloud/routes/sitemap/root.ts diff --git a/app/routes/sitemap/services.ts b/cloud/routes/sitemap/services.ts similarity index 100% rename from app/routes/sitemap/services.ts rename to cloud/routes/sitemap/services.ts diff --git a/app/routes/system/redirects/home.ts b/cloud/routes/system/redirects/home.ts similarity index 100% rename from app/routes/system/redirects/home.ts rename to cloud/routes/system/redirects/home.ts diff --git a/app/routes/table/convert/route.tsx b/cloud/routes/table/convert/route.tsx similarity index 100% rename from app/routes/table/convert/route.tsx rename to cloud/routes/table/convert/route.tsx diff --git a/app/routes/table/validate/route.tsx b/cloud/routes/table/validate/route.tsx similarity index 100% rename from app/routes/table/validate/route.tsx rename to cloud/routes/table/validate/route.tsx diff --git a/app/rpc.ts b/cloud/rpc.ts similarity index 100% rename from app/rpc.ts rename to cloud/rpc.ts diff --git a/app/settings.ts b/cloud/settings.ts similarity index 100% rename from app/settings.ts rename to cloud/settings.ts diff --git a/app/styles/index.ts b/cloud/styles/index.ts similarity index 100% rename from app/styles/index.ts rename to cloud/styles/index.ts diff --git a/app/styles/main.css b/cloud/styles/main.css similarity index 100% rename from app/styles/main.css rename to cloud/styles/main.css diff --git a/app/theme.ts b/cloud/theme.ts similarity index 100% rename from app/theme.ts rename to cloud/theme.ts diff --git a/app/tsconfig.json b/cloud/tsconfig.json similarity index 100% rename from app/tsconfig.json rename to cloud/tsconfig.json diff --git a/app/types/index.ts b/cloud/types/index.ts similarity index 100% rename from app/types/index.ts rename to cloud/types/index.ts diff --git a/app/types/language.ts b/cloud/types/language.ts similarity index 100% rename from app/types/language.ts rename to cloud/types/language.ts diff --git a/app/types/page.ts b/cloud/types/page.ts similarity index 100% rename from app/types/page.ts rename to cloud/types/page.ts diff --git a/app/types/payload.ts b/cloud/types/payload.ts similarity index 100% rename from app/types/payload.ts rename to cloud/types/payload.ts diff --git a/app/types/rpc.ts b/cloud/types/rpc.ts similarity index 100% rename from app/types/rpc.ts rename to cloud/types/rpc.ts diff --git a/app/vite.config.ts b/cloud/vite.config.ts similarity index 85% rename from app/vite.config.ts rename to cloud/vite.config.ts index 0dfc2ef6..b7316219 100644 --- a/app/vite.config.ts +++ b/cloud/vite.config.ts @@ -13,6 +13,6 @@ export default defineConfig({ svgr(), ], resolve: { - alias: [{ find: "@dpkit/app", replacement: import.meta.dirname }], + alias: [{ find: "@dpkit/cloud", replacement: import.meta.dirname }], }, }) diff --git a/app/worker-configuration.d.ts b/cloud/worker-configuration.d.ts similarity index 100% rename from app/worker-configuration.d.ts rename to cloud/worker-configuration.d.ts diff --git a/app/wrangler.jsonc b/cloud/wrangler.jsonc similarity index 100% rename from app/wrangler.jsonc rename to cloud/wrangler.jsonc diff --git a/package.json b/package.json index 614a168c..5331c5ff 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "pnpm": "^10.0.0" }, "scripts": { - "build": "pnpm -F !app -F !docs -F !site build", + "build": "pnpm -F !cloud -F !docs -F !site build", "bump": "ncu -ws -u", "clean": "rm -rf **/node_modules", "compile": "pnpm -F cli compile", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a14ff40..183f2f64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,7 +54,102 @@ importers: specifier: 3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1) - app: + arrow: + dependencies: + '@dpkit/core': + specifier: workspace:* + version: link:../core + '@dpkit/file': + specifier: workspace:* + version: link:../file + '@dpkit/table': + specifier: workspace:* + version: link:../table + csv-sniffer: + specifier: ^0.1.1 + version: 0.1.1 + nodejs-polars: + specifier: ^0.22.1 + version: 0.22.1 + devDependencies: + '@dpkit/test': + specifier: workspace:* + version: link:../test + + browser: {} + + ckan: + dependencies: + '@dpkit/core': + specifier: workspace:* + version: link:../core + '@dpkit/file': + specifier: workspace:* + version: link:../file + devDependencies: + '@dpkit/test': + specifier: workspace:* + version: link:../test + + cli: + dependencies: + '@clack/prompts': + specifier: ^0.11.0 + version: 0.11.0 + '@commander-js/extra-typings': + specifier: ^14.0.0 + version: 14.0.0(commander@14.0.1) + '@dpkit/lib': + specifier: workspace:* + version: link:../lib + commander: + specifier: ^14.0.0 + version: 14.0.1 + es-toolkit: + specifier: ^1.39.10 + version: 1.39.10 + exit-hook: + specifier: ^4.0.0 + version: 4.0.0 + ink: + specifier: ^6.3.1 + version: 6.3.1(@types/react@19.1.9)(react-devtools-core@6.1.5)(react@19.2.0) + nodejs-polars: + specifier: ^0.22.1 + version: 0.22.1 + picocolors: + specifier: ^1.1.1 + version: 1.1.1 + react: + specifier: ^19.1.1 + version: 19.2.0 + react-devtools-core: + specifier: ^6.1.2 + version: 6.1.5 + tiny-invariant: + specifier: ^1.3.3 + version: 1.3.3 + ts-extras: + specifier: ^0.14.0 + version: 0.14.0 + devDependencies: + '@dpkit/file': + specifier: workspace:* + version: link:../file + '@dpkit/test': + specifier: workspace:* + version: link:../test + '@types/node': + specifier: 24.2.0 + version: 24.2.0 + '@types/react': + specifier: 19.1.9 + version: 19.1.9 + ink-testing-library: + specifier: 4.0.0 + version: 4.0.0(@types/react@19.1.9) + + cloud: devDependencies: '@cloudflare/containers': specifier: 0.0.28 @@ -62,6 +157,9 @@ importers: '@cloudflare/vite-plugin': specifier: 1.13.13 version: 1.13.13(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(workerd@1.20251008.0)(wrangler@4.43.0) + '@dpkit/service': + specifier: workspace:* + version: link:../service '@mantine/core': specifier: 8.3.5 version: 8.3.5(@mantine/hooks@8.3.5(react@19.2.0))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -159,101 +257,6 @@ importers: specifier: 5.0.8 version: 5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0) - arrow: - dependencies: - '@dpkit/core': - specifier: workspace:* - version: link:../core - '@dpkit/file': - specifier: workspace:* - version: link:../file - '@dpkit/table': - specifier: workspace:* - version: link:../table - csv-sniffer: - specifier: ^0.1.1 - version: 0.1.1 - nodejs-polars: - specifier: ^0.22.1 - version: 0.22.1 - devDependencies: - '@dpkit/test': - specifier: workspace:* - version: link:../test - - browser: {} - - ckan: - dependencies: - '@dpkit/core': - specifier: workspace:* - version: link:../core - '@dpkit/file': - specifier: workspace:* - version: link:../file - devDependencies: - '@dpkit/test': - specifier: workspace:* - version: link:../test - - cli: - dependencies: - '@clack/prompts': - specifier: ^0.11.0 - version: 0.11.0 - '@commander-js/extra-typings': - specifier: ^14.0.0 - version: 14.0.0(commander@14.0.1) - '@dpkit/lib': - specifier: workspace:* - version: link:../lib - commander: - specifier: ^14.0.0 - version: 14.0.1 - es-toolkit: - specifier: ^1.39.10 - version: 1.39.10 - exit-hook: - specifier: ^4.0.0 - version: 4.0.0 - ink: - specifier: ^6.3.1 - version: 6.3.1(@types/react@19.1.9)(react-devtools-core@6.1.5)(react@19.2.0) - nodejs-polars: - specifier: ^0.22.1 - version: 0.22.1 - picocolors: - specifier: ^1.1.1 - version: 1.1.1 - react: - specifier: ^19.1.1 - version: 19.2.0 - react-devtools-core: - specifier: ^6.1.2 - version: 6.1.5 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - ts-extras: - specifier: ^0.14.0 - version: 0.14.0 - devDependencies: - '@dpkit/file': - specifier: workspace:* - version: link:../file - '@dpkit/test': - specifier: workspace:* - version: link:../test - '@types/node': - specifier: 24.2.0 - version: 24.2.0 - '@types/react': - specifier: 19.1.9 - version: 19.1.9 - ink-testing-library: - specifier: 4.0.0 - version: 4.0.0(@types/react@19.1.9) - core: dependencies: '@sindresorhus/slugify': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index bd347c47..6473bd05 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,8 +1,8 @@ dangerouslyAllowAllBuilds: true packages: - - app - arrow - browser + - cloud - ckan - cli - core From 684d94cf69b1af09783cf6177f422722f75bb148 Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 12:14:48 +0100 Subject: [PATCH 09/16] Added http logging --- service/logger.ts | 2 +- service/server.ts | 100 +++++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/service/logger.ts b/service/logger.ts index 64f73aff..77cac9c0 100644 --- a/service/logger.ts +++ b/service/logger.ts @@ -4,6 +4,6 @@ import { Logger } from "tslog" export const logger = new LogLayer({ transport: new TsLogTransport({ - logger: new Logger(), + logger: new Logger({ type: "pretty" }), }), }) diff --git a/service/server.ts b/service/server.ts index 0b4f7e72..da31964f 100644 --- a/service/server.ts +++ b/service/server.ts @@ -51,60 +51,62 @@ export function createServer(options?: { }) const server = http.createServer(async (req, res) => { - console.log(req.url) + try { + if (req.url === config.prefix) { + const html = ` + + + + dpkit Service + + + + + +
+ + + + + ` - const { matched } = await openAPIHandler.handle(req, res, { - prefix: config.prefix, - }) + res.writeHead(200, { "Content-Type": "text/html" }) + res.end(html) + } else if (req.url === `${config.prefix}/spec.json`) { + const spec = await openAPIGenerator.generate(config.router, { + info: { + title: "dpkit Service", + version: metadata.version, + }, + servers: [{ url: url.toString() }], + security: [{ bearerAuth: [] }], + }) - if (matched) { - return - } + res.writeHead(200, { "Content-Type": "application/json" }) + res.end(JSON.stringify(spec)) + return + } else { + const { matched } = await openAPIHandler.handle(req, res, { + prefix: config.prefix, + }) - if (req.url === `${config.prefix}/spec.json`) { - const spec = await openAPIGenerator.generate(config.router, { - info: { - title: "dpkit Service", - version: metadata.version, - }, - servers: [{ url: url.toString() }], - security: [{ bearerAuth: [] }], - }) + if (!matched) { + res.writeHead(404) + res.end() + } + } + } catch (error: any) { + logger.error(error) - res.writeHead(200, { "Content-Type": "application/json" }) - res.end(JSON.stringify(spec)) - return + res.writeHead(500) + res.end() + } finally { + logger.info(`[${req.method}] ${req.url} → ${res.statusCode}`) } - - if (req.url === config.prefix) { - const html = ` - - - - dpkit Service - - - - - -
- - - - - ` - - res.writeHead(200, { "Content-Type": "text/html" }) - res.end(html) - return - } - - res.writeHead(404) - res.end() }) if (config.start) { From 708dd363534d2904d6a20df941bee072b15d927f Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 12:36:15 +0100 Subject: [PATCH 10/16] Connected cloud/service --- cloud/Dockerfile | 2 +- cloud/helpers/rpc.ts | 11 -------- cloud/logger.ts | 8 ++++-- cloud/main.ts | 12 ++++---- cloud/package.json | 27 ++++++++++-------- cloud/routes/package/validate/queries.ts | 15 +++++----- cloud/routes/package/validate/services.ts | 8 ------ cloud/rpc.ts | 34 ----------------------- cloud/service.ts | 12 ++++++++ cloud/settings.ts | 2 +- cloud/wrangler.jsonc | 8 +++--- pnpm-lock.yaml | 10 +++++++ service/client.ts | 4 +++ service/index.ts | 1 + 14 files changed, 67 insertions(+), 87 deletions(-) delete mode 100644 cloud/helpers/rpc.ts delete mode 100644 cloud/routes/package/validate/services.ts delete mode 100644 cloud/rpc.ts create mode 100644 cloud/service.ts create mode 100644 service/client.ts diff --git a/cloud/Dockerfile b/cloud/Dockerfile index 8b98debc..389f06f6 100644 --- a/cloud/Dockerfile +++ b/cloud/Dockerfile @@ -11,4 +11,4 @@ RUN pnpm install:ci RUN pnpm build EXPOSE 8080 -CMD ["node", "cloud/rpc.ts"] +CMD ["node", "service/main.ts"] diff --git a/cloud/helpers/rpc.ts b/cloud/helpers/rpc.ts deleted file mode 100644 index e04426ce..00000000 --- a/cloud/helpers/rpc.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { newHttpBatchRpcSession } from "capnweb" -import * as settings from "#settings.ts" -import type * as types from "#types/index.ts" - -export function createRpcSession() { - const url = import.meta.env.PROD - ? new URL("/rpc", settings.URL).toString() - : "/rpc" - - return newHttpBatchRpcSession(url) -} diff --git a/cloud/logger.ts b/cloud/logger.ts index fc75860e..77cac9c0 100644 --- a/cloud/logger.ts +++ b/cloud/logger.ts @@ -1,7 +1,9 @@ -import { ConsoleTransport, LogLayer } from "loglayer" +import { TsLogTransport } from "@loglayer/transport-tslog" +import { LogLayer } from "loglayer" +import { Logger } from "tslog" export const logger = new LogLayer({ - transport: new ConsoleTransport({ - logger: console, + transport: new TsLogTransport({ + logger: new Logger({ type: "pretty" }), }), }) diff --git a/cloud/main.ts b/cloud/main.ts index 9269dd59..71af62f3 100644 --- a/cloud/main.ts +++ b/cloud/main.ts @@ -2,10 +2,10 @@ import { Container, getContainer } from "@cloudflare/containers" import { createRequestHandler } from "react-router" export interface Env { - RPC: DurableObjectNamespace + SERVICE: DurableObjectNamespace } -export class Rpc extends Container { +export class Service extends Container { defaultPort = 8080 sleepAfter = "1h" } @@ -29,12 +29,12 @@ export default { async fetch(request, env, ctx) { const path = new URL(request.url).pathname - if (path === "/rpc") { - const containerInstance = getContainer(env.RPC, path) - return containerInstance.fetch(request) + if (path === "/api") { + const containerInstance = getContainer(env.SERVICE, path) + return await containerInstance.fetch(request) } - return requestHandler(request, { + return await requestHandler(request, { cloudflare: { env, ctx }, }) }, diff --git a/cloud/package.json b/cloud/package.json index e128c766..5252db8d 100644 --- a/cloud/package.json +++ b/cloud/package.json @@ -15,18 +15,26 @@ "type": "tsc --noEmit" }, "devDependencies": { - "@dpkit/service": "workspace:*", "@cloudflare/containers": "0.0.28", + "@cloudflare/vite-plugin": "1.13.13", + "@dpkit/service": "workspace:*", "@mantine/core": "8.3.5", "@mantine/form": "8.3.5", "@mantine/hooks": "8.3.5", + "@orpc/client": "1.10.0", + "@react-router/dev": "7.9.4", "@tanstack/react-query": "5.90.3", + "@types/react": "19.2.2", + "@types/react-dom": "^19.2.0", "es-toolkit": "1.39.10", "i18next": "25.6.0", "immer": "10.1.3", "isbot": "5.1.31", "loglayer": "6.9.1", "lucide-react": "0.545.0", + "postcss": "8.5.6", + "postcss-preset-mantine": "1.18.0", + "postcss-simple-vars": "7.0.1", "react": "19.2.0", "react-dom": "19.2.0", "react-flags-select": "2.5.0", @@ -38,17 +46,14 @@ "remix-utils": "9.0.0", "ts-extras": "^0.14.0", "vaul": "1.1.2", - "xml-js": "1.6.11", - "zustand": "5.0.8", - "@cloudflare/vite-plugin": "1.13.13", - "@react-router/dev": "7.9.4", - "@types/react": "19.2.2", - "@types/react-dom": "^19.2.0", - "postcss": "8.5.6", - "postcss-preset-mantine": "1.18.0", - "postcss-simple-vars": "7.0.1", "vite-plugin-devtools-json": "1.0.0", "vite-plugin-svgr": "4.5.0", - "wrangler": "4.43.0" + "wrangler": "4.43.0", + "xml-js": "1.6.11", + "zustand": "5.0.8" + }, + "dependencies": { + "@loglayer/transport-tslog": "^3.0.4", + "tslog": "^4.10.2" } } diff --git a/cloud/routes/package/validate/queries.ts b/cloud/routes/package/validate/queries.ts index 5a69832a..1d8280c2 100644 --- a/cloud/routes/package/validate/queries.ts +++ b/cloud/routes/package/validate/queries.ts @@ -1,19 +1,18 @@ import { useMutation } from "@tanstack/react-query" -import { createRpcSession } from "#helpers/rpc.ts" -import type { validatePackage } from "./services.ts" +import { service } from "#service.ts" import { store } from "./store.ts" export function useValidatePackage() { return useMutation({ mutationKey: ["validatePackage"], - mutationFn: async (source: Parameters[0]) => { + mutationFn: async ( + input: Parameters[0], + ) => { + return await service.package.validate(input) + }, + onMutate: () => { store.setState({ isDialogOpen: true }) store.setState({ isPending: true }) - - const rpc = createRpcSession() - const report = await rpc.validatePackage(source) - - return report }, onSettled: () => { store.setState({ isPending: false }) diff --git a/cloud/routes/package/validate/services.ts b/cloud/routes/package/validate/services.ts deleted file mode 100644 index 1c822b7f..00000000 --- a/cloud/routes/package/validate/services.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as dpkit from "@dpkit/lib" - -export async function validatePackage( - source: Parameters[0], -) { - const result = await dpkit.validatePackage(source) - return result -} diff --git a/cloud/rpc.ts b/cloud/rpc.ts deleted file mode 100644 index 63d4141f..00000000 --- a/cloud/rpc.ts +++ /dev/null @@ -1,34 +0,0 @@ -import http from "node:http" -import { RpcTarget, nodeHttpBatchRpcResponse } from "capnweb" -import { logger } from "#logger.ts" -import { validatePackage } from "#routes/package/validate/services.ts" - -export class Rpc extends RpcTarget { - validatePackage(...args: Parameters) { - return validatePackage(...args) - } -} - -const server = http.createServer(async (request, response) => { - try { - // For health-checks we just return 200 - if (request.url === "/") { - response.statusCode = 200 - response.end() - return - } - - await nodeHttpBatchRpcResponse(request, response, new Rpc()) - } catch (error: any) { - response.statusCode = 500 - response.end("Internal Error") - - logger.error(error) - } finally { - logger.info(`[${request.method}] ${request.url}`, response.statusCode) - } -}) - -server.listen(8080, () => { - logger.info("Listening on port 8080") -}) diff --git a/cloud/service.ts b/cloud/service.ts new file mode 100644 index 00000000..a7e321b1 --- /dev/null +++ b/cloud/service.ts @@ -0,0 +1,12 @@ +import type { Client } from "@dpkit/service" +import { createORPCClient } from "@orpc/client" +import { RPCLink } from "@orpc/client/fetch" +import * as settings from "#settings.ts" + +export const service: Client = createORPCClient( + new RPCLink({ + url: import.meta.env.PROD + ? new URL("/api", settings.URL).toString() + : "/api", + }), +) diff --git a/cloud/settings.ts b/cloud/settings.ts index 689282bc..511b5f47 100644 --- a/cloud/settings.ts +++ b/cloud/settings.ts @@ -3,5 +3,5 @@ export const TITLE = "dpkit Cloud" export const DESCRIPTION = "dpkit Cloud" export const ICON_SIZE = 20 -export const ICON_STROKE_WIDTH = 1.5 export const ICON_SIZE_SMALL = 12 +export const ICON_STROKE_WIDTH = 1.5 diff --git a/cloud/wrangler.jsonc b/cloud/wrangler.jsonc index e32a4a0f..61e50986 100644 --- a/cloud/wrangler.jsonc +++ b/cloud/wrangler.jsonc @@ -13,7 +13,7 @@ }, "containers": [ { - "class_name": "Rpc", + "class_name": "Service", "image": "./Dockerfile", "image_build_context": "../", "instance_type": "standard-1", @@ -23,14 +23,14 @@ "durable_objects": { "bindings": [ { - "class_name": "Rpc", - "name": "RPC" + "class_name": "Service", + "name": "SERVICE" } ] }, "migrations": [ { - "new_sqlite_classes": ["Rpc"], + "new_sqlite_classes": ["Service"], "tag": "v1" } ] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 183f2f64..8ff995b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -150,6 +150,13 @@ importers: version: 4.0.0(@types/react@19.1.9) cloud: + dependencies: + '@loglayer/transport-tslog': + specifier: ^3.0.4 + version: 3.0.4(tslog@4.10.2) + tslog: + specifier: ^4.10.2 + version: 4.10.2 devDependencies: '@cloudflare/containers': specifier: 0.0.28 @@ -169,6 +176,9 @@ importers: '@mantine/hooks': specifier: 8.3.5 version: 8.3.5(react@19.2.0) + '@orpc/client': + specifier: 1.10.0 + version: 1.10.0 '@react-router/dev': specifier: 7.9.4 version: 7.9.4(@types/node@24.2.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(typescript@5.9.2)(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(wrangler@4.43.0)(yaml@2.8.1) diff --git a/service/client.ts b/service/client.ts new file mode 100644 index 00000000..361a4cb5 --- /dev/null +++ b/service/client.ts @@ -0,0 +1,4 @@ +import type { RouterClient } from "@orpc/server" +import type { router } from "./router.ts" + +export type Client = RouterClient diff --git a/service/index.ts b/service/index.ts index ebb79d39..1a0c7811 100644 --- a/service/index.ts +++ b/service/index.ts @@ -1,3 +1,4 @@ export { router } from "./router.ts" export { logger } from "./logger.ts" export { createServer } from "./server.ts" +export type { Client } from "./client.ts" From 40722e6798f7f7fdef3dd4961b02d8e58c68b46f Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 13:23:10 +0100 Subject: [PATCH 11/16] Updated dependencies --- browser/index.ts | 0 browser/tsconfig.json | 3 ++ cloud/Dockerfile | 2 +- cloud/{service.ts => api/client.ts} | 3 +- cloud/api/server.ts | 3 ++ cloud/main.ts | 2 +- cloud/package.json | 13 +++--- cloud/routes/package/validate/queries.ts | 11 +++--- package.json | 2 +- pnpm-lock.yaml | 50 ++++++++++++++++-------- service/package.json | 14 +++---- service/server.ts | 6 ++- 12 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 browser/index.ts create mode 100644 browser/tsconfig.json rename cloud/{service.ts => api/client.ts} (81%) create mode 100644 cloud/api/server.ts diff --git a/browser/index.ts b/browser/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/browser/tsconfig.json b/browser/tsconfig.json new file mode 100644 index 00000000..3c43903c --- /dev/null +++ b/browser/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.json" +} diff --git a/cloud/Dockerfile b/cloud/Dockerfile index 389f06f6..cf7ce5bd 100644 --- a/cloud/Dockerfile +++ b/cloud/Dockerfile @@ -11,4 +11,4 @@ RUN pnpm install:ci RUN pnpm build EXPOSE 8080 -CMD ["node", "service/main.ts"] +CMD ["node", "cloud/api/server.ts"] diff --git a/cloud/service.ts b/cloud/api/client.ts similarity index 81% rename from cloud/service.ts rename to cloud/api/client.ts index a7e321b1..ee9512a7 100644 --- a/cloud/service.ts +++ b/cloud/api/client.ts @@ -1,9 +1,10 @@ +import "client-only" import type { Client } from "@dpkit/service" import { createORPCClient } from "@orpc/client" import { RPCLink } from "@orpc/client/fetch" import * as settings from "#settings.ts" -export const service: Client = createORPCClient( +export const api: Client = createORPCClient( new RPCLink({ url: import.meta.env.PROD ? new URL("/api", settings.URL).toString() diff --git a/cloud/api/server.ts b/cloud/api/server.ts new file mode 100644 index 00000000..2b5f6e11 --- /dev/null +++ b/cloud/api/server.ts @@ -0,0 +1,3 @@ +import { createServer } from "@dpkit/service" + +createServer({ start: true }) diff --git a/cloud/main.ts b/cloud/main.ts index 71af62f3..e6708517 100644 --- a/cloud/main.ts +++ b/cloud/main.ts @@ -29,7 +29,7 @@ export default { async fetch(request, env, ctx) { const path = new URL(request.url).pathname - if (path === "/api") { + if (path.startsWith("/api")) { const containerInstance = getContainer(env.SERVICE, path) return await containerInstance.fetch(request) } diff --git a/cloud/package.json b/cloud/package.json index 5252db8d..a3a3d4c9 100644 --- a/cloud/package.json +++ b/cloud/package.json @@ -22,10 +22,12 @@ "@mantine/form": "8.3.5", "@mantine/hooks": "8.3.5", "@orpc/client": "1.10.0", + "@orpc/openapi-client": "1.10.0", "@react-router/dev": "7.9.4", "@tanstack/react-query": "5.90.3", "@types/react": "19.2.2", "@types/react-dom": "^19.2.0", + "client-only": "0.0.1", "es-toolkit": "1.39.10", "i18next": "25.6.0", "immer": "10.1.3", @@ -44,16 +46,15 @@ "react-share": "5.2.2", "react-type-animation": "3.2.0", "remix-utils": "9.0.0", - "ts-extras": "^0.14.0", + "server-only": "0.0.1", + "ts-extras": "0.14.0", "vaul": "1.1.2", "vite-plugin-devtools-json": "1.0.0", "vite-plugin-svgr": "4.5.0", "wrangler": "4.43.0", "xml-js": "1.6.11", - "zustand": "5.0.8" - }, - "dependencies": { - "@loglayer/transport-tslog": "^3.0.4", - "tslog": "^4.10.2" + "zustand": "5.0.8", + "@loglayer/transport-tslog": "3.0.4", + "tslog": "4.10.2" } } diff --git a/cloud/routes/package/validate/queries.ts b/cloud/routes/package/validate/queries.ts index 1d8280c2..d4fa7a3e 100644 --- a/cloud/routes/package/validate/queries.ts +++ b/cloud/routes/package/validate/queries.ts @@ -1,14 +1,12 @@ import { useMutation } from "@tanstack/react-query" -import { service } from "#service.ts" +import { api } from "#api/client.ts" import { store } from "./store.ts" export function useValidatePackage() { return useMutation({ mutationKey: ["validatePackage"], - mutationFn: async ( - input: Parameters[0], - ) => { - return await service.package.validate(input) + mutationFn: async (input: Parameters[0]) => { + return await api.package.validate(input) }, onMutate: () => { store.setState({ isDialogOpen: true }) @@ -20,7 +18,8 @@ export function useValidatePackage() { onSuccess: report => { store.setState({ report }) }, - onError: () => { + onError: error => { + console.log(error) store.setState({ isFault: true }) }, }) diff --git a/package.json b/package.json index 5331c5ff..ceb83402 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "npm-check-updates": "18.0.1", "semantic-release": "24.2.9", "tempy": "3.1.0", - "type-fest": "^4.41.0", + "type-fest": "4.41.0", "typescript": "5.9.2", "vite": "7.1.10", "vitest": "3.2.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ff995b6..93c35db6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,7 +42,7 @@ importers: specifier: 3.1.0 version: 3.1.0 type-fest: - specifier: ^4.41.0 + specifier: 4.41.0 version: 4.41.0 typescript: specifier: 5.9.2 @@ -150,13 +150,6 @@ importers: version: 4.0.0(@types/react@19.1.9) cloud: - dependencies: - '@loglayer/transport-tslog': - specifier: ^3.0.4 - version: 3.0.4(tslog@4.10.2) - tslog: - specifier: ^4.10.2 - version: 4.10.2 devDependencies: '@cloudflare/containers': specifier: 0.0.28 @@ -167,6 +160,9 @@ importers: '@dpkit/service': specifier: workspace:* version: link:../service + '@loglayer/transport-tslog': + specifier: 3.0.4 + version: 3.0.4(tslog@4.10.2) '@mantine/core': specifier: 8.3.5 version: 8.3.5(@mantine/hooks@8.3.5(react@19.2.0))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -179,6 +175,9 @@ importers: '@orpc/client': specifier: 1.10.0 version: 1.10.0 + '@orpc/openapi-client': + specifier: 1.10.0 + version: 1.10.0 '@react-router/dev': specifier: 7.9.4 version: 7.9.4(@types/node@24.2.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(typescript@5.9.2)(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(wrangler@4.43.0)(yaml@2.8.1) @@ -191,6 +190,9 @@ importers: '@types/react-dom': specifier: ^19.2.0 version: 19.2.0(@types/react@19.2.2) + client-only: + specifier: 0.0.1 + version: 0.0.1 es-toolkit: specifier: 1.39.10 version: 1.39.10 @@ -245,9 +247,15 @@ importers: remix-utils: specifier: 9.0.0 version: 9.0.0(@oslojs/encoding@1.1.0)(@standard-schema/spec@1.0.0)(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0) + server-only: + specifier: 0.0.1 + version: 0.0.1 ts-extras: - specifier: ^0.14.0 + specifier: 0.14.0 version: 0.14.0 + tslog: + specifier: 4.10.2 + version: 4.10.2 vaul: specifier: 1.1.2 version: 1.1.2(@types/react-dom@19.2.0(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -641,30 +649,30 @@ importers: version: link:../test service: - devDependencies: + dependencies: '@dpkit/lib': specifier: workspace:* version: link:../lib '@loglayer/transport-tslog': - specifier: ^3.0.4 + specifier: 3.0.4 version: 3.0.4(tslog@4.10.2) '@orpc/openapi': - specifier: ^1.10.0 + specifier: 1.10.0 version: 1.10.0(crossws@0.3.5)(ws@8.18.3) '@orpc/server': - specifier: ^1.10.0 + specifier: 1.10.0 version: 1.10.0(crossws@0.3.5)(ws@8.18.3) '@orpc/zod': - specifier: ^1.10.0 + specifier: 1.10.0 version: 1.10.0(@orpc/contract@1.10.0)(@orpc/server@1.10.0(crossws@0.3.5)(ws@8.18.3))(crossws@0.3.5)(ws@8.18.3)(zod@4.1.12) loglayer: specifier: 6.9.1 version: 6.9.1 tslog: - specifier: ^4.10.2 + specifier: 4.10.2 version: 4.10.2 zod: - specifier: ^4.1.12 + specifier: 4.1.12 version: 4.1.12 site: @@ -3059,6 +3067,9 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -5548,6 +5559,9 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} @@ -9018,6 +9032,8 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.2.0 + client-only@0.0.1: {} + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -11896,6 +11912,8 @@ snapshots: transitivePeerDependencies: - supports-color + server-only@0.0.1: {} + set-cookie-parser@2.7.1: {} setprototypeof@1.2.0: {} diff --git a/service/package.json b/service/package.json index 96ed3e29..a6d51370 100644 --- a/service/package.json +++ b/service/package.json @@ -24,14 +24,14 @@ "scripts": { "build": "tsc" }, - "devDependencies": { + "dependencies": { "@dpkit/lib": "workspace:*", - "@loglayer/transport-tslog": "^3.0.4", - "@orpc/openapi": "^1.10.0", - "@orpc/server": "^1.10.0", - "@orpc/zod": "^1.10.0", + "@loglayer/transport-tslog": "3.0.4", + "@orpc/openapi": "1.10.0", + "@orpc/server": "1.10.0", + "@orpc/zod": "1.10.0", "loglayer": "6.9.1", - "tslog": "^4.10.2", - "zod": "^4.1.12" + "tslog": "4.10.2", + "zod": "4.1.12" } } diff --git a/service/server.ts b/service/server.ts index da31964f..19807a1f 100644 --- a/service/server.ts +++ b/service/server.ts @@ -52,7 +52,11 @@ export function createServer(options?: { const server = http.createServer(async (req, res) => { try { - if (req.url === config.prefix) { + if (req.url === "/") { + // Handle health checks + res.writeHead(200) + res.end() + } else if (req.url === config.prefix) { const html = ` From 0643ea1b5b6711e1600d0686e3ea408f32757c7b Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 15:31:22 +0100 Subject: [PATCH 12/16] Rebased on openapi client --- cloud/api/client.ts | 25 +++++++++++++++++++++++++ cloud/package.json | 1 - pnpm-lock.yaml | 3 --- service/endpoints/package/validate.ts | 6 ++++++ service/server.ts | 9 +++++---- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/cloud/api/client.ts b/cloud/api/client.ts index ee9512a7..ffbf2740 100644 --- a/cloud/api/client.ts +++ b/cloud/api/client.ts @@ -1,7 +1,11 @@ import "client-only" import type { Client } from "@dpkit/service" import { createORPCClient } from "@orpc/client" +import { createORPCClient, onError } from "@orpc/client" import { RPCLink } from "@orpc/client/fetch" +import type { ContractRouterClient } from "@orpc/contract" +import type { JsonifiedClient } from "@orpc/openapi-client" +import { OpenAPILink } from "@orpc/openapi-client/fetch" import * as settings from "#settings.ts" export const api: Client = createORPCClient( @@ -11,3 +15,24 @@ export const api: Client = createORPCClient( : "/api", }), ) + +const link = new OpenAPILink(contract, { + url: "http://localhost:3000/api", + headers: () => ({ + "x-api-key": "my-api-key", + }), + fetch: (request, init) => { + return globalThis.fetch(request, { + ...init, + credentials: "include", // Include cookies for cross-origin requests + }) + }, + interceptors: [ + onError(error => { + console.error(error) + }), + ], +}) + +const client: JsonifiedClient> = + createORPCClient(link) diff --git a/cloud/package.json b/cloud/package.json index a3a3d4c9..07b8c9fa 100644 --- a/cloud/package.json +++ b/cloud/package.json @@ -21,7 +21,6 @@ "@mantine/core": "8.3.5", "@mantine/form": "8.3.5", "@mantine/hooks": "8.3.5", - "@orpc/client": "1.10.0", "@orpc/openapi-client": "1.10.0", "@react-router/dev": "7.9.4", "@tanstack/react-query": "5.90.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93c35db6..4d7e3abc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,9 +172,6 @@ importers: '@mantine/hooks': specifier: 8.3.5 version: 8.3.5(react@19.2.0) - '@orpc/client': - specifier: 1.10.0 - version: 1.10.0 '@orpc/openapi-client': specifier: 1.10.0 version: 1.10.0 diff --git a/service/endpoints/package/validate.ts b/service/endpoints/package/validate.ts index 6d76417c..6276ca33 100644 --- a/service/endpoints/package/validate.ts +++ b/service/endpoints/package/validate.ts @@ -8,6 +8,12 @@ export const validatePackage = os source: z.string(), }), ) + .output( + z.object({ + valid: z.boolean(), + errors: z.array(z.record(z.string(), z.any())), + }), + ) .handler(async ({ input }) => { const { source } = input const result = await dpkit.validatePackage(source) diff --git a/service/server.ts b/service/server.ts index 19807a1f..fdce5728 100644 --- a/service/server.ts +++ b/service/server.ts @@ -3,7 +3,7 @@ import { OpenAPIGenerator } from "@orpc/openapi" import { OpenAPIHandler } from "@orpc/openapi/node" import type { Router } from "@orpc/server" import { CORSPlugin } from "@orpc/server/plugins" -import { ZodSmartCoercionPlugin, ZodToJsonSchemaConverter } from "@orpc/zod" +import { ZodToJsonSchemaConverter } from "@orpc/zod" import type { Logger } from "tslog" import { logger } from "./logger.ts" import metadata from "./package.json" with { type: "json" } @@ -41,8 +41,10 @@ export function createServer(options?: { const openAPIHandler = new OpenAPIHandler(config.router, { plugins: [ - new CORSPlugin({ allowMethods: config.corsMethods }), - new ZodSmartCoercionPlugin(), + new CORSPlugin({ + allowMethods: config.corsMethods, + exposeHeaders: ["Content-Disposition"], + }), ], }) @@ -87,7 +89,6 @@ export function createServer(options?: { version: metadata.version, }, servers: [{ url: url.toString() }], - security: [{ bearerAuth: [] }], }) res.writeHead(200, { "Content-Type": "application/json" }) From 603e9d736bb477ef056ca8d4a13cf72f8c3a3612 Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 16:26:44 +0100 Subject: [PATCH 13/16] Split server/client --- pnpm-lock.yaml | 9 ++++ service/@generate.ts | 11 +++++ service/client.ts | 43 +++++++++++++++++-- service/contract.json | 11 +++++ service/contract.ts | 4 ++ service/exports/client.ts | 3 ++ service/exports/server.ts | 3 ++ service/index.ts | 4 -- .../package/validate.ts | 0 service/package.json | 12 ++++-- service/router.ts | 2 +- service/sandbox.ts | 1 - 12 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 service/@generate.ts create mode 100644 service/contract.json create mode 100644 service/contract.ts create mode 100644 service/exports/client.ts create mode 100644 service/exports/server.ts delete mode 100644 service/index.ts rename service/{endpoints => operations}/package/validate.ts (100%) delete mode 100644 service/sandbox.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d7e3abc..cedc591b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -653,9 +653,18 @@ importers: '@loglayer/transport-tslog': specifier: 3.0.4 version: 3.0.4(tslog@4.10.2) + '@orpc/client': + specifier: ^1.10.0 + version: 1.10.0 + '@orpc/contract': + specifier: ^1.10.0 + version: 1.10.0 '@orpc/openapi': specifier: 1.10.0 version: 1.10.0(crossws@0.3.5)(ws@8.18.3) + '@orpc/openapi-client': + specifier: 1.10.0 + version: 1.10.0 '@orpc/server': specifier: 1.10.0 version: 1.10.0(crossws@0.3.5)(ws@8.18.3) diff --git a/service/@generate.ts b/service/@generate.ts new file mode 100644 index 00000000..3b26193d --- /dev/null +++ b/service/@generate.ts @@ -0,0 +1,11 @@ +import fs from "node:fs" +import { join } from "node:path" +import { minifyContractRouter } from "@orpc/contract" +import { router } from "./router.ts" + +const contractJson = minifyContractRouter(router) + +fs.writeFileSync( + join(import.meta.dirname, "contract.json"), + JSON.stringify(contractJson, null, 2), +) diff --git a/service/client.ts b/service/client.ts index 361a4cb5..092fedec 100644 --- a/service/client.ts +++ b/service/client.ts @@ -1,4 +1,41 @@ -import type { RouterClient } from "@orpc/server" -import type { router } from "./router.ts" +import { createORPCClient } from "@orpc/client" +import type { ContractRouterClient } from "@orpc/contract" +import type { ContractRouter } from "@orpc/contract" +import type { JsonifiedClient } from "@orpc/openapi-client" +import { OpenAPILink } from "@orpc/openapi-client/fetch" +import type { Logger } from "tslog" +import { contract } from "./contract.ts" +import { logger } from "./logger.ts" +import * as settings from "./settings.ts" -export type Client = RouterClient +export function createClient(options?: { + contract: ContractRouter + logger?: Logger + protocol?: "http" | "https" + host?: string + port?: number + prefix?: `/${string}` +}) { + const config = { + contract: options?.contract ?? contract, + logger: options?.logger ?? logger, + protocol: options?.protocol ?? settings.PROTOCOL, + host: options?.host ?? settings.HOST, + port: options?.port ?? settings.PORT, + prefix: options?.prefix ?? settings.PREFIX, + } + + const url = new URL( + config.prefix, + `${config.protocol}://${config.host}:${config.port}`, + ) + + const link = new OpenAPILink(config.contract, { + url, + }) + + const client: JsonifiedClient> = + createORPCClient(link) + + return client +} diff --git a/service/contract.json b/service/contract.json new file mode 100644 index 00000000..d52f19c0 --- /dev/null +++ b/service/contract.json @@ -0,0 +1,11 @@ +{ + "package": { + "validate": { + "~orpc": { + "errorMap": {}, + "meta": {}, + "route": {} + } + } + } +} \ No newline at end of file diff --git a/service/contract.ts b/service/contract.ts new file mode 100644 index 00000000..685e7f8e --- /dev/null +++ b/service/contract.ts @@ -0,0 +1,4 @@ +import contractJson from "./contract.json" with { type: "json" } +import type { router } from "./router.ts" + +export const contract = contractJson as typeof router diff --git a/service/exports/client.ts b/service/exports/client.ts new file mode 100644 index 00000000..b8448c16 --- /dev/null +++ b/service/exports/client.ts @@ -0,0 +1,3 @@ +export { logger } from "../logger.ts" +export { contract } from "../contract.ts" +export { createClient } from "../client.ts" diff --git a/service/exports/server.ts b/service/exports/server.ts new file mode 100644 index 00000000..f76f62d9 --- /dev/null +++ b/service/exports/server.ts @@ -0,0 +1,3 @@ +export { router } from "../router.ts" +export { logger } from "../logger.ts" +export { createServer } from "../server.ts" diff --git a/service/index.ts b/service/index.ts deleted file mode 100644 index 1a0c7811..00000000 --- a/service/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { router } from "./router.ts" -export { logger } from "./logger.ts" -export { createServer } from "./server.ts" -export type { Client } from "./client.ts" diff --git a/service/endpoints/package/validate.ts b/service/operations/package/validate.ts similarity index 100% rename from service/endpoints/package/validate.ts rename to service/operations/package/validate.ts diff --git a/service/package.json b/service/package.json index a6d51370..faee1ca8 100644 --- a/service/package.json +++ b/service/package.json @@ -2,8 +2,10 @@ "name": "@dpkit/service", "type": "module", "version": "0.0.0-dev", - "private": true, - "exports": "./build/index.js", + "exports": { + "./client": "./build/exports/client.js", + "./server": "./build/exports/server.js" + }, "sideEffects": false, "license": "MIT", "author": "Evgeny Karev", @@ -22,12 +24,16 @@ "service" ], "scripts": { - "build": "tsc" + "build": "tsc", + "generate": "node @generate.ts" }, "dependencies": { "@dpkit/lib": "workspace:*", "@loglayer/transport-tslog": "3.0.4", + "@orpc/client": "^1.10.0", + "@orpc/contract": "^1.10.0", "@orpc/openapi": "1.10.0", + "@orpc/openapi-client": "1.10.0", "@orpc/server": "1.10.0", "@orpc/zod": "1.10.0", "loglayer": "6.9.1", diff --git a/service/router.ts b/service/router.ts index cb90464d..2bb35947 100644 --- a/service/router.ts +++ b/service/router.ts @@ -1,4 +1,4 @@ -import { validatePackage } from "./endpoints/package/validate.ts" +import { validatePackage } from "./operations/package/validate.ts" export const router = { package: { diff --git a/service/sandbox.ts b/service/sandbox.ts deleted file mode 100644 index ebf465a0..00000000 --- a/service/sandbox.ts +++ /dev/null @@ -1 +0,0 @@ -// TODO: Implement disposable sandbox with size limit control From 51a9dd2c37d3135b62d00fd6da6355d883410d4f Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 16:33:34 +0100 Subject: [PATCH 14/16] Fixed contract --- service/contract.json | 5 ++++- service/operations/package/validate.ts | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/service/contract.json b/service/contract.json index d52f19c0..b78e69af 100644 --- a/service/contract.json +++ b/service/contract.json @@ -4,7 +4,10 @@ "~orpc": { "errorMap": {}, "meta": {}, - "route": {} + "route": { + "method": "POST", + "path": "/package/validate" + } } } } diff --git a/service/operations/package/validate.ts b/service/operations/package/validate.ts index 6276ca33..29569c56 100644 --- a/service/operations/package/validate.ts +++ b/service/operations/package/validate.ts @@ -3,6 +3,10 @@ import { os } from "@orpc/server" import * as z from "zod" export const validatePackage = os + .route({ + method: "POST", + path: "/package/validate", + }) .input( z.object({ source: z.string(), From a8df4c8300fe693ba0f1080cb4f81b8fcece218c Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 16:56:19 +0100 Subject: [PATCH 15/16] Fixed api --- .dockerignore | 4 ++ cloud/api/client.ts | 39 +++---------------- cloud/api/server.ts | 2 +- cloud/main.ts | 6 +-- cloud/package.json | 1 + cloud/routes/package/validate/Form.tsx | 10 ++--- cloud/wrangler.jsonc | 8 ++-- pnpm-lock.yaml | 3 ++ service/@generate.ts | 2 +- service/client.ts | 15 +++---- service/contract.json | 2 +- .../package/validate.ts | 2 +- service/package.json | 4 +- service/router.ts | 2 +- service/{exports => runtimes}/client.ts | 0 service/{exports => runtimes}/server.ts | 0 service/server.ts | 7 ++-- 17 files changed, 40 insertions(+), 67 deletions(-) rename service/{operations => endpoints}/package/validate.ts (87%) rename service/{exports => runtimes}/client.ts (100%) rename service/{exports => runtimes}/server.ts (100%) diff --git a/.dockerignore b/.dockerignore index 6a154f15..0e4767f1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,9 @@ .git .user +cli/ +docs/ +dpkit/ +site/ **/node_modules **/build **/compile diff --git a/cloud/api/client.ts b/cloud/api/client.ts index ffbf2740..52d4626f 100644 --- a/cloud/api/client.ts +++ b/cloud/api/client.ts @@ -1,38 +1,9 @@ import "client-only" -import type { Client } from "@dpkit/service" -import { createORPCClient } from "@orpc/client" -import { createORPCClient, onError } from "@orpc/client" -import { RPCLink } from "@orpc/client/fetch" -import type { ContractRouterClient } from "@orpc/contract" -import type { JsonifiedClient } from "@orpc/openapi-client" -import { OpenAPILink } from "@orpc/openapi-client/fetch" +import { createClient } from "@dpkit/service/client" import * as settings from "#settings.ts" -export const api: Client = createORPCClient( - new RPCLink({ - url: import.meta.env.PROD - ? new URL("/api", settings.URL).toString() - : "/api", - }), -) - -const link = new OpenAPILink(contract, { - url: "http://localhost:3000/api", - headers: () => ({ - "x-api-key": "my-api-key", - }), - fetch: (request, init) => { - return globalThis.fetch(request, { - ...init, - credentials: "include", // Include cookies for cross-origin requests - }) - }, - interceptors: [ - onError(error => { - console.error(error) - }), - ], +export const api = createClient({ + protocol: import.meta.env.PROD ? "https" : "http", + host: import.meta.env.PROD ? settings.URL : "localhost", + port: import.meta.env.PROD ? 80 : 4000, }) - -const client: JsonifiedClient> = - createORPCClient(link) diff --git a/cloud/api/server.ts b/cloud/api/server.ts index 2b5f6e11..c4b30a65 100644 --- a/cloud/api/server.ts +++ b/cloud/api/server.ts @@ -1,3 +1,3 @@ -import { createServer } from "@dpkit/service" +import { createServer } from "@dpkit/service/server" createServer({ start: true }) diff --git a/cloud/main.ts b/cloud/main.ts index e6708517..f278e674 100644 --- a/cloud/main.ts +++ b/cloud/main.ts @@ -2,10 +2,10 @@ import { Container, getContainer } from "@cloudflare/containers" import { createRequestHandler } from "react-router" export interface Env { - SERVICE: DurableObjectNamespace + API: DurableObjectNamespace } -export class Service extends Container { +export class API extends Container { defaultPort = 8080 sleepAfter = "1h" } @@ -30,7 +30,7 @@ export default { const path = new URL(request.url).pathname if (path.startsWith("/api")) { - const containerInstance = getContainer(env.SERVICE, path) + const containerInstance = getContainer(env.API, path) return await containerInstance.fetch(request) } diff --git a/cloud/package.json b/cloud/package.json index 07b8c9fa..666a5ce5 100644 --- a/cloud/package.json +++ b/cloud/package.json @@ -17,6 +17,7 @@ "devDependencies": { "@cloudflare/containers": "0.0.28", "@cloudflare/vite-plugin": "1.13.13", + "@dpkit/core": "workspace:*", "@dpkit/service": "workspace:*", "@mantine/core": "8.3.5", "@mantine/form": "8.3.5", diff --git a/cloud/routes/package/validate/Form.tsx b/cloud/routes/package/validate/Form.tsx index a3121182..02306fcd 100644 --- a/cloud/routes/package/validate/Form.tsx +++ b/cloud/routes/package/validate/Form.tsx @@ -1,16 +1,16 @@ -import type { Descriptor } from "@dpkit/lib" +import type { Descriptor } from "@dpkit/core" import { Form } from "#components/Form/index.ts" import { useValidatePackage } from "./queries.ts" export function ValidatePackageForm() { const validatePackage = useValidatePackage() - const handleSubmit = (value: string | File | Descriptor) => { - if (value instanceof File) { - throw new Error("File upload not implemented") + const handleSubmit = (source: string | File | Descriptor) => { + if (source instanceof File) { + throw new Error("Not implemented") } - validatePackage.mutate(value) + validatePackage.mutate({ source }) } return
diff --git a/cloud/wrangler.jsonc b/cloud/wrangler.jsonc index 61e50986..c4986da1 100644 --- a/cloud/wrangler.jsonc +++ b/cloud/wrangler.jsonc @@ -13,7 +13,7 @@ }, "containers": [ { - "class_name": "Service", + "class_name": "API", "image": "./Dockerfile", "image_build_context": "../", "instance_type": "standard-1", @@ -23,14 +23,14 @@ "durable_objects": { "bindings": [ { - "class_name": "Service", - "name": "SERVICE" + "class_name": "API", + "name": "API" } ] }, "migrations": [ { - "new_sqlite_classes": ["Service"], + "new_sqlite_classes": ["API"], "tag": "v1" } ] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cedc591b..ec114cde 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -157,6 +157,9 @@ importers: '@cloudflare/vite-plugin': specifier: 1.13.13 version: 1.13.13(vite@7.1.10(@types/node@24.2.0)(sass@1.93.2)(sugarss@5.0.1(postcss@8.5.6))(tsx@4.20.3)(yaml@2.8.1))(workerd@1.20251008.0)(wrangler@4.43.0) + '@dpkit/core': + specifier: workspace:* + version: link:../core '@dpkit/service': specifier: workspace:* version: link:../service diff --git a/service/@generate.ts b/service/@generate.ts index 3b26193d..99921e6f 100644 --- a/service/@generate.ts +++ b/service/@generate.ts @@ -7,5 +7,5 @@ const contractJson = minifyContractRouter(router) fs.writeFileSync( join(import.meta.dirname, "contract.json"), - JSON.stringify(contractJson, null, 2), + `${JSON.stringify(contractJson, null, 2)}\n`, ) diff --git a/service/client.ts b/service/client.ts index 092fedec..fc6f0870 100644 --- a/service/client.ts +++ b/service/client.ts @@ -9,7 +9,7 @@ import { logger } from "./logger.ts" import * as settings from "./settings.ts" export function createClient(options?: { - contract: ContractRouter + contract?: ContractRouter logger?: Logger protocol?: "http" | "https" host?: string @@ -25,17 +25,12 @@ export function createClient(options?: { prefix: options?.prefix ?? settings.PREFIX, } - const url = new URL( - config.prefix, - `${config.protocol}://${config.host}:${config.port}`, - ) - - const link = new OpenAPILink(config.contract, { - url, - }) + const port = ![80, 443].includes(config.port) ? config.port : undefined + const host = [config.host, port].filter(Boolean).join(":") + const url = new URL(config.prefix, `${config.protocol}://${host}`) const client: JsonifiedClient> = - createORPCClient(link) + createORPCClient(new OpenAPILink(config.contract, { url })) return client } diff --git a/service/contract.json b/service/contract.json index b78e69af..85263eb0 100644 --- a/service/contract.json +++ b/service/contract.json @@ -11,4 +11,4 @@ } } } -} \ No newline at end of file +} diff --git a/service/operations/package/validate.ts b/service/endpoints/package/validate.ts similarity index 87% rename from service/operations/package/validate.ts rename to service/endpoints/package/validate.ts index 29569c56..6cb5335d 100644 --- a/service/operations/package/validate.ts +++ b/service/endpoints/package/validate.ts @@ -9,7 +9,7 @@ export const validatePackage = os }) .input( z.object({ - source: z.string(), + source: z.union([z.string(), z.record(z.string(), z.unknown())]), }), ) .output( diff --git a/service/package.json b/service/package.json index faee1ca8..1a386d04 100644 --- a/service/package.json +++ b/service/package.json @@ -3,8 +3,8 @@ "type": "module", "version": "0.0.0-dev", "exports": { - "./client": "./build/exports/client.js", - "./server": "./build/exports/server.js" + "./client": "./build/runtimes/client.js", + "./server": "./build/runtimes/server.js" }, "sideEffects": false, "license": "MIT", diff --git a/service/router.ts b/service/router.ts index 2bb35947..cb90464d 100644 --- a/service/router.ts +++ b/service/router.ts @@ -1,4 +1,4 @@ -import { validatePackage } from "./operations/package/validate.ts" +import { validatePackage } from "./endpoints/package/validate.ts" export const router = { package: { diff --git a/service/exports/client.ts b/service/runtimes/client.ts similarity index 100% rename from service/exports/client.ts rename to service/runtimes/client.ts diff --git a/service/exports/server.ts b/service/runtimes/server.ts similarity index 100% rename from service/exports/server.ts rename to service/runtimes/server.ts diff --git a/service/server.ts b/service/server.ts index fdce5728..34de7217 100644 --- a/service/server.ts +++ b/service/server.ts @@ -34,10 +34,9 @@ export function createServer(options?: { options?.withDocumentation ?? settings.WITH_DOCUMENTATION, } - const url = new URL( - config.prefix, - `${config.protocol}://${config.host}:${config.port}`, - ) + const port = ![80, 443].includes(config.port) ? config.port : undefined + const host = [config.host, port].filter(Boolean).join(":") + const url = new URL(config.prefix, `${config.protocol}://${host}`) const openAPIHandler = new OpenAPIHandler(config.router, { plugins: [ From 735496e389cbcd5f29c3125da2be52a95251b3cd Mon Sep 17 00:00:00 2001 From: roll Date: Wed, 22 Oct 2025 19:56:31 +0100 Subject: [PATCH 16/16] Fixed types --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index b68af920..fffde1ae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,10 +3,10 @@ "include": ["${configDir}/**/*.ts", "${configDir}/**/*.tsx"], "exclude": [ - "${configDir}/**/app/", "${configDir}/**/docs/", "${configDir}/**/site/", "${configDir}/**/build/", + "${configDir}/**/cloud/", "${configDir}/**/compile/", "${configDir}/**/*.spec.*/" ],