diff --git a/compose-dev.yaml b/compose-dev.yaml index cc7fd0a..36487f0 100644 --- a/compose-dev.yaml +++ b/compose-dev.yaml @@ -1,12 +1,11 @@ services: app: entrypoint: - - sleep - - infinity + - sleep + - infinity image: docker/dev-environments-javascript:stable-1 init: true volumes: - - type: bind - source: /var/run/docker.sock - target: /var/run/docker.sock - + - type: bind + source: /var/run/docker.sock + target: /var/run/docker.sock diff --git a/lib/ajv/index.ts b/lib/ajv/index.ts index 61ffc0d..71c8e49 100644 --- a/lib/ajv/index.ts +++ b/lib/ajv/index.ts @@ -3,7 +3,10 @@ import { basename } from 'node:path' import { TRPCError } from '@trpc/server' import Ajv from 'ajv' -import localize from 'ajv-i18n/localize/ru' +import ajvErrors from 'ajv-errors' +import ajvFormats from 'ajv-formats' +import ajvI18n from 'ajv-i18n' +import ajvKeywords from 'ajv-keywords' import consola from 'consola' import glob from 'fast-glob' @@ -26,8 +29,12 @@ export async function createAjv() { messages: false, verbose: true, allowDate: true, + parseDate: true, addUsedSchema: true, validateFormats: true, + inlineRefs: true, + passContext: true, + timestamp: 'date', }) const files = await glob('*.json', { @@ -43,27 +50,26 @@ export async function createAjv() { return { ...schema, $id: schemaId } })) + ajvKeywords(ajv) + ajvFormats(ajv) + ajvErrors(ajv) + ajv.addSchema(schemas) ajv.addSchema(userSchema, 'User') - // const test = ajv.getSchema('User') - // logger.info(test?.schemaEnv) function validateSchema(schemaId: string, data: unknown) { const valid = ajv.validate(schemaId, data) if (!valid) { - localize(ajv.errors) + ajvI18n.ru(ajv.errors) throw new TRPCError({ cause: ajv.errors, code: 'BAD_REQUEST', - message: ajv.errorsText( - ajv.errors, - { - separator: '\n', - dataVar: 'data', - }, - ), + message: ajv.errorsText(ajv.errors, { + separator: '\n', + dataVar: 'data', + }), }) } } diff --git a/lib/ajv/schema.ts b/lib/ajv/schema.ts index 1e0576f..f6f94d3 100644 --- a/lib/ajv/schema.ts +++ b/lib/ajv/schema.ts @@ -4,6 +4,7 @@ import type { TestUserInfo } from 'types' export const userSchema: JSONSchemaType<{ status: string info?: TestUserInfo + date: string }> = { type: 'object', properties: { @@ -13,6 +14,10 @@ export const userSchema: JSONSchemaType<{ info: { $ref: 'TestUserInfo', }, + date: { + type: 'string', + format: 'date-time', + }, }, required: ['status'], additionalProperties: false, diff --git a/lib/guard/index.ts b/lib/guard/index.ts deleted file mode 100644 index 78a82c2..0000000 --- a/lib/guard/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import path from 'node:path' - -export const alg = 'ES256' -const keysDir = path.join(__dirname, './keys') - -export const publicKeyPath = path.join(keysDir, 'public') -export const privateKeyPath = path.join(keysDir, 'private') -export function loadKeys() { - -} - -// export async function writeKeys(obj: { -// name: string -// privateKey: jose.KeyLike -// publicKey: jose.KeyLike -// }) { - -// } - -// export async function generateKeyPair(name: string) { -// const { privateKey, publicKey } = await jose.generateKeyPair(alg, { extractable: true }) - -// // writeKeys({ -// // name, -// // privateKey, -// // publicKey, -// // }) -// } diff --git a/lib/guard/keys.ts b/lib/guard/keys.ts deleted file mode 100644 index 75a3cb7..0000000 --- a/lib/guard/keys.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as jose from 'jose' - -export const alg = 'ES256' - -export const serverKeys = await jose.generateKeyPair(alg, { extractable: true }) -export const userKeys1 = await jose.generateKeyPair(alg, { extractable: true }) -export const userKeys3 = await jose.generateKeyPair(alg, { extractable: true }) diff --git a/lib/guard/t1.ts b/lib/guard/t1.ts deleted file mode 100644 index c0257e4..0000000 --- a/lib/guard/t1.ts +++ /dev/null @@ -1,29 +0,0 @@ -import consola from 'consola' -import * as jose from 'jose' - -const alg = 'ES256' - -const keys = await jose.generateKeyPair(alg, { extractable: true }) -const keys2 = await jose.generateKeyPair(alg, { extractable: true }) - -consola.log('keys\n', await jose.exportPKCS8(keys.privateKey)) -consola.log('keys2\n', await jose.exportPKCS8(keys2.privateKey)) - -const jws = await new jose.GeneralSign( - new TextEncoder().encode('Hello, World!'), -) - .addSignature(keys.privateKey) - .setProtectedHeader({ alg, b64: true }) - .addSignature(keys2.privateKey) - .setProtectedHeader({ alg, b64: true }) - .sign() - -consola.log('jws', jws) - -const { payload, protectedHeader } = await jose.generalVerify( - jws, - keys2.publicKey, -) - -consola.log(protectedHeader) -consola.log(new TextDecoder().decode(payload)) diff --git a/lib/guard/t2.ts b/lib/guard/t2.ts deleted file mode 100644 index 0ca5372..0000000 --- a/lib/guard/t2.ts +++ /dev/null @@ -1,54 +0,0 @@ -import consola from 'consola' -import * as jose from 'jose' - -const alg = 'ES256' -const options = { - issuer: 'urn:example:issuer', - audience: 'urn:example:audience', -} - -const keys = await jose.generateKeyPair(alg, { extractable: true }) -const keys2 = await jose.generateKeyPair(alg, { extractable: true }) -// const keys3 = await jose.generateKeyPair(alg, { extractable: true }); - -consola.info(keys.publicKey) - -const jwk1 = await jose.exportJWK(keys.publicKey).then((jwk) => { - jwk.kid = 'key1' - - return jwk -}) - -const jwk2 = await jose.exportJWK(keys2.publicKey).then((jwk) => { - jwk.kid = 'key2' - - return jwk -}) - -// const jwk3 = await jose.exportJWK(keys3.publicKey).then((jwk) => { -// jwk.kid = "key3"; -// return jwk; -// }); - -const jwks = jose.createLocalJWKSet({ keys: [jwk1, jwk2] }) - -consola.log('keys\n', await jose.exportPKCS8(keys.privateKey)) -consola.log('keys2\n', await jose.exportPKCS8(keys2.privateKey)) - -const jwt = await new jose.SignJWT({ - foo: 'bar', -}) - .setIssuer(options.issuer) - .setAudience(options.audience) - .setProtectedHeader({ alg, kid: 'key1' }) - .setExpirationTime('10m') - .setIssuedAt() - .sign(keys.privateKey) - -consola.log('jwt', jwt) - -const { payload, protectedHeader } = await jose - .jwtVerify(jwt, jwks, options) - -consola.log(protectedHeader) -consola.log(payload) diff --git a/lib/guard/test.ts b/lib/guard/test.ts deleted file mode 100644 index eb97f8d..0000000 --- a/lib/guard/test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import consola from 'consola' - -export function generateCombinations(test: { [key: string]: string[] }): string[][] { - let combinations: string[][] = [[]] - Object.keys(test).forEach((key) => { - const newCombinations: string[][] = [] - test[key].forEach((value) => { - combinations.forEach((combination) => { - newCombinations.push([...combination, `${key}-${value}`]) - }) - }) - combinations = newCombinations - }) - - return combinations -} - -const test = { - size: ['xs', 's', 'm', 'l', 'xl'], - color: ['red', 'green', 'blue'], - material: ['wood', 'plastic', 'metal'], -} - -consola.log(generateCombinations(test)) diff --git a/lib/jose/keys.ts b/lib/jose/keys.ts index b294501..708dd30 100644 --- a/lib/jose/keys.ts +++ b/lib/jose/keys.ts @@ -1,6 +1,6 @@ import { readFile } from 'node:fs/promises' -import * as jose from 'jose' +import { createLocalJWKSet, importJWK } from 'jose' import type { KeyPair } from './types' @@ -13,10 +13,10 @@ export const keys2: KeyPair = JSON.parse(await readFile( 'utf8', )) -export const keys1Private = await jose.importJWK(keys1.privateKey) -export const keys2Private = await jose.importJWK(keys2.privateKey) +export const keys1Private = await importJWK(keys1.privateKey) +export const keys2Private = await importJWK(keys2.privateKey) -export const jwks = jose.createLocalJWKSet({ +export const jwks = createLocalJWKSet({ keys: [ keys1.publicKey, keys2.publicKey, diff --git a/lib/jose/sign.ts b/lib/jose/sign.ts index e9443e4..0d7dc11 100644 --- a/lib/jose/sign.ts +++ b/lib/jose/sign.ts @@ -1,6 +1,7 @@ -import * as jose from 'jose' +import { SignJWT, importJWK, jwtVerify } from 'jose' import type { KeyPair } from './types' +import type { JWTPayload, JWTVerifyGetKey, VerifyOptions } from 'jose' const alg = 'ES256' const options = { @@ -10,29 +11,28 @@ const options = { export async function sign( keyPair: KeyPair, - payload: jose.JWTPayload, + payload: JWTPayload, ) { const { privateKey } = keyPair - const keys1Private = await jose.importJWK(privateKey) + const { kid } = privateKey - return new jose.SignJWT(payload) + const signKey = await importJWK(privateKey) + + return new SignJWT(payload) .setIssuer(options.issuer) .setAudience(options.audience) - .setProtectedHeader({ - alg, - kid: 'key1', - }) + .setProtectedHeader({ alg, kid }) .setExpirationTime('10m') .setIssuedAt() - .sign(keys1Private) + .sign(signKey) } export async function verify( jwt: string, - keySet: jose.JWTVerifyGetKey, - verifyOptions?: jose.VerifyOptions, + keySet: JWTVerifyGetKey, + verifyOptions?: VerifyOptions, ) { - const { payload } = await jose.jwtVerify( + const { payload } = await jwtVerify( jwt, keySet, verifyOptions, diff --git a/lib/mongo/index.ts b/lib/mongodb/index.ts similarity index 99% rename from lib/mongo/index.ts rename to lib/mongodb/index.ts index 5c692c6..7961589 100644 --- a/lib/mongo/index.ts +++ b/lib/mongodb/index.ts @@ -4,7 +4,6 @@ import { MongoClient } from 'mongodb' const logger = consola.withTag('mongodb') export async function createMongoDBStore() { const client = new MongoClient('mongodb://root:example@mongodb:27017') - await client.connect() const db = client.db('testSozdev') diff --git a/lib/quicktype/index.ts b/lib/quicktype/index.ts index 7241ec4..2dbd68d 100644 --- a/lib/quicktype/index.ts +++ b/lib/quicktype/index.ts @@ -1,4 +1,3 @@ -'fast-glob' import { FetchingJSONSchemaStore, InputData, @@ -7,37 +6,30 @@ import { } from 'quicktype-core' import type { + JSONSchemaSourceData, Options, TargetLanguage, } from 'quicktype-core' -export interface IQucktypeData { - typeName: string - jsonString: string -} - export async function quicktypeMultipleJSONSchema( - targetLanguage: string | TargetLanguage, - data: IQucktypeData[], + lang: string | TargetLanguage, + data: JSONSchemaSourceData[], options: Omit, 'inputData'>, ) { - const inputData = new InputData() - const jsonInput = new JSONSchemaInput(new FetchingJSONSchemaStore()) + await Promise.all( + data.map(({ name, schema }) => jsonInput.addSource({ + name, + schema, + })), + ) - for (const { typeName, jsonString } of data) { - await jsonInput.addSource({ - name: typeName, - schema: jsonString, - }) - } - + const inputData = new InputData() inputData.addInput(jsonInput) return quicktypeMultiFile({ + lang, inputData, - lang: targetLanguage, - outputFilename: 'index', ...options, }) } diff --git a/lib/superjson/index.ts b/lib/superjson/index.ts index 25f912a..ca85843 100644 --- a/lib/superjson/index.ts +++ b/lib/superjson/index.ts @@ -1,8 +1,6 @@ -import superjson from 'superjson' +import json from 'superjson' -import type { DataTransformer } from '@trpc/server' +import type { DataTransformerOptions } from '@trpc/server' -export const transformer: DataTransformer = { - serialize: (obj: unknown) => superjson.stringify(obj), - deserialize: (obj: string) => superjson.parse(obj), -} +export const superjson = json as DataTransformerOptions +export const transformer = undefined diff --git a/lib/ws/ws.ts b/lib/ws/ws.ts index 47a30b1..b6cf9f7 100644 --- a/lib/ws/ws.ts +++ b/lib/ws/ws.ts @@ -7,7 +7,7 @@ import { sign, verify } from '@/jose/sign' import type { Buffer } from 'node:buffer' import type { ClientOptions } from 'ws' -const logger = consola.withTag('ws/client') +const logger = consola.withTag('ws') type BufferLike = | string diff --git a/lib/ws/wss.ts b/lib/ws/wss.ts index 9973e74..1b1051e 100644 --- a/lib/ws/wss.ts +++ b/lib/ws/wss.ts @@ -5,7 +5,7 @@ import { wrapSocket } from './ws' import type { ServerOptions, WebSocket } from 'ws' -const logger = consola.withTag('ws/server') +const logger = consola.withTag('wss') export class WebSocketServerProxy extends WebSocketServer { public constructor(options?: ServerOptions, callback?: () => void) { diff --git a/package.json b/package.json index 2853100..561367d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,8 @@ "server": "yarn tsx --watch src/server", "client": "yarn tsx --watch src/client", "workers": "yarn tsx --watch src/workers", - "quicktype": "yarn tsx scripts/quicktype.ts" + "generate:types": "yarn tsx scripts/generate_types.ts", + "generate:keys": "yarn tsx scripts/generate_keys.ts" }, "dependencies": { "@antfu/utils": "^0.7.7", @@ -57,7 +58,10 @@ "@trpc/client": "^10.45.2", "@trpc/server": "^10.45.2", "ajv": "^8.12.0", + "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1", "ajv-i18n": "^4.2.0", + "ajv-keywords": "^5.1.0", "bullmq": "^5.4.2", "c12": "^1.10.0", "consola": "^3.2.3", diff --git a/scripts/keys.ts b/scripts/generate_keys.ts similarity index 88% rename from scripts/keys.ts rename to scripts/generate_keys.ts index 6918ada..244bf40 100644 --- a/scripts/keys.ts +++ b/scripts/generate_keys.ts @@ -1,7 +1,10 @@ import { writeFile } from 'node:fs/promises' +import consola from 'consola' import * as jose from 'jose' +const logger = consola.withTag('generate:keys') + const alg = 'ES256' const keys1 = await jose.generateKeyPair(alg, { extractable: true }) @@ -34,3 +37,5 @@ function addKid(kid: string) { return jwk } } + +logger.success('Done!') diff --git a/scripts/quicktype.ts b/scripts/generate_types.ts similarity index 60% rename from scripts/quicktype.ts rename to scripts/generate_types.ts index fb97549..9af8cdd 100644 --- a/scripts/quicktype.ts +++ b/scripts/generate_types.ts @@ -5,29 +5,27 @@ import consola from 'consola' import glob from 'fast-glob' import { TypeScriptTargetLanguage } from 'quicktype-core' -import type { IQucktypeData } from '@/quicktype' import { quicktypeMultipleJSONSchema } from '@/quicktype' -const logger = consola.withTag('generate') -const lang = new TypeScriptTargetLanguage() +import type { JSONSchemaSourceData } from 'quicktype-core' + +const logger = consola.withTag('generate:types') +const lang = new TypeScriptTargetLanguage() +const data: JSONSchemaSourceData[] = [] const files = await glob('**/*.json', { cwd: 'defs', absolute: true, }) -const data: IQucktypeData[] = [] - await Promise.all(files.map(async (file) => { - const fileContent = await readFile(file, 'utf8') - const schemaId = basename(file, '.json') - data.push({ - typeName: schemaId, - jsonString: fileContent, - }) + const schema = await readFile(file, 'utf8') + const name = basename(file, '.json') + data.push({ name, schema }) })) const filesRendered = await quicktypeMultipleJSONSchema(lang, data, { + outputFilename: 'index', rendererOptions: { 'just-types': true, 'prefer-types': true, @@ -36,9 +34,15 @@ const filesRendered = await quicktypeMultipleJSONSchema(lang, data, { }, }) -filesRendered.forEach(({ annotations, lines }, fileName) => { - writeFile( - `types/${fileName}.ts`, +for ( + const [ + outputFilename, + { annotations, lines }, + ] of filesRendered.entries() +) { + logger.info(`Writing ${outputFilename}.ts...`) + await writeFile( + `types/${outputFilename}.ts`, [ `/* eslint-disable */`, ...lines, @@ -49,6 +53,6 @@ filesRendered.forEach(({ annotations, lines }, fileName) => { flag: 'w', }, ) -}) +} -logger.info('rendered', filesRendered) +logger.success('Done!') diff --git a/src/client/index.ts b/src/client/index.ts index f81f9eb..1a726f5 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -15,8 +15,9 @@ import type { Router } from '~/server/router' const logger = consola.withTag('client') const ws = createWSClient({ - WebSocket: WebSocketProxy as any, url: 'ws://localhost:4000', + WebSocket: WebSocketProxy as any, + onOpen() { logger.info('Connected') }, @@ -73,6 +74,7 @@ while (true) { schemaId: 'User', data: { status: 'active', + date: new Date(), info: { name, email: `${name}@example.com`, diff --git a/src/server/context.ts b/src/server/context.ts index c422f47..6bd5873 100644 --- a/src/server/context.ts +++ b/src/server/context.ts @@ -1,6 +1,6 @@ import { createAjv } from '@/ajv' import { bullmq } from '@/bullmq' -import { createMongoDBStore } from '@/mongo' +import { createMongoDBStore } from '@/mongodb' import { createRedisStore } from '@/redis' import type { CreateHTTPContextOptions } from '@trpc/server/adapters/standalone' diff --git a/src/server/routers/data.ts b/src/server/routers/data.ts index ddf96e4..8438441 100644 --- a/src/server/routers/data.ts +++ b/src/server/routers/data.ts @@ -1,5 +1,3 @@ -import { EventEmitter } from 'node:events' - import { observable } from '@trpc/server/observable' import consola from 'consola' import { z } from 'zod' @@ -11,7 +9,7 @@ import { queueEvents } from '@/bullmq/events' import type { Document, OptionalId } from 'mongodb' const logger = consola.withTag('server') -const ee = new EventEmitter() + export const dataRouter = rootRouter({ getAll: publicProcedure .query(async ({ @@ -20,7 +18,6 @@ export const dataRouter = rootRouter({ getItem: publicProcedure .input(z.string()) - // .use(loggerMiddleware) .query(async ({ input: id, ctx: { redis }, @@ -43,12 +40,16 @@ export const dataRouter = rootRouter({ ) logger.info(`Job ${job.id} added:`, JSON.stringify(data, null, 2)) - // const returnvalue = await job.waitUntilFinished(queueEvents) - // logger.success(`Job ${job.id} result:`, returnvalue) - const { insertedId } = await mongodb.data.insertOne(data as OptionalId) - logger.info('insertedId:', insertedId.toJSON()) + const returnvalue = await job.waitUntilFinished(queueEvents) + logger.success(`Job ${job.id} result:`, returnvalue) + + const { insertedId } = await mongodb + .data + .insertOne(data as OptionalId) - return redis.data.insertOne(insertedId.toJSON(), data) + return redis + .data + .insertOne(insertedId.toJSON(), data) }), randomNumber: publicProcedure @@ -58,10 +59,6 @@ export const dataRouter = rootRouter({ ctx: { bullmq }, }) => observable<{ status: number }>((emit) => { logger.info(`subscription: Running subscription with n = ${n}`) - const onData = (data: any) => { - emit.next(data) - } - ee.on('onData', onData) queueEvents.on('completed', async ({ jobId }) => { logger.info(`subscription: Job ${jobId} completed`) const job = await bullmq.getJob(jobId) diff --git a/tsconfig.json b/tsconfig.json index de1c654..a31c120 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,26 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "compilerOptions": { "target": "ESNext", - "lib": ["ESNext", "DOM"], + "lib": [ + "ESNext", + "DOM" + ], "baseUrl": ".", "rootDir": ".", "module": "ESNext", "moduleResolution": "Bundler", "noResolve": false, "paths": { - "~/*": ["src/*"], - "@/*": ["lib/*"], - "types/*": ["types/*"] + "~/*": [ + "src/*" + ], + "@/*": [ + "lib/*" + ], + "types/*": [ + "types/*" + ] }, "resolveJsonModule": true, "resolvePackageJsonExports": true, @@ -28,5 +36,10 @@ "forceConsistentCasingInFileNames": true, "skipLibCheck": true }, - "include": ["types/**/*", "src/**/*", "lib/**/*", "scripts/**/*"] + "include": [ + "types/**/*", + "src/**/*", + "lib/**/*", + "scripts/**/*" + ] } diff --git a/types/index.ts b/types/index.ts index 5204492..2901f68 100644 --- a/types/index.ts +++ b/types/index.ts @@ -1,176 +1,176 @@ /* eslint-disable */ -export type GeoJSONFeature = { - bbox?: number[]; - geometry: null | GeoJSONFeatureGeoJSONPoint; - id?: number | string; - properties: { [key: string]: any } | null; - type: GeoJSONFeatureType; - [property: string]: any; +export type GeoJSONMultiLineString = { + bbox?: number[]; + coordinates: Array>; + type: PurpleType; + [property: string]: any; } -export type GeoJSONFeatureGeoJSONPoint = { - bbox?: number[]; - coordinates?: Array | number> | number>; - type: PurpleType; - geometries?: PurpleGeoJSON[]; - [property: string]: any; +export type PurpleType = "MultiLineString"; + +export type GeoJSONGeometryCollection = { + bbox?: number[]; + geometries: PurpleGeoJSON[]; + type: FluffyType; + [property: string]: any; } export type PurpleGeoJSON = { - bbox?: number[]; - coordinates: Array | number> | number>; - type: GeometryType; - [property: string]: any; + bbox?: number[]; + coordinates: Array | number> | number>; + type: GeometryType; + [property: string]: any; } export type GeometryType = "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon"; -export type PurpleType = "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon" | "GeometryCollection"; - -export type GeoJSONFeatureType = "Feature"; - -export type GeoJSONFeatureCollection = { - bbox?: number[]; - features: FeatureElement[]; - type: GeoJSONFeatureCollectionType; - [property: string]: any; -} +export type FluffyType = "GeometryCollection"; -export type FeatureElement = { - bbox?: number[]; - geometry: null | FeatureGeoJSONPoint; - id?: number | string; - properties: { [key: string]: any } | null; - type: GeoJSONFeatureType; - [property: string]: any; +export type GeoJSONFeature = { + bbox?: number[]; + geometry: null | GeoJSONFeatureGeoJSONPoint; + id?: number | string; + properties: { [key: string]: any } | null; + type: GeoJSONFeatureType; + [property: string]: any; } -export type FeatureGeoJSONPoint = { - bbox?: number[]; - coordinates?: Array | number> | number>; - type: PurpleType; - geometries?: FluffyGeoJSON[]; - [property: string]: any; +export type GeoJSONFeatureGeoJSONPoint = { + bbox?: number[]; + coordinates?: Array | number> | number>; + type: TentacledType; + geometries?: FluffyGeoJSON[]; + [property: string]: any; } export type FluffyGeoJSON = { - bbox?: number[]; - coordinates: Array | number> | number>; - type: GeometryType; - [property: string]: any; + bbox?: number[]; + coordinates: Array | number> | number>; + type: GeometryType; + [property: string]: any; } -export type GeoJSONFeatureCollectionType = "FeatureCollection"; +export type TentacledType = "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon" | "GeometryCollection"; -export type GeoJSONGeometryCollection = { - bbox?: number[]; - geometries: TentacledGeoJSON[]; - type: FluffyType; - [property: string]: any; -} +export type GeoJSONFeatureType = "Feature"; -export type TentacledGeoJSON = { - bbox?: number[]; - coordinates: Array | number> | number>; - type: GeometryType; - [property: string]: any; +export type GeoJSONGeometry = { + bbox?: number[]; + coordinates: Array | number> | number>; + type: GeometryType; + [property: string]: any; } -export type FluffyType = "GeometryCollection"; +export type GeoJSONFeatureCollection = { + bbox?: number[]; + features: FeatureElement[]; + type: GeoJSONFeatureCollectionType; + [property: string]: any; +} -export type GeoJSONLineString = { - bbox?: number[]; - coordinates: Array; - type: TentacledType; - [property: string]: any; +export type FeatureElement = { + bbox?: number[]; + geometry: null | FeatureGeoJSONPoint; + id?: number | string; + properties: { [key: string]: any } | null; + type: GeoJSONFeatureType; + [property: string]: any; } -export type TentacledType = "LineString"; +export type FeatureGeoJSONPoint = { + bbox?: number[]; + coordinates?: Array | number> | number>; + type: TentacledType; + geometries?: TentacledGeoJSON[]; + [property: string]: any; +} -export type GeoJSONMultiLineString = { - bbox?: number[]; - coordinates: Array>; - type: StickyType; - [property: string]: any; +export type TentacledGeoJSON = { + bbox?: number[]; + coordinates: Array | number> | number>; + type: GeometryType; + [property: string]: any; } -export type StickyType = "MultiLineString"; +export type GeoJSONFeatureCollectionType = "FeatureCollection"; -export type GeoJSONGeometry = { - bbox?: number[]; - coordinates: Array | number> | number>; - type: GeometryType; - [property: string]: any; +export type GeoJSONLineString = { + bbox?: number[]; + coordinates: Array; + type: StickyType; + [property: string]: any; } +export type StickyType = "LineString"; + export type GeoJSONMultiPoint = { - bbox?: number[]; - coordinates: Array; - type: IndigoType; - [property: string]: any; + bbox?: number[]; + coordinates: Array; + type: IndigoType; + [property: string]: any; } export type IndigoType = "MultiPoint"; -export type GeoJSONMultiPolygon = { - bbox?: number[]; - coordinates: Array>>; - type: IndecentType; - [property: string]: any; +export type GeoJSONPoint = { + bbox?: number[]; + coordinates: number[]; + type: IndecentType; + [property: string]: any; } -export type IndecentType = "MultiPolygon"; +export type IndecentType = "Point"; -export type GeoJSONPoint = { - bbox?: number[]; - coordinates: number[]; - type: HilariousType; - [property: string]: any; +export type GeoJSONMultiPolygon = { + bbox?: number[]; + coordinates: Array>>; + type: HilariousType; + [property: string]: any; } -export type HilariousType = "Point"; +export type HilariousType = "MultiPolygon"; export type TestUserInfo = { - email: string; - name: string; - [property: string]: any; + email: string; + name: string; + [property: string]: any; } export type TileJSON = { - attribution?: string; - bounds?: number[]; - center?: number[]; - data?: string[]; - description?: string; - fillzoom?: number; - grids?: string[]; - legend?: string; - maxzoom?: number; - minzoom?: number; - name?: string; - scheme?: string; - template?: string; - tilejson: string; - tiles: string[]; - vector_layers: VectorLayer[]; - version?: string; - [property: string]: any; + attribution?: string; + bounds?: number[]; + center?: number[]; + data?: string[]; + description?: string; + fillzoom?: number; + grids?: string[]; + legend?: string; + maxzoom?: number; + minzoom?: number; + name?: string; + scheme?: string; + template?: string; + tilejson: string; + tiles: string[]; + vector_layers: VectorLayer[]; + version?: string; + [property: string]: any; } export type VectorLayer = { - description?: string; - fields: { [key: string]: string }; - id: string; - maxzoom?: number; - minzoom?: number; - [property: string]: any; + description?: string; + fields: { [key: string]: string }; + id: string; + maxzoom?: number; + minzoom?: number; + [property: string]: any; } export type GeoJSONPolygon = { - bbox?: number[]; - coordinates: Array>; - type: AmbitiousType; - [property: string]: any; + bbox?: number[]; + coordinates: Array>; + type: AmbitiousType; + [property: string]: any; } export type AmbitiousType = "Polygon"; diff --git a/yarn.lock b/yarn.lock index bae2c6e..b6c3784 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1198,7 +1198,10 @@ __metadata: "@trpc/server": "npm:^10.45.2" "@types/ws": "npm:^8.5.10" ajv: "npm:^8.12.0" + ajv-errors: "npm:^3.0.0" + ajv-formats: "npm:^2.1.1" ajv-i18n: "npm:^4.2.0" + ajv-keywords: "npm:^5.1.0" bullmq: "npm:^5.4.2" c12: "npm:^1.10.0" consola: "npm:^3.2.3" @@ -1610,6 +1613,29 @@ __metadata: languageName: node linkType: hard +"ajv-errors@npm:^3.0.0": + version: 3.0.0 + resolution: "ajv-errors@npm:3.0.0" + peerDependencies: + ajv: ^8.0.1 + checksum: 10/bd3403f8547dc12f7417c40b6a003f6d891c0123e365b4b3cd9fffb0edd29100ae682b92ef47dcb3a3b4642a702a246873d3758c3fb92e24dfa3443f97476421 + languageName: node + linkType: hard + +"ajv-formats@npm:^2.1.1": + version: 2.1.1 + resolution: "ajv-formats@npm:2.1.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10/70c263ded219bf277ffd9127f793b625f10a46113b2e901e150da41931fcfd7f5592da6d66862f4449bb157ffe65867c3294a7df1d661cc232c4163d5a1718ed + languageName: node + linkType: hard + "ajv-i18n@npm:^4.2.0": version: 4.2.0 resolution: "ajv-i18n@npm:4.2.0" @@ -1619,6 +1645,17 @@ __metadata: languageName: node linkType: hard +"ajv-keywords@npm:^5.1.0": + version: 5.1.0 + resolution: "ajv-keywords@npm:5.1.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + peerDependencies: + ajv: ^8.8.2 + checksum: 10/5021f96ab7ddd03a4005326bd06f45f448ebfbb0fe7018b1b70b6c28142fa68372bda2057359814b83fd0b2d4c8726c297f0a7557b15377be7b56ce5344533d8 + languageName: node + linkType: hard + "ajv@npm:^6.12.4": version: 6.12.6 resolution: "ajv@npm:6.12.6"