@kubb/core 1.0.0-alpha.6 → 1.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ /* eslint-disable no-param-reassign */
2
+ /* eslint-disable consistent-return */
3
+
4
+ export interface Cache<T extends object = object> {
5
+ delete(id: keyof T): boolean
6
+ get(id: keyof T): T[keyof T] | null
7
+ has(id: keyof T): boolean
8
+ set(id: keyof T, value: unknown): void
9
+ }
10
+
11
+ export function createPluginCache<T extends Record<string, [number, unknown]>>(cache: T): Cache<T> {
12
+ return {
13
+ delete(id: keyof T) {
14
+ return delete cache[id]
15
+ },
16
+ get(id) {
17
+ const item = cache[id]
18
+ if (!item) return null
19
+ item[0] = 0
20
+ return item[1] as T[keyof T]
21
+ },
22
+ has(id) {
23
+ const item = cache[id]
24
+ if (!item) return false
25
+ item[0] = 0
26
+ return true
27
+ },
28
+ set(id, value) {
29
+ cache[id] = [0, value] as T[keyof T]
30
+ },
31
+ }
32
+ }
@@ -0,0 +1,10 @@
1
+ /* eslint-disable no-param-reassign */
2
+ export function getUniqueName(originalName: string, data: Record<string, number>) {
3
+ let used = data[originalName] || 0
4
+ if (used) {
5
+ data[originalName] = ++used
6
+ originalName += used
7
+ }
8
+ data[originalName] = 1
9
+ return originalName
10
+ }
@@ -0,0 +1,11 @@
1
+ export * from './isPromise'
2
+ export * from './write'
3
+ export * from './cache'
4
+ export * from './read'
5
+ export * from './isURL'
6
+ export * from './objectToParameters'
7
+ export * from './nameSorter'
8
+ export * from './jsdoc'
9
+ export * from './getUniqueName'
10
+ export * from './timeout'
11
+ export * from './queue'
@@ -0,0 +1,5 @@
1
+ import type { MaybePromise } from '../types'
2
+
3
+ export function isPromise<T>(result: MaybePromise<T>): result is Promise<T> {
4
+ return typeof (result as Promise<unknown>)?.then === 'function'
5
+ }
@@ -0,0 +1,11 @@
1
+ export function isURL(data: string) {
2
+ try {
3
+ const url = new URL(data)
4
+ if (url?.href) {
5
+ return true
6
+ }
7
+ } catch (error) {
8
+ return false
9
+ }
10
+ return false
11
+ }
@@ -0,0 +1,13 @@
1
+ export function createJSDocBlockText({ comments }: { comments: Array<string | undefined> }) {
2
+ const filteredComments = comments.filter(Boolean)
3
+
4
+ if (!filteredComments.length) {
5
+ return undefined
6
+ }
7
+
8
+ const text = filteredComments.reduce((acc, comment) => {
9
+ return `${acc}\n* ${comment}`
10
+ }, '/**')
11
+
12
+ return `${text}\n*/`
13
+ }
@@ -0,0 +1,9 @@
1
+ export function nameSorter<T extends { name: string }>(a: T, b: T) {
2
+ if (a.name < b.name) {
3
+ return -1
4
+ }
5
+ if (a.name > b.name) {
6
+ return 1
7
+ }
8
+ return 0
9
+ }
@@ -0,0 +1,19 @@
1
+ type Data = string[][]
2
+
3
+ type Options = {
4
+ typed?: boolean
5
+ }
6
+
7
+ export function objectToParameters(data: Data, options: Options = {}) {
8
+ return data
9
+ .reduce((acc, [key, value]) => {
10
+ if (options.typed) {
11
+ acc.push(`${key}: ${value}["${key}"], `)
12
+ } else {
13
+ acc.push(`${key},`)
14
+ }
15
+
16
+ return acc
17
+ }, [] as string[])
18
+ .join('')
19
+ }
@@ -0,0 +1,46 @@
1
+ /* eslint-disable no-cond-assign */
2
+
3
+ export type QueueTask<T = unknown> = {
4
+ (...args: unknown[]): Promise<T>
5
+ }
6
+
7
+ interface QueueItem {
8
+ reject: <T>(reason?: T) => void
9
+ resolve: <T>(value: T | PromiseLike<T>) => void
10
+ task: QueueTask<unknown>
11
+ }
12
+
13
+ export class Queue {
14
+ private readonly queue: QueueItem[] = []
15
+
16
+ workerCount = 0
17
+
18
+ private maxParallel: number
19
+
20
+ constructor(maxParallel: number) {
21
+ this.maxParallel = maxParallel
22
+ }
23
+
24
+ run<T>(task: QueueTask<T>): Promise<T> {
25
+ return new Promise<T>((resolve, reject) => {
26
+ const item: QueueItem = { reject, resolve, task } as QueueItem
27
+ this.queue.push(item)
28
+ this.work()
29
+ })
30
+ }
31
+
32
+ private async work(): Promise<void> {
33
+ if (this.workerCount >= this.maxParallel) return
34
+ this.workerCount++
35
+
36
+ let entry: QueueItem | undefined
37
+ while ((entry = this.queue.shift())) {
38
+ const { reject, resolve, task } = entry
39
+ task()
40
+ .then((result) => resolve(result))
41
+ .catch((err) => reject(err))
42
+ }
43
+
44
+ this.workerCount--
45
+ }
46
+ }
@@ -0,0 +1,48 @@
1
+ import pathParser from 'path'
2
+ import { promises as fs } from 'fs'
3
+
4
+ function slash(path: string) {
5
+ const isExtendedLengthPath = /^\\\\\?\\/.test(path)
6
+
7
+ if (isExtendedLengthPath) {
8
+ return path
9
+ }
10
+
11
+ return path.replace(/\\/g, '/')
12
+ }
13
+
14
+ export function getRelativePath(rootDir?: string | null, filePath?: string | null) {
15
+ if (!rootDir || !filePath) {
16
+ throw new Error('Root and file should be filled in when retrieving the relativePath')
17
+ }
18
+
19
+ const relativePath = pathParser.relative(rootDir, filePath)
20
+
21
+ // On Windows, paths are separated with a "\"
22
+ // However, web browsers use "/" no matter the platform
23
+ const path = slash(relativePath).replace('../', '').trimEnd()
24
+
25
+ if (path.startsWith('../')) {
26
+ return path.replace(pathParser.basename(path), pathParser.basename(path, pathParser.extname(filePath)))
27
+ }
28
+
29
+ return `./${path.replace(pathParser.basename(path), pathParser.basename(path, pathParser.extname(filePath)))}`
30
+ }
31
+
32
+ export type PathMode = 'file' | 'directory'
33
+
34
+ export function getPathMode(path: string | undefined | null): PathMode {
35
+ if (!path) {
36
+ return 'directory'
37
+ }
38
+ return pathParser.extname(path) ? 'file' : 'directory'
39
+ }
40
+
41
+ export async function read(path: string) {
42
+ try {
43
+ return fs.readFile(path, { encoding: 'utf8' })
44
+ } catch (err) {
45
+ console.error(err)
46
+ throw err
47
+ }
48
+ }
@@ -0,0 +1,7 @@
1
+ export async function timeout(ms: number) {
2
+ return new Promise((resolve) => {
3
+ setTimeout(() => {
4
+ resolve(true)
5
+ }, ms)
6
+ })
7
+ }
@@ -0,0 +1,40 @@
1
+ /* eslint-disable consistent-return */
2
+ import { promises as fs } from 'fs'
3
+ import pathParser from 'path'
4
+
5
+ import rimraf from 'rimraf'
6
+
7
+ async function safeWriteFileToPath(path: string, data: string) {
8
+ // resolve the full path and get just the directory, ignoring the file and extension
9
+ const passedPath = pathParser.dirname(pathParser.resolve(path))
10
+ // make the directory, recursively. Theoretically, if every directory in the path exists, this won't do anything.
11
+ await fs.mkdir(passedPath, { recursive: true })
12
+ // write the file to the newly created directory
13
+ return fs.writeFile(pathParser.resolve(path), data, { encoding: 'utf-8' })
14
+ }
15
+
16
+ export async function write(data: string, path: string) {
17
+ try {
18
+ await fs.stat(path)
19
+ const oldContent = await fs.readFile(path, { encoding: 'utf-8' })
20
+ if (oldContent?.toString() === data) {
21
+ return
22
+ }
23
+ } catch (_err) {
24
+ return safeWriteFileToPath(path, data)
25
+ }
26
+
27
+ return safeWriteFileToPath(path, data)
28
+ }
29
+
30
+ export async function clean(path: string) {
31
+ return new Promise((resolve, reject) => {
32
+ rimraf(path, (err) => {
33
+ if (err) {
34
+ reject(err)
35
+ } else {
36
+ resolve(true)
37
+ }
38
+ })
39
+ })
40
+ }