diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.yml b/.github/ISSUE_TEMPLATE/1_Bug_report.yml
index 61881ae..bd54b8a 100644
--- a/.github/ISSUE_TEMPLATE/1_Bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/1_Bug_report.yml
@@ -25,9 +25,7 @@ body:
options:
- Alpine
- React
- - React w/ Inertia
- Vue
- - Vue w/ Inertia
validations:
required: true
- type: textarea
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d1687ba..fecd1ab 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -29,23 +29,9 @@ updates:
# Only open pull requests for security updates...
open-pull-requests-limit: 0
- - package-ecosystem: "npm"
- directory: "/packages/react-inertia"
- schedule:
- interval: "daily"
- # Only open pull requests for security updates...
- open-pull-requests-limit: 0
-
- package-ecosystem: "npm"
directory: "/packages/vue"
schedule:
interval: "daily"
# Only open pull requests for security updates...
open-pull-requests-limit: 0
-
- - package-ecosystem: "npm"
- directory: "/packages/vue-inertia"
- schedule:
- interval: "daily"
- # Only open pull requests for security updates...
- open-pull-requests-limit: 0
diff --git a/bin/release b/bin/release
index 472f07c..d9df572 100755
--- a/bin/release
+++ b/bin/release
@@ -13,7 +13,5 @@ fi
npm version $1 \
--workspace=packages/core \
--workspace=packages/react \
- --workspace=packages/react-inertia \
--workspace=packages/vue \
- --workspace=packages/vue-inertia \
--workspace=packages/alpine
diff --git a/package.json b/package.json
index ff11e35..0e26e66 100644
--- a/package.json
+++ b/package.json
@@ -4,13 +4,11 @@
"workspaces": [
"packages/core",
"packages/react",
- "packages/react-inertia",
"packages/vue",
- "packages/vue-inertia",
"packages/alpine"
],
"scripts": {
- "watch": "npx concurrently \"npm run watch --workspace=packages/core\" \"npm run watch --workspace=packages/react\" \"npm run watch --workspace=packages/react-inertia\" \"npm run watch --workspace=packages/vue\" \"npm run watch --workspace=packages/vue-inertia\" \"npm run watch --workspace=packages/alpine\" --names=core,react,react-inertia,vue,vue-inertia,alpine",
+ "watch": "npx concurrently \"npm run watch --workspace=packages/core\" \"npm run watch --workspace=packages/react\" \"npm run watch \"npm run watch --workspace=packages/vue\" \"npm run watch \"npm run watch --workspace=packages/alpine\" --names=core,react,vue,alpine",
"build": "npm run build --workspaces",
"link": "npm link --workspaces",
"typeCheck": "npm run typeCheck --workspaces",
diff --git a/packages/react-inertia/.gitignore b/packages/react-inertia/.gitignore
deleted file mode 100644
index c925c21..0000000
--- a/packages/react-inertia/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/dist
-/node_modules
diff --git a/packages/react-inertia/LICENSE.md b/packages/react-inertia/LICENSE.md
deleted file mode 100644
index 79810c8..0000000
--- a/packages/react-inertia/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Taylor Otwell
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/packages/react-inertia/README.md b/packages/react-inertia/README.md
deleted file mode 100644
index 0b20012..0000000
--- a/packages/react-inertia/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Laravel Precognition
-
-
-
-
-
-
-
-## Introduction
-
-Laravel Precognition allows you to anticipate the outcome of a future HTTP request. One of the primary use cases of Precognition is the ability to provide "live" validation in your frontend application.
-
-## Official Documentation
-
-Documentation for Laravel Precognition can be found on the [Laravel website](https://laravel.com/docs/precognition).
-
-## Contributing
-
-Thank you for considering contributing to Laravel Precognition! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
-
-## Code of Conduct
-
-In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
-
-## Security Vulnerabilities
-
-Please review [our security policy](https://github.com/laravel/precognition/security/policy) on how to report security vulnerabilities.
-
-## License
-
-Laravel Precognition is open-sourced software licensed under the [MIT license](LICENSE.md).
diff --git a/packages/react-inertia/package.json b/packages/react-inertia/package.json
deleted file mode 100644
index cc44e3d..0000000
--- a/packages/react-inertia/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "laravel-precognition-react-inertia",
- "version": "0.8.0",
- "description": "Laravel Precognition (React w/ Inertia).",
- "keywords": [
- "laravel",
- "precognition",
- "react",
- "inertia"
- ],
- "homepage": "https://github.com/laravel/precognition",
- "type": "module",
- "repository": {
- "type": "git",
- "url": "https://github.com/laravel/precognition"
- },
- "license": "MIT",
- "author": "Laravel",
- "main": "dist/index.js",
- "files": [
- "/dist"
- ],
- "scripts": {
- "watch": "rm -rf dist && tsc --watch --preserveWatchOutput",
- "build": "rm -rf dist && tsc",
- "typeCheck": "tsc --noEmit",
- "prepublishOnly": "npm run build",
- "test": "vitest run",
- "version": "npm pkg set dependencies.laravel-precognition=$npm_package_version && npm pkg set dependencies.laravel-precognition-react=$npm_package_version"
- },
- "peerDependencies": {
- "@inertiajs/react": "^1.0.0 || ^2.0.0",
- "react": "^18.0.0 || ^19.0.0"
- },
- "dependencies": {
- "laravel-precognition": "0.8.0",
- "laravel-precognition-react": "0.8.0"
- },
- "devDependencies": {
- "@testing-library/react": "^16.3.0",
- "@types/react-dom": "^18.2.4 || ^19.0.0",
- "jsdom": "^27.2.0",
- "typescript": "^5.0.0",
- "vitest": "^2.0.5"
- }
-}
diff --git a/packages/react-inertia/src/index.ts b/packages/react-inertia/src/index.ts
deleted file mode 100644
index 865f001..0000000
--- a/packages/react-inertia/src/index.ts
+++ /dev/null
@@ -1,220 +0,0 @@
-import { NamedInputEvent, RequestMethod, SimpleValidationErrors, toSimpleValidationErrors, ValidationConfig, ValidationErrors, resolveUrl, resolveMethod } from 'laravel-precognition'
-import { useForm as usePrecognitiveForm, client } from 'laravel-precognition-react'
-import { useForm as useInertiaForm } from '@inertiajs/react'
-import { FormDataKeys, FormDataType, VisitOptions } from '@inertiajs/core'
-import { useRef } from 'react'
-import { Form, FormDataConvertible } from './types'
-
-export { client, Form }
-
-export const useForm = >(method: RequestMethod | (() => RequestMethod), url: string | (() => string), inputs: Data, config: ValidationConfig = {}): Form => {
- const booted = useRef(false)
-
- /**
- * The Inertia form.
- */
- // @ts-expect-error
- const inertiaForm = useInertiaForm(inputs)
-
- /**
- * The React form.
- */
- const precognitiveForm = usePrecognitiveForm(method, url, inputs, config)
-
- /**
- * The Inertia set defaults function.
- */
- const inertiaSetDefaults = inertiaForm.setDefaults.bind(inertiaForm)
-
- /**
- * The Inertia submit function.
- */
- const inertiaSubmit = inertiaForm.submit.bind(inertiaForm)
-
- /**
- * The Inertia reset function.
- */
- const inertiaReset = inertiaForm.reset.bind(inertiaForm)
-
- /**
- * The Inertia clear errors function.
- */
- const inertiaClearErrors = inertiaForm.clearErrors.bind(inertiaForm)
-
- /**
- * The Inertia set error function.
- */
- const inertiaSetError = inertiaForm.setError.bind(inertiaForm)
-
- /**
- * The Inertia set data function.
- */
- const inertiaSetData = inertiaForm.setData.bind(inertiaForm)
-
- /**
- * The Inertia trasform function.
- */
- const inertiaTransform = inertiaForm.transform.bind(inertiaForm)
-
- /**
- * The transform function.
- */
- const transformer = useRef<(data: Data) => Data>((data) => data)
-
- if (! booted.current) {
- /**
- * Setup event listeners.
- */
- precognitiveForm.validator().on('errorsChanged', () => {
- inertiaClearErrors()
-
- inertiaSetError(
- // @ts-expect-error
- toSimpleValidationErrors(precognitiveForm.validator().errors()),
- )
- })
-
- booted.current = true
- }
-
- /**
- * Patch the form.
- */
- const form = Object.assign(inertiaForm, {
- validating: precognitiveForm.validating,
- touched: precognitiveForm.touched,
- touch(name: Array | string | NamedInputEvent) {
- precognitiveForm.touch(name)
-
- return form
- },
- valid: precognitiveForm.valid,
- invalid: precognitiveForm.invalid,
- setData(key: any, value?: any) {
- inertiaSetData(key, value)
-
- precognitiveForm.setData(key, value)
-
- return form
- },
- clearErrors(...names: FormDataKeys>[]) {
- inertiaClearErrors(...names)
-
- if (names.length === 0) {
- precognitiveForm.setErrors({})
- } else {
- names.forEach(precognitiveForm.forgetError)
- }
-
- return form
- },
- setDefaults(field?: keyof Data | Partial> | ((previousData: FormDataType) => FormDataType), value?: Data[keyof Data]){
- const data = ((): Partial> => {
- if (typeof field === 'undefined') {
- return inertiaForm.data
- }
-
- if (typeof field === 'function') {
- return field(inertiaForm.data)
- }
-
- if (typeof field === 'object') {
- return field
- }
-
- // @ts-ignore
- return { [field]: value }
- })()
-
- inertiaSetDefaults(data)
-
- precognitiveForm.validator().defaults(data)
- },
- reset(...names: FormDataKeys>[]) {
- inertiaReset(...names)
-
- precognitiveForm.reset(...names)
- },
- setErrors(errors: SimpleValidationErrors | ValidationErrors) {
- // @ts-expect-error
- precognitiveForm.setErrors(errors)
-
- return form
- },
- setError(key: any, value?: any) {
- form.setErrors({
- ...inertiaForm.errors,
- ...typeof value === 'undefined'
- ? key
- : { [key]: value },
- })
-
- return form
- },
- forgetError(name: string | NamedInputEvent) {
- precognitiveForm.forgetError(name)
-
- return form
- },
- transform(callback: (data: Data) => Data) {
- inertiaTransform(callback)
-
- transformer.current = callback
-
- return form
- },
- validate(name?: string | NamedInputEvent | ValidationConfig, config?: ValidationConfig) {
- precognitiveForm.setData(transformer.current(inertiaForm.data))
-
- if (typeof name === 'object' && !('target' in name)) {
- config = name
- name = undefined
- }
-
- if (typeof name === 'undefined') {
- precognitiveForm.validate(config)
- } else {
- precognitiveForm.validate(name, config)
- }
-
- return form
- },
- setValidationTimeout(duration: number) {
- precognitiveForm.setValidationTimeout(duration)
-
- return form
- },
- validateFiles() {
- precognitiveForm.validateFiles()
-
- return form
- },
- withoutFileValidation() {
- precognitiveForm.withoutFileValidation()
-
- return form
- },
- submit(submitMethod: RequestMethod | Omit = {}, submitUrl?: string, submitOptions?: Omit): void {
- if (typeof submitMethod !== 'string') {
- submitOptions = submitMethod
- submitUrl = resolveUrl(url)
- submitMethod = resolveMethod(method)
- }
-
- inertiaSubmit(submitMethod, submitUrl!, {
- ...submitOptions,
- onError: (errors: SimpleValidationErrors): any => {
- precognitiveForm.validator().setErrors(errors)
-
- if (submitOptions?.onError) {
- return submitOptions.onError(errors)
- }
- },
- })
- },
- validator: precognitiveForm.validator,
- })
-
- // @ts-expect-error
- return form
-}
diff --git a/packages/react-inertia/src/types.ts b/packages/react-inertia/src/types.ts
deleted file mode 100644
index d8cd734..0000000
--- a/packages/react-inertia/src/types.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { NamedInputEvent, RequestMethod, SimpleValidationErrors, ValidationConfig, ValidationErrors } from 'laravel-precognition'
-import { Form as PrecognitiveForm } from 'laravel-precognition-react/dist/types'
-import { InertiaFormProps } from '@inertiajs/react'
-import { VisitOptions } from '@inertiajs/core'
-
-type RedefinedProperties = 'setErrors' | 'touch' | 'forgetError' | 'setValidationTimeout' | 'submit' | 'reset' | 'validateFiles' | 'setData' | 'validate'
-
-export type Form> = Omit, RedefinedProperties> & InertiaFormProps & {
- setErrors(errors: SimpleValidationErrors | ValidationErrors): Form,
- touch(name: Array | string | NamedInputEvent): Form,
- forgetError(string: keyof Data | NamedInputEvent): Form,
- setValidationTimeout(duration: number): Form,
- submit(config?: Omit): void,
- submit(method: RequestMethod, url: string, options?: Omit): void,
- reset(...keys: (keyof Partial)[]): void,
- validateFiles(): Form,
- withoutFileValidation(): Form,
- setData(data: Record): Form,
- validate(name?: (keyof Data | NamedInputEvent) | ValidationConfig, config?: ValidationConfig): Form,
- setDefaults(): void,
- setDefaults(defaults: Partial): void,
- setDefaults(defaults: (previousData: Data) => Data): void,
- setDefaults(field: K, value: Data[K]): void,
-}
-
-// This type has been duplicated from @inertiajs/core to
-// continue supporting Inertia 1. When we drop version 1
-// support we can import this directly from Inertia.
-export type FormDataConvertible = Array | {
- [key: string]: FormDataConvertible;
-} | Blob | FormDataEntryValue | Date | boolean | number | null | undefined;
-
diff --git a/packages/react-inertia/tests/index.test.ts b/packages/react-inertia/tests/index.test.ts
deleted file mode 100644
index 864ff0d..0000000
--- a/packages/react-inertia/tests/index.test.ts
+++ /dev/null
@@ -1,235 +0,0 @@
-import { it, expect, beforeEach, afterEach, vi } from 'vitest'
-import { renderHook, act } from '@testing-library/react'
-import { useForm, client } from '../src/index'
-import axios from 'axios'
-import { Config } from 'laravel-precognition'
-
-beforeEach(() => {
- vi.mock('axios')
- client.use(axios)
-})
-
-afterEach(() => {
- vi.restoreAllMocks()
-})
-
-it('can clear all errors via Inertia\'s clearErrors', () => {
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: '',
- }))
-
- act(() => form.current.setErrors({
- name: 'xxxx',
- other: 'xxxx',
- }))
-
- expect(form.current.errors).toEqual({
- name: 'xxxx',
- other: 'xxxx',
- })
-
- act(() => form.current.clearErrors())
-
- expect(form.current.errors).toEqual({})
- expect(form.current.validator().errors()).toEqual({})
-})
-
-it('can clear specific errors via Inertia\'s clearErrors', () => {
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: '',
- }))
-
- act(() => form.current.setErrors({
- name: 'xxxx',
- email: 'xxxx',
- other: 'xxxx',
- }))
-
- expect(form.current.errors).toEqual({
- name: 'xxxx',
- email: 'xxxx',
- other: 'xxxx',
- })
-
- act(() => form.current.clearErrors('name', 'email'))
-
- expect(form.current.errors).toEqual({
- other: 'xxxx',
- })
- expect(form.current.validator().errors()).toEqual({
- other: ['xxxx'],
- })
-})
-
-it('provides default data for validation requests', () => {
- const response = { headers: { precognition: 'true', 'precognition-success': 'true' }, status: 204, data: 'data' }
-
- let config: Config
- axios.request.mockImplementation(async (c: Config) => {
- config = c
-
- return response
- })
-
- const { result: form } = renderHook(() => useForm('post', '/register', {
- emails: '',
- }))
-
- act(() => form.current.setData('emails', 'taylor@laravel.com, tim@laravel.com'))
- act(() => form.current.validate('emails'))
-
- expect(config!.data.emails).toEqual('taylor@laravel.com, tim@laravel.com')
- expect(form.current.data.emails).toBe('taylor@laravel.com, tim@laravel.com')
-})
-
-it('transforms data for validation requests', () => {
- const response = { headers: { precognition: 'true', 'precognition-success': 'true' }, status: 204, data: 'data' }
-
- let config: Config
- axios.request.mockImplementation(async (c: Config) => {
- config = c
-
- return response
- })
-
- const { result: form } = renderHook(() => useForm('post', '/register', {
- emails: '',
- }))
-
- act(() => form.current.transform((data) => ({
- emails: data.emails.split(',').map((email: string) => email.trim()),
- })))
-
- act(() => form.current.setData('emails', 'taylor@laravel.com, tim@laravel.com'))
- act(() => form.current.validate('emails'))
-
- expect(config!.data.emails).toEqual(['taylor@laravel.com', 'tim@laravel.com'])
- expect(form.current.data.emails).toBe('taylor@laravel.com, tim@laravel.com')
-})
-
-it('can set individual errors', function () {
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: '',
- }))
-
- act(() => form.current.setError('name', 'The name is required.'))
-
- expect(form.current.errors.name).toBe('The name is required.')
-})
-
-it('can check that specific fields have been touched', () => {
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: '',
- email: '',
- }))
-
- expect(form.current.touched('name')).toBe(false)
- expect(form.current.touched('email')).toBe(false)
-
- act(() => form.current.touch('name'))
-
- expect(form.current.touched('name')).toBe(true)
- expect(form.current.touched('email')).toBe(false)
-})
-
-it('can check it any fields have been touched', () => {
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: '',
- email: '',
- }))
-
- expect(form.current.touched()).toBe(false)
-
- act(() => form.current.touch('name'))
-
- expect(form.current.touched()).toBe(true)
-})
-
-it('can set defaults with no arguments', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: 'John',
- }))
-
- act(() => form.current.setData('name', 'Jane'))
- act(() => form.current.setDefaults())
-
- act(() => form.current.setData('name', 'John'))
- act(() => form.current.reset())
- expect(form.current.data.name).toBe('Jane')
-
- act(() => form.current.validate('name'))
- expect(requests).toBe(0)
-})
-
-it('can set defaults with an object', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: 'John',
- }))
-
- act(() => form.current.setDefaults({ name: 'Jane' }))
-
- act(() => form.current.setData('name', 'John'))
- act(() => form.current.reset())
- expect(form.current.data.name).toBe('Jane')
-
- act(() => form.current.validate('name'))
- expect(requests).toBe(0)
-})
-
-it('can set defaults with a function', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: 'John',
- }))
-
- act(() => form.current.setDefaults((prevData: any) => {
- expect(prevData).toEqual({
- name: 'John',
- })
-
- return {
- name: 'Jane',
- }
- }))
-
- act(() => form.current.setData('name', 'John'))
- act(() => form.current.reset())
- expect(form.current.data.name).toBe('Jane')
-
- act(() => form.current.validate('name'))
- expect(requests).toBe(0)
-})
-
-it('can set defaults with a field and value', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const { result: form } = renderHook(() => useForm('post', '/register', {
- name: 'John',
- }))
-
- act(() => form.current.setDefaults('name', 'Jane'))
-
- act(() => form.current.setData('name', 'John'))
- act(() => form.current.reset())
- expect(form.current.data.name).toBe('Jane')
-
- act(() => form.current.validate('name'))
- expect(requests).toBe(0)
-})
diff --git a/packages/react-inertia/tsconfig.json b/packages/react-inertia/tsconfig.json
deleted file mode 100644
index d926f37..0000000
--- a/packages/react-inertia/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "compilerOptions": {
- "outDir": "./dist",
- "target": "ES2020",
- "module": "ES2020",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "strict": true,
- "declaration": true,
- "esModuleInterop": true
- },
- "include": [
- "./src/index.ts"
- ]
-}
diff --git a/packages/react-inertia/vitest.config.ts b/packages/react-inertia/vitest.config.ts
deleted file mode 100644
index e7ef8ea..0000000
--- a/packages/react-inertia/vitest.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- environment: 'jsdom',
- },
-})
diff --git a/packages/vue-inertia/.gitignore b/packages/vue-inertia/.gitignore
deleted file mode 100644
index c925c21..0000000
--- a/packages/vue-inertia/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/dist
-/node_modules
diff --git a/packages/vue-inertia/LICENSE.md b/packages/vue-inertia/LICENSE.md
deleted file mode 100644
index 79810c8..0000000
--- a/packages/vue-inertia/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Taylor Otwell
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/packages/vue-inertia/README.md b/packages/vue-inertia/README.md
deleted file mode 100644
index 0b20012..0000000
--- a/packages/vue-inertia/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Laravel Precognition
-
-
-
-
-
-
-
-## Introduction
-
-Laravel Precognition allows you to anticipate the outcome of a future HTTP request. One of the primary use cases of Precognition is the ability to provide "live" validation in your frontend application.
-
-## Official Documentation
-
-Documentation for Laravel Precognition can be found on the [Laravel website](https://laravel.com/docs/precognition).
-
-## Contributing
-
-Thank you for considering contributing to Laravel Precognition! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
-
-## Code of Conduct
-
-In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
-
-## Security Vulnerabilities
-
-Please review [our security policy](https://github.com/laravel/precognition/security/policy) on how to report security vulnerabilities.
-
-## License
-
-Laravel Precognition is open-sourced software licensed under the [MIT license](LICENSE.md).
diff --git a/packages/vue-inertia/package.json b/packages/vue-inertia/package.json
deleted file mode 100644
index b5f74f3..0000000
--- a/packages/vue-inertia/package.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "name": "laravel-precognition-vue-inertia",
- "version": "0.8.0",
- "description": "Laravel Precognition (Vue w/ Inertia).",
- "keywords": [
- "laravel",
- "precognition",
- "vue",
- "inertia"
- ],
- "homepage": "https://github.com/laravel/precognition",
- "type": "module",
- "repository": {
- "type": "git",
- "url": "https://github.com/laravel/precognition"
- },
- "license": "MIT",
- "author": "Laravel",
- "main": "dist/index.js",
- "files": [
- "/dist"
- ],
- "scripts": {
- "watch": "rm -rf dist && tsc --watch --preserveWatchOutput",
- "build": "rm -rf dist && tsc",
- "typeCheck": "tsc --noEmit",
- "prepublishOnly": "npm run build",
- "test": "vitest run",
- "version": "npm pkg set dependencies.laravel-precognition=$npm_package_version && npm pkg set dependencies.laravel-precognition-vue=$npm_package_version"
- },
- "peerDependencies": {
- "@inertiajs/vue3": "^1.0.0 || ^2.0.0",
- "vue": "^3.0.0"
- },
- "dependencies": {
- "laravel-precognition": "0.8.0",
- "laravel-precognition-vue": "0.8.0"
- },
- "devDependencies": {
- "typescript": "^5.0.0",
- "vitest": "^2.0.5"
- }
-}
diff --git a/packages/vue-inertia/src/index.ts b/packages/vue-inertia/src/index.ts
deleted file mode 100644
index 79feb05..0000000
--- a/packages/vue-inertia/src/index.ts
+++ /dev/null
@@ -1,230 +0,0 @@
-import { NamedInputEvent, RequestMethod, SimpleValidationErrors, toSimpleValidationErrors, ValidationConfig, ValidationErrors, resolveUrl, resolveMethod } from 'laravel-precognition'
-import { useForm as usePrecognitiveForm, client } from 'laravel-precognition-vue'
-import { useForm as useInertiaForm } from '@inertiajs/vue3'
-import { FormDataKeys, FormDataType, VisitOptions } from '@inertiajs/core'
-import { watchEffect } from 'vue'
-import { Form, FormDataConvertible } from './types'
-
-export { client, Form }
-
-export const useForm = >(method: RequestMethod | (() => RequestMethod), url: string | (() => string), inputs: Data | (() => Data), config: ValidationConfig = {}): Form => {
- /**
- * The Inertia form.
- */
- // @ts-expect-error
- const inertiaForm = useInertiaForm(inputs)
-
- /**
- * The Precognitive form.
- */
- const precognitiveForm = usePrecognitiveForm(method, url, inputs, config)
-
- /**
- * Setup event listeners.
- */
- precognitiveForm.validator().on('errorsChanged', () => {
- inertiaClearErrors()
-
- inertiaSetError(
- // @ts-expect-error
- toSimpleValidationErrors(precognitiveForm.validator().errors()),
- )
- })
-
- /**
- * The Inertia defaults function.
- */
- const inertiaDefaults = inertiaForm.defaults.bind(inertiaForm)
-
- /**
- * The Inertia submit function.
- */
- const inertiaSubmit = inertiaForm.submit.bind(inertiaForm)
-
- /**
- * The Inertia reset function.
- */
- const inertiaReset = inertiaForm.reset.bind(inertiaForm)
-
- /**
- * The Inertia clear errors function.
- */
- const inertiaClearErrors = inertiaForm.clearErrors.bind(inertiaForm)
-
- /**
- * The Inertia set error function.
- */
- const inertiaSetError = inertiaForm.setError.bind(inertiaForm)
-
- /**
- * The Inertia trasform function.
- */
- const inertiaTransform = inertiaForm.transform.bind(inertiaForm)
-
- /**
- * The transform function.
- */
- let transformer: (data: Data) => Record = (data) => data
-
- /**
- * Patch the form.
- */
- // @ts-expect-error
- const form: Form = Object.assign(inertiaForm, {
- validating: precognitiveForm.validating,
- touched: precognitiveForm.touched,
- touch(name: Array | string | NamedInputEvent) {
- precognitiveForm.touch(name)
-
- return form
- },
- valid: precognitiveForm.valid,
- invalid: precognitiveForm.invalid,
- setData(data: Record) {
- Object.keys(data).forEach((input) => {
- // @ts-expect-error
- form[input] = data[input]
- })
-
- return form
- },
- clearErrors(...names: FormDataKeys>[]) {
- inertiaClearErrors(...names)
-
- if (names.length === 0) {
- precognitiveForm.setErrors({})
- } else {
- names.forEach(precognitiveForm.forgetError)
- }
-
- return form
- },
- defaults(field?: keyof Data | Partial> | ((previousData: FormDataType) => FormDataType), value?: Data[keyof Data]){
- const data = ((): Partial> => {
- if (typeof field === 'undefined') {
- return inertiaForm.data()
- }
-
- if (typeof field === 'function') {
- return field(inertiaForm.data())
- }
-
- if (typeof field === 'object') {
- return field
- }
-
- // @ts-ignore
- return { [field]: value }
- })()
-
- inertiaDefaults(data)
-
- precognitiveForm.validator().defaults(data)
- },
- reset(...names: FormDataKeys>[]) {
- inertiaReset(...names)
-
- precognitiveForm.reset(...names)
- },
- setErrors(errors: SimpleValidationErrors | ValidationErrors) {
- // @ts-expect-error
- precognitiveForm.setErrors(errors)
-
- return form
- },
- forgetError(name: string | NamedInputEvent) {
- precognitiveForm.forgetError(name)
-
- return form
- },
- setError(key: (keyof Data) | Record, value?: string) {
- let errors: SimpleValidationErrors
-
- if (typeof key !== 'object') {
- if (typeof value === 'undefined') {
- throw new Error('The `value` is required.')
- }
-
- errors = { [key]: value }
- } else {
- errors = key
- }
-
- form.setErrors({
- ...inertiaForm.errors,
- ...errors,
- })
-
- return form
- },
- transform(callback: (data: Data) => Record) {
- inertiaTransform(callback)
-
- transformer = callback
-
- return form
- },
- validate(name?: string | NamedInputEvent | ValidationConfig, config?: ValidationConfig) {
- precognitiveForm.setData(transformer(inertiaForm.data()))
-
- if (typeof name === 'object' && !('target' in name)) {
- config = name
- name = undefined
- }
-
- if (typeof config === 'object') {
- // @ts-expect-error
- config.onValidationError = config.onValidationError ?? config?.onError
- }
-
- if (typeof name === 'undefined') {
- precognitiveForm.validate(config)
- } else {
- precognitiveForm.validate(name, config)
- }
-
- return form
- },
- setValidationTimeout(duration: number) {
- precognitiveForm.setValidationTimeout(duration)
-
- return form
- },
- validateFiles() {
- precognitiveForm.validateFiles()
-
- return form
- },
- withoutFileValidation() {
- precognitiveForm.withoutFileValidation()
-
- return form
- },
- submit(submitMethod: RequestMethod | Partial = {}, submitUrl?: string, submitOptions?: Partial): void {
- if (typeof submitMethod !== 'string') {
- submitOptions = submitMethod
- submitUrl = resolveUrl(url)
- submitMethod = resolveMethod(method)
- }
-
- inertiaSubmit(submitMethod, submitUrl!, {
- ...submitOptions,
- onError: (errors: SimpleValidationErrors): void => {
- precognitiveForm.validator().setErrors(errors)
-
- if (submitOptions?.onError) {
- return submitOptions.onError(errors)
- }
- },
- })
- },
- validator: precognitiveForm.validator,
- })
-
- // Due to the nature of `reactive` elements, reactivity is not inherited by
- // the patched Inertia form as we have to destructure the Precog form. We
- // can handle this by watching for changes and apply the changes manually.
- watchEffect(() => form.validating = precognitiveForm.validating)
-
- return form
-}
diff --git a/packages/vue-inertia/src/types.ts b/packages/vue-inertia/src/types.ts
deleted file mode 100644
index 1eb579c..0000000
--- a/packages/vue-inertia/src/types.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { NamedInputEvent, RequestMethod, SimpleValidationErrors, ValidationConfig, ValidationErrors } from 'laravel-precognition'
-import { Form as PrecognitiveForm } from 'laravel-precognition-vue/dist/types'
-import { InertiaForm } from '@inertiajs/vue3'
-import { VisitOptions } from '@inertiajs/core'
-
-type RedefinedProperties = 'setErrors' | 'touch' | 'forgetError' | 'setValidationTimeout' | 'submit' | 'reset' | 'validateFiles' | 'setData' | 'validate'
-
-export type Form> = Omit, RedefinedProperties> & InertiaForm & {
- setErrors(errors: SimpleValidationErrors | ValidationErrors): Data & Form,
- touch(name: Array | string | NamedInputEvent): Data & Form,
- forgetError(string: keyof Data | NamedInputEvent): Data & Form,
- setValidationTimeout(duration: number): Data & Form,
- submit(config?: Partial): void,
- submit(method: RequestMethod, url: string, options?: Partial): void,
- reset(...keys: (keyof Partial)[]): Data & Form,
- validateFiles(): Data & Form,
- withoutFileValidation(): Data & Form,
- setData(data: Record): Data & Form,
- validate(name?: (keyof Data | NamedInputEvent) | ValidationConfig, config?: ValidationConfig): Data & Form,
- defaults(): void,
- defaults(defaults: Partial): void,
- defaults(defaults: (previousData: Data) => Data): void,
- defaults(field: K, value: Data[K]): void,
-}
-
-// This type has been duplicated from @inertiajs/core to
-// continue supporting Inertia 1. When we drop version 1
-// support we can import this directly from Inertia.
-export type FormDataConvertible = Array | {
- [key: string]: FormDataConvertible;
-} | Blob | FormDataEntryValue | Date | boolean | number | null | undefined;
diff --git a/packages/vue-inertia/tests/index.test.ts b/packages/vue-inertia/tests/index.test.ts
deleted file mode 100644
index 0a85ca0..0000000
--- a/packages/vue-inertia/tests/index.test.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-import { it, expect, beforeEach, afterEach, vi } from 'vitest'
-import { useForm, client } from '../src/index'
-import axios from 'axios'
-import { Config } from 'laravel-precognition'
-
-beforeEach(() => {
- vi.mock('axios')
- client.use(axios)
-})
-
-afterEach(() => {
- vi.restoreAllMocks()
-})
-
-it('can clear all errors via Inertia\'s clearErrors', () => {
- const form = useForm('post', '/register', {
- name: '',
- }).setErrors({
- name: 'xxxx',
- other: 'xxxx',
- })
-
- expect(form.errors).toEqual({
- name: 'xxxx',
- other: 'xxxx',
- })
-
- form.clearErrors()
-
- expect(form.errors).toEqual({})
- expect(form.validator().errors()).toEqual({})
-})
-
-it('can clear specific errors via Inertia\'s clearErrors', () => {
- const form = useForm('post', '/register', {
- name: '',
- }).setErrors({
- name: 'xxxx',
- email: 'xxxx',
- other: 'xxxx',
- })
-
- expect(form.errors).toEqual({
- name: 'xxxx',
- email: 'xxxx',
- other: 'xxxx',
- })
-
- form.clearErrors('name', 'email')
-
- expect(form.errors).toEqual({
- other: 'xxxx',
- })
- expect(form.validator().errors()).toEqual({
- other: ['xxxx'],
- })
-})
-
-it('provides default data for validation requests', () => {
- const response = { headers: { precognition: 'true', 'precognition-success': 'true' }, status: 204, data: 'data' }
-
- let config: Config
- axios.request.mockImplementation(async (c: Config) => {
- config = c
-
- return response
- })
-
- const form = useForm('post', '/register', {
- emails: '',
- })
-
- form.emails = 'taylor@laravel.com, tim@laravel.com'
- form.validate('emails')
-
- expect(config!.data.emails).toEqual('taylor@laravel.com, tim@laravel.com')
- expect(form.emails).toBe('taylor@laravel.com, tim@laravel.com')
- expect(form.data().emails).toBe('taylor@laravel.com, tim@laravel.com')
-})
-
-it('transforms data for validation requests', () => {
- const response = { headers: { precognition: 'true', 'precognition-success': 'true' }, status: 204, data: 'data' }
-
- let config: Config
- axios.request.mockImplementation(async (c: Config) => {
- config = c
-
- return response
- })
-
- const form = useForm('post', '/register', {
- emails: '',
- }).transform((data) => ({
- emails: data.emails.split(',').map((email) => email.trim()),
- }))
-
- form.emails = 'taylor@laravel.com, tim@laravel.com'
- form.validate('emails')
-
- expect(config!.data.emails).toEqual(['taylor@laravel.com', 'tim@laravel.com'])
- expect(form.emails).toBe('taylor@laravel.com, tim@laravel.com')
- expect(form.data().emails).toBe('taylor@laravel.com, tim@laravel.com')
-})
-
-it('can set individual errors', function () {
- const form = useForm('post', '/register', {
- name: '',
- })
-
- form.setError('name', 'The name is required.')
-
- expect(form.errors.name).toBe('The name is required.')
-})
-
-it('allows getter as data inputs', function () {
- let dynamicEmail = 'taylor@laravel.com'
-
- function getData() {
- return {
- email: dynamicEmail,
- }
- }
-
- const form = useForm('post', '/register', getData)
-
- expect(form.email).toBe('taylor@laravel.com')
-
- dynamicEmail = 'tim@laravel.com'
- form.reset()
-
- expect(form.email).toBe('tim@laravel.com')
-})
-
-it('can check that specific fields have been touched', () => {
- const form = useForm('post', '/register', {
- name: '',
- email: '',
- })
-
- expect(form.touched('name')).toBe(false)
- expect(form.touched('email')).toBe(false)
-
- form.touch('name')
-
- expect(form.touched('name')).toBe(true)
- expect(form.touched('email')).toBe(false)
-})
-
-it('can check it any fields have been touched', () => {
- const form = useForm('post', '/register', {
- name: '',
- email: '',
- })
-
- expect(form.touched()).toBe(false)
-
- form.touch('name')
-
- expect(form.touched()).toBe(true)
-})
-
-it('can set defaults with no arguments', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const form = useForm('post', '/register', {
- name: 'John',
- })
-
- form.name = 'Jane'
- form.defaults()
-
- form.name = 'John'
- form.reset()
- expect(form.name).toBe('Jane')
-
- form.validate('name')
- expect(requests).toBe(0)
-})
-
-it('can set defaults with an object', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const form = useForm('post', '/register', {
- name: 'John',
- })
-
- form.defaults({ name: 'Jane' })
-
- form.name = 'John'
- form.reset()
- expect(form.name).toBe('Jane')
-
- form.validate('name')
- expect(requests).toBe(0)
-})
-
-it('can set defaults with a function', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const form = useForm('post', '/register', {
- name: 'John',
- })
-
- form.defaults((prevData: any) => {
- expect(prevData).toEqual({
- name: 'John',
- })
-
- return {
- name: 'Jane',
- }
- })
-
- form.name = 'John'
- form.reset()
- expect(form.name).toBe('Jane')
-
- form.validate('name')
- expect(requests).toBe(0)
-})
-
-it('can set defaults with a field and value', () => {
- let requests = 0
- axios.request.mockImplementation(async () => {
- requests++
- })
-
- const form = useForm('post', '/register', {
- name: 'John',
- })
-
- form.defaults('name', 'Jane')
-
- form.name = 'John'
- form.reset()
- expect(form.name).toBe('Jane')
-
- form.validate('name')
- expect(requests).toBe(0)
-})
diff --git a/packages/vue-inertia/tsconfig.json b/packages/vue-inertia/tsconfig.json
deleted file mode 100644
index c4ba78c..0000000
--- a/packages/vue-inertia/tsconfig.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "compilerOptions": {
- "skipLibCheck": true,
- "outDir": "./dist",
- "target": "ES2020",
- "module": "ES2020",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "strict": true,
- "declaration": true,
- "esModuleInterop": true,
- "types": [
- "vue"
- ]
- },
- "include": [
- "./src/index.ts"
- ]
-}