vue-useurl
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -1,2 +0,2 @@ | ||
import { Ref, UnwrapRef, ComputedRef } from "vue-demi"; | ||
import { ComputedRef, Ref, UnwrapRef } from 'vue-demi'; | ||
export type MaybeRef<T> = T | Ref<T>; | ||
@@ -11,3 +11,3 @@ export type MaybeReactive<T> = T | UnwrapRef<T>; | ||
hash?: MaybeRef<string | number>; | ||
disableCSV?: MaybeRef<boolean>; | ||
arraySerializer?: (array: unknown[]) => string; | ||
} | ||
@@ -19,3 +19,3 @@ export interface IBuilderResult { | ||
hash: Ref<string | number>; | ||
disableCSV: Ref<boolean>; | ||
arraySerializer: (array: unknown[]) => string; | ||
url: ComputedRef<string>; | ||
@@ -25,4 +25,2 @@ setUrl: (url: ComputedRef<string>) => void; | ||
export declare class BuilderResult implements IBuilderResult { | ||
constructor(path: MaybeRef<string>, pathVariables: MaybeReactive<IPathVariables>, queryParams: MaybeReactive<IQueryParams>, hash: MaybeRef<string>, disableCSV: MaybeRef<boolean>); | ||
setUrl(url: ComputedRef<string>): void; | ||
path: Ref<string>; | ||
@@ -32,12 +30,14 @@ pathVariables: UnwrapRef<IPathVariables>; | ||
hash: Ref<string>; | ||
disableCSV: Ref<boolean>; | ||
arraySerializer: (array: unknown[]) => string; | ||
url: ComputedRef<string>; | ||
constructor(path: MaybeRef<string>, pathVariables: MaybeReactive<IPathVariables>, queryParams: MaybeReactive<IQueryParams>, hash: MaybeRef<string>, arraySerializer: (array: unknown[]) => string); | ||
setUrl(url: ComputedRef<string>): void; | ||
} | ||
export declare class UrlBuilder { | ||
baseUrl: string; | ||
private defaultSerializer; | ||
constructor(baseUrl?: string | null | undefined); | ||
buildHash(url: string, hash: string | number): string; | ||
buildPathVariables(url: string, pathVariables: IPathVariables): string; | ||
buildQueryParams(url: string, queryParams: IQueryParams, disableCSV?: boolean): string; | ||
buildCSV(key: string, param: any, disableCSV: boolean): string[] | any[]; | ||
buildQueryParams(url: string, queryParams: IQueryParams, arraySerializer?: (array: unknown[]) => string): string; | ||
} | ||
@@ -44,0 +44,0 @@ declare const useUrl: (options: IUrlOptions | any, baseUrl?: string) => IBuilderResult; |
@@ -1,4 +0,10 @@ | ||
import { ref, reactive, computed, isReactive } from "vue-demi"; | ||
import { computed, isReactive, reactive, ref } from 'vue-demi'; | ||
export class BuilderResult { | ||
constructor(path, pathVariables, queryParams, hash, disableCSV) { | ||
path; | ||
pathVariables; | ||
queryParams; | ||
hash; | ||
arraySerializer; | ||
url; | ||
constructor(path, pathVariables, queryParams, hash, arraySerializer) { | ||
this.path = ref(path); | ||
@@ -8,4 +14,4 @@ this.pathVariables = reactive(pathVariables); | ||
this.hash = ref(hash); | ||
this.disableCSV = ref(disableCSV); | ||
this.url = computed(() => ""); | ||
this.arraySerializer = arraySerializer; | ||
this.url = computed(() => ''); | ||
} | ||
@@ -15,18 +21,15 @@ setUrl(url) { | ||
} | ||
path; | ||
pathVariables; | ||
queryParams; | ||
hash; | ||
disableCSV; | ||
url; | ||
} | ||
export class UrlBuilder { | ||
baseUrl; | ||
defaultSerializer; | ||
constructor(baseUrl) { | ||
this.baseUrl = baseUrl ?? ""; | ||
this.baseUrl = baseUrl ?? ''; | ||
this.defaultSerializer = v => v.join(','); | ||
} | ||
buildHash(url, hash) { | ||
hash = hash ? `#${hash}` : ''; | ||
if (url.match(/#.+/gi)) | ||
return url.replace(/#.+/gi, `#${hash}`); | ||
return `${url}#${hash}`; | ||
return url.replace(/#.+/gi, `${hash}`); | ||
return `${url}${hash}`; | ||
} | ||
@@ -36,44 +39,30 @@ buildPathVariables(url, pathVariables) { | ||
const value = Object.values(pathVariables)[index]; | ||
url = url.replace(/:([^\/]+)/gi, isReactive(value) ? value.value : value.toString()); | ||
url = url.replace(/:([^\/]+)/gi, isReactive(value) ? value.value : value?.toString()); | ||
}); | ||
return url; | ||
} | ||
buildQueryParams(url, queryParams, disableCSV = false) { | ||
url = url.replace(/(\?|\&)([^=]+)\=([^&]+)/gi, ""); | ||
const params = Object.keys(queryParams) | ||
.map((key, index) => { | ||
const param = Object.values(queryParams)[index]; | ||
switch (typeof key) { | ||
default: | ||
return `${key}=${param}`; | ||
case "object": | ||
return this.buildCSV(key, param, disableCSV); | ||
} | ||
}) | ||
.flat() | ||
.filter(x => !!x); | ||
const paramsString = params.length > 0 ? `?${params.join("&")}` : ""; | ||
return url + paramsString; | ||
buildQueryParams(url, queryParams, arraySerializer) { | ||
const serializer = arraySerializer ?? this.defaultSerializer; | ||
Object.entries(queryParams) | ||
.filter(([, value]) => value instanceof Array) | ||
.forEach(([key, value]) => { | ||
queryParams[key] = serializer(value); | ||
}); | ||
const urlObject = new URL(url); | ||
var searchParams = new URLSearchParams(queryParams); | ||
searchParams.forEach((value, key) => urlObject.searchParams.set(key, value)); | ||
return urlObject.toString(); | ||
} | ||
buildCSV(key, param, disableCSV) { | ||
if (Array.isArray(param)) { | ||
if (disableCSV) { | ||
return param.map(p => `${key}=${p}`); | ||
} | ||
return [`${key}=${param.join(",")}`]; | ||
} | ||
return []; | ||
} | ||
} | ||
const useUrl = (options, baseUrl) => { | ||
const builderResult = new BuilderResult(options?.path ?? "", options?.pathVariables ?? {}, options?.queryParams ?? {}, options?.hash ?? "", options?.disableCSV ?? false); | ||
const { queryParams, pathVariables, path, hash, disableCSV } = builderResult; | ||
const builderResult = new BuilderResult(options?.path ?? '', options?.pathVariables ?? {}, options?.queryParams ?? {}, options?.hash ?? '', options?.arraySerializer); | ||
const { queryParams, pathVariables, path, hash, arraySerializer } = builderResult; | ||
const builder = new UrlBuilder(baseUrl); | ||
const computedUrl = computed(() => { | ||
let tempUrl = `${builder.baseUrl}${path.value}`; | ||
tempUrl = tempUrl.replace(/([^:]\/)\/+/g, "$1"); | ||
tempUrl = tempUrl.replace(/([^:]\/)\/+/g, '$1'); | ||
tempUrl = builder.buildPathVariables(tempUrl, pathVariables); | ||
tempUrl = builder.buildQueryParams(tempUrl, queryParams, disableCSV.value); | ||
tempUrl = builder.buildQueryParams(tempUrl, queryParams, arraySerializer); | ||
tempUrl = builder.buildHash(tempUrl, hash.value); | ||
return tempUrl; | ||
return new URL(tempUrl).toString(); | ||
}); | ||
@@ -83,5 +72,3 @@ builderResult.setUrl(computedUrl); | ||
}; | ||
const createUseUrlInstance = () => { | ||
return useUrl; | ||
}; | ||
const createUseUrlInstance = () => useUrl; | ||
export { useUrl, createUseUrlInstance }; |
161
package.json
{ | ||
"name": "vue-useurl", | ||
"version": "1.1.0", | ||
"description": "Reactive Url Builder Vue Composable", | ||
"type": "module", | ||
"exports": "./dist/index.js", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/rainxh11/vue-useurl.git" | ||
}, | ||
"publishConfig": { | ||
"@rainxh11:registry": "https://npm.pkg.github.com" | ||
}, | ||
"files": [ | ||
"dist/**/*" | ||
], | ||
"keywords": [ | ||
"vue", | ||
"compositionapi", | ||
"hooks", | ||
"url", | ||
"urlbuilder", | ||
"vueuse", | ||
"vuehook", | ||
"vue-compositionapi", | ||
"vuejs", | ||
"reactive-url", | ||
"reactive", | ||
"buildurl", | ||
"urlgenerator", | ||
"query", | ||
"querybuilder", | ||
"parameters", | ||
"routing", | ||
"build", | ||
"route", | ||
"api", | ||
"path", | ||
"fetch", | ||
"usefetch" | ||
], | ||
"author": "Ahmed Chakhoum", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/rainxh11/vue-useurl/issues" | ||
}, | ||
"homepage": "https://github.com/rainxh11/vue-useurl#readme", | ||
"dependencies": { | ||
"vue-demi": "^0.13.11" | ||
}, | ||
"peerDependencies": { | ||
"@vue/composition-api": "^1.0.0-rc.1", | ||
"vue": "^2.0.0 || >=3.0.0" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@vue/composition-api": { | ||
"optional": true | ||
} | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^27.4.1", | ||
"@types/node": "^18.15.3", | ||
"@typescript-eslint/eslint-plugin": "^5.17.0", | ||
"@typescript-eslint/parser": "^5.17.0", | ||
"@vueuse/core": "^8.3.1", | ||
"eslint": "^8.12.0", | ||
"jest": "^27.5.1", | ||
"prettier": "^2.8.2", | ||
"ts-jest": "^27.1.4", | ||
"ts-node": "^10.7.0", | ||
"typescript": "^4.6.4" | ||
}, | ||
"scripts": { | ||
"test_code": "npx ts-node ./test/test.ts", | ||
"test": "jest --config jestconfig.json", | ||
"build": "npx tsc -b", | ||
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", | ||
"lint": "eslint -p tsconfig.json" | ||
} | ||
"name": "vue-useurl", | ||
"version": "1.2.0", | ||
"description": "Reactive Url Builder Vue Composable", | ||
"type": "module", | ||
"exports": "./dist/index.js", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"scripts": { | ||
"test_code": "npx ts-node ./test/test.ts", | ||
"test": "jest --config jestconfig.json", | ||
"build": "npx tsc -b", | ||
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", | ||
"lint": "eslint -p tsconfig.json" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/rainxh11/vue-useurl.git" | ||
}, | ||
"publishConfig": { | ||
"@rainxh11:registry": "https://npm.pkg.github.com" | ||
}, | ||
"files": [ | ||
"dist/**/*" | ||
], | ||
"keywords": [ | ||
"vue", | ||
"compositionapi", | ||
"hooks", | ||
"url", | ||
"urlbuilder", | ||
"vueuse", | ||
"vuehook", | ||
"vue-compositionapi", | ||
"vuejs", | ||
"reactive-url", | ||
"reactive", | ||
"buildurl", | ||
"urlgenerator", | ||
"query", | ||
"querybuilder", | ||
"parameters", | ||
"routing", | ||
"build", | ||
"route", | ||
"api", | ||
"path", | ||
"fetch", | ||
"usefetch" | ||
], | ||
"author": "Ahmed Chakhoum", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/rainxh11/vue-useurl/issues" | ||
}, | ||
"homepage": "https://github.com/rainxh11/vue-useurl#readme", | ||
"dependencies": { | ||
"vue-demi": "^0.14.7" | ||
}, | ||
"peerDependencies": { | ||
"@vue/composition-api": "^1.0.0-rc.1", | ||
"vue": "^2.0.0 || >=3.0.0" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@vue/composition-api": { | ||
"optional": true | ||
} | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^29.5.12", | ||
"@types/node": "^20.11.19", | ||
"@typescript-eslint/eslint-plugin": "^7.0.1", | ||
"@typescript-eslint/parser": "^7.0.1", | ||
"@vueuse/core": "^10.7.2", | ||
"eslint": "^8.56.0", | ||
"eslint-plugin-vue": "^9.21.1", | ||
"jest": "^27.5.1", | ||
"prettier": "^3.2.5", | ||
"ts-jest": "^29.1.2", | ||
"ts-node": "^10.9.2", | ||
"typescript": "^5.3.3" | ||
} | ||
} |
213
README.md
<img src="https://raw.githubusercontent.com/rainxh11/vue-useurl/master/assets/logo.svg" width="300"> | ||
# 🔗 Vue-useUrl | ||
## Reactive Url Builder Vue Composable for Vue 2 & Vue 3 | ||
# 🔗 Vue-useUrl | ||
## Reactive Url Builder Vue Composable for Vue 2 & Vue 3 | ||
[![NPM version](https://img.shields.io/npm/v/vue-useurl.svg)](https://www.npmjs.com/package/vue-useurl) | ||
A library for building URL using ***(Query Parameters, Path Variables, Hash, Path)*** while being reactive and ready to use as Vue Composition API Composable | ||
A library for building URL using ***(Query Parameters, Path Variables, Hash, Path)*** while being reactive and ready to | ||
use as Vue Composition API Composable | ||
@@ -23,21 +26,21 @@ ## Installation | ||
const params = { | ||
search: 'ahmed', | ||
limit: 50, | ||
page: 12, | ||
sort: 'CreatedOn', | ||
types: ['Cancelled', 'OnGoing'] | ||
search: 'ahmed', | ||
limit: 50, | ||
page: 12, | ||
sort: 'CreatedOn', | ||
types: ['Cancelled', 'OnGoing'] | ||
} | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl({ | ||
path: '/api/v1/users/:id/search', | ||
pathVariables: { | ||
id: 451 | ||
}, | ||
queryParams: { | ||
...params | ||
}, | ||
hash: 'someHash', | ||
disableCSV: false | ||
}, | ||
'http://api.com') | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl({ | ||
path: '/api/v1/users/:id/search', | ||
pathVariables: { | ||
id: 451 | ||
}, | ||
queryParams: { | ||
...params | ||
}, | ||
hash: 'someHash', | ||
arraySerializer: (v) => v.join(',') | ||
}, | ||
'http://api.com') | ||
``` | ||
@@ -48,19 +51,24 @@ | ||
The `userUrl` function accepts two arguments. The first is 'options' of type IUrlOptions e.g: | ||
```ts | ||
import { useUrl } from 'vue-useurl' | ||
{ | ||
path: '/path/path1', // URL Path | ||
pathVariables: { | ||
id: 451 | ||
}, // Path variables e.g: /:id/ | ||
queryParams: { | ||
limit:10, | ||
sortBy: 'property', | ||
page: 1 | ||
}, // Query parameters | ||
hash: 'someHash', // Hash | ||
disableCSV: false | ||
// Enabled: param=1¶m=2¶m=3 | ||
// Disabled: param=1,2,3 | ||
} | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl( | ||
{ | ||
path: '/path/path1', // URL Path | ||
pathVariables: | ||
{ | ||
id: 451 | ||
} | ||
, // Path variables e.g: /:id/ | ||
queryParams: { | ||
limit: 10, | ||
sortBy: | ||
'property', | ||
page: | ||
1 | ||
} | ||
, // Query parameters | ||
hash: 'someHash', // Hash | ||
}) | ||
``` | ||
@@ -71,12 +79,11 @@ | ||
```ts | ||
useUrl({ | ||
path: '/about', | ||
queryParams: { | ||
foo:'bar', | ||
fizz: 'baz' | ||
}, | ||
hash: 'contact', | ||
disableCSV: false | ||
}, | ||
'http://api.com') | ||
useUrl({ | ||
path: '/about', | ||
queryParams: { | ||
foo: 'bar', | ||
fizz: 'baz' | ||
}, | ||
hash: 'contact', | ||
}, | ||
'http://api.com') | ||
@@ -86,3 +93,4 @@ // returns http://api.com/about?foo=bar&bar=baz#contact | ||
Variables returned by `useUrl()` are all reactive objects, changing any of: `path` `queryParams` `pathVariables` `hash` `disableCSV` will rebuild `url` | ||
Variables returned by `useUrl()` are all reactive objects, changing any | ||
of: `path` `queryParams` `pathVariables` `hash` `arraySerializer` will rebuild `url` | ||
@@ -95,3 +103,6 @@ ```ts | ||
This library is compatible with VueUse `useFetch()`, and `url` returned from `useUrl()` can easily be used to trigger auto-reftech if option `{ refetch: true }` is passed to `useFetch()` which make for intuitive and easy way to work with url parametes and variables without the need to modify url string directly | ||
This library is compatible with VueUse `useFetch()`, and `url` returned from `useUrl()` can easily be used to trigger | ||
auto-reftech if option `{ refetch: true }` is passed to `useFetch()` which make for intuitive and easy way to work with | ||
url parametes and variables without the need to modify url string directly | ||
```ts | ||
@@ -101,24 +112,21 @@ import { useFetch } from "@vueuse/core" | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl({ | ||
path: '/api/v1/users/:id/search', | ||
pathVariables: { | ||
id: 451 | ||
}, | ||
queryParams: { | ||
search: 'ahmed', | ||
limit: 50, | ||
page: 12, | ||
sort: 'CreatedOn', | ||
types: ['Cancelled', 'OnGoing'] | ||
}, | ||
hash: 'hashtag', | ||
disableCSV: false | ||
}, | ||
'http://api.com') | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl({ | ||
path: '/api/v1/users/:id/search', | ||
pathVariables: { | ||
id: 451 | ||
}, | ||
queryParams: { | ||
search: 'ahmed', | ||
limit: 50, | ||
page: 12, | ||
sort: 'CreatedOn', | ||
types: ['Cancelled', 'OnGoing'] | ||
}, | ||
hash: 'hashtag', | ||
}, | ||
'http://api.com') | ||
const { isFetching, error, data } = useFetch( | ||
url, | ||
{ initialData: { results: [] }, refetch: true}) | ||
.get() | ||
.json() | ||
const { isFetching, error, data } = useFetch(url, { initialData: { results: [] }, refetch: true }) | ||
.get() | ||
.json() | ||
``` | ||
@@ -133,39 +141,40 @@ | ||
export useApi() { | ||
const search = ref('query') // | ||
const filters = ref([ 'filter1', 'filter2', 'filter3' ]) // declare reactive varibales | ||
export function useApi() | ||
{ | ||
const search = ref('query') // | ||
const filters = ref(['filter1', 'filter2', 'filter3']) // declare reactive varibales | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl({ | ||
path: '/api/v1/users/:id/search', | ||
pathVariables: { | ||
id: 451 | ||
}, | ||
queryParams: { | ||
search: useDebounce(search, 500), // | ||
limit: 50, | ||
page: 12, | ||
sort: 'CreatedOn', | ||
types: useDebounce(filters, 3500) // then pass their reactive backpressure objects instead | ||
}, | ||
hash: 'hashtag', | ||
disableCSV: false | ||
}, | ||
'http://api.com') | ||
const { url, queryParams, pathVariables, hash, path, disableCSV } = useUrl({ | ||
path: '/api/v1/users/:id/search', | ||
pathVariables: { | ||
id: 451 | ||
}, | ||
queryParams: { | ||
search: useDebounce(search, 500), // | ||
limit: 50, | ||
page: 12, | ||
sort: 'CreatedOn', | ||
types: useDebounce(filters, 3500) // then pass their reactive backpressure objects instead | ||
}, | ||
hash: 'hashtag', | ||
disableCSV: false | ||
}, | ||
'http://api.com') | ||
const { isFetching, error, data } = useFetch( | ||
url, | ||
{ initialData: { results: [] }, refetch: true}) | ||
.get() | ||
.json() | ||
const { isFetching, error, data } = useFetch( | ||
url, | ||
{ initialData: { results: [] }, refetch: true }) | ||
.get() | ||
.json() | ||
return { | ||
data, | ||
search, // | ||
filters,// changing this now will trigger the url re-build | ||
queryParams, | ||
pathVariables, | ||
hash, | ||
path, | ||
url | ||
} | ||
return { | ||
data, | ||
search, // | ||
filters,// changing this now will trigger the url re-build | ||
queryParams, | ||
pathVariables, | ||
hash, | ||
path, | ||
url | ||
} | ||
} | ||
@@ -172,0 +181,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
180
0
11753
12
112
+ Addedvue-demi@0.14.7(transitive)
- Removedvue-demi@0.13.11(transitive)
Updatedvue-demi@^0.14.7