diff --git a/.env.example b/.env.example index 6d0a8b6..3dd4887 100644 --- a/.env.example +++ b/.env.example @@ -9,5 +9,7 @@ NEXTAUTH_SECRET="hey" FLATFILE_API_KEY='sk_...' FLATFILE_ENVIRONMENT_ID='us_env_...' FLATFILE_NAMESPACE='space:plmproject' +NEXT_PUBLIC_FLATFILE_PUBLISHABLE_KEY='pk_...' +NEXT_PUBLIC_FLATFILE_ENVIRONMENT_ID='us_env_...' NEXT_PUBLIC_APP_ID='products-show' LISTENER_AUTH_TOKEN='token' \ No newline at end of file diff --git a/app/(authenticated)/dynamic-portal/custom-field-builder.tsx b/app/(authenticated)/dynamic-portal/custom-field-builder.tsx new file mode 100644 index 0000000..2ce51c1 --- /dev/null +++ b/app/(authenticated)/dynamic-portal/custom-field-builder.tsx @@ -0,0 +1,261 @@ +import { OptionBuilder } from "./option-builder"; +import { FormEvent } from "react"; +import { + CustomField, + DATE_FORMATS, + FIELD_TYPES, + INITIAL_OPTIONS, +} from "@/lib/dynamic/field-options"; +import { useToast } from "@/components/ui/use-toast"; + +type Props = { + customField: CustomField; + setCustomField: (customField: CustomField) => void; +}; + +export const CustomFieldBuilder = ({ customField, setCustomField }: Props) => { + const { toast } = useToast(); + + if (!customField.enumOptions) { + customField.enumOptions = INITIAL_OPTIONS; + } + + const options = customField.enumOptions; + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + + const formData = new FormData(e.target as HTMLFormElement); + const { name, type, required, dateFormat, decimals, enumOptions } = + JSON.parse(formData.get("customField") as string); + + try { + const response = await fetch("/api/custom-field", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name, + type, + required, + dateFormat, + decimals, + enumOptions, + }), + }); + + const json = await response.json(); + const data = json.customField; + + const customField = { + name: data.name, + type: data.type, + required: data.required, + dateFormat: data.dateFormat, + decimals: data.decimals, + enumOptions: data.enumOptions, + }; + + console.log("custom field saved", customField); + } catch (error) { + console.error("Error saving custom field:", error); + } + }; + + return ( +
+
+ { + setCustomField({ ...customField, name: e.target.value }); + }} + /> + + + +
+ { + setCustomField({ ...customField, required: e.target.checked }); + }} + /> + +
+ + +
+ +
+
+
+
+ +
+ {customField.type === "date" && ( +
+ + +
+ )} + + {customField.type === "number" && ( +
+ + { + setCustomField({ + ...customField, + decimals: parseInt(e.target.value), + }); + }} + /> +
+ )} + + {customField.type === "enum" && ( +
+ + a.id - b.id)} + updateInput={(option, value) => { + const filteredOptions = options.filter((o) => { + return o.id !== option.id; + }); + + setCustomField({ + ...customField, + enumOptions: [ + ...filteredOptions, + { ...option, input: value }, + ], + }); + }} + updateOutput={(option, value) => { + const filteredOptions = options.filter((o) => { + return o.id !== option.id; + }); + + setCustomField({ + ...customField, + enumOptions: [ + ...filteredOptions, + { ...option, output: value }, + ], + }); + }} + addNewOption={() => { + const maxId = options.reduce((max, option) => { + return Math.max(max, option.id); + }, 0); + + setCustomField({ + ...customField, + enumOptions: [ + ...options, + { id: maxId + 1, input: "", output: "" }, + ], + }); + }} + removeOption={(option) => { + const filteredObjects = options.filter((o) => { + return o.id !== option.id; + }); + + setCustomField({ + ...customField, + enumOptions: filteredObjects, + }); + }} + /> +
+ )} +
+
+ ); +}; diff --git a/app/(authenticated)/dynamic-portal/option-builder.tsx b/app/(authenticated)/dynamic-portal/option-builder.tsx new file mode 100644 index 0000000..d0cb6dc --- /dev/null +++ b/app/(authenticated)/dynamic-portal/option-builder.tsx @@ -0,0 +1,98 @@ +import { Option } from "@/lib/dynamic/field-options"; + +type Props = { + options: Option[]; + updateInput: (option: Option, value: string) => void; + updateOutput: (option: Option, value: string) => void; + addNewOption: () => void; + removeOption: (option: Option) => void; +}; + +export const OptionBuilder = ({ + options, + updateInput, + updateOutput, + addNewOption, + removeOption, +}: Props) => { + return ( +
+
+

Sheet Value

+

Record Output

+

+
+ +
+ {options.map((option) => { + return ( +
+ { + updateInput(option, e.target.value); + }} + className="text-dark text-xs border border-dark rounded px-2 py-1 w-[45%] md:w-[47.5%]" + /> + + { + updateOutput(option, e.target.value); + }} + className="text-dark text-xs border border-dark rounded px-2 py-1 w-[45%] md:w-[47.5%]" + /> + +
+ { + removeOption(option); + }} + > + + +
+
+ ); + })} +
+ +
+ + + + +

New Option

+
+
+ ); +}; diff --git a/app/(authenticated)/dynamic-portal/page.tsx b/app/(authenticated)/dynamic-portal/page.tsx new file mode 100644 index 0000000..832927c --- /dev/null +++ b/app/(authenticated)/dynamic-portal/page.tsx @@ -0,0 +1,32 @@ +import Workspace from "@/app/(authenticated)/dynamic-portal/workspace"; +import { + Option, + CustomField, + DATE_FORMATS, + FIELD_TYPES, +} from "@/lib/dynamic/field-options"; +import { getServerSession } from "@/lib/get-server-session"; +import { CustomFieldService } from "@/lib/services/custom-field"; +import invariant from "ts-invariant"; + +export default async function Page() { + const session = await getServerSession(); + invariant(session?.user.id, "User must be logged in"); + + const customField = await CustomFieldService.get({ userId: session.user.id }); + + let mappedCustomField: CustomField | null = null; + + if (customField) { + mappedCustomField = { + name: customField.name, + type: customField.type as keyof typeof FIELD_TYPES, + required: customField.required, + dateFormat: customField.dateFormat as keyof typeof DATE_FORMATS, + decimals: customField.decimals as number, + enumOptions: customField.enumOptions as unknown as Option[], + }; + } + + return ; +} diff --git a/app/(authenticated)/dynamic-portal/workspace.tsx b/app/(authenticated)/dynamic-portal/workspace.tsx new file mode 100644 index 0000000..bc248f2 --- /dev/null +++ b/app/(authenticated)/dynamic-portal/workspace.tsx @@ -0,0 +1,255 @@ +"use client"; + +import { WORKFLOW_ITEMS } from "@/lib/workflow-constants"; +import { WorkflowType } from "@/lib/workflow-type"; +import SVG from "react-inlinesvg"; +import { blueprint } from "@/lib/dynamic/blueprint"; +import { CustomFieldBuilder } from "@/app/(authenticated)/dynamic-portal/custom-field-builder"; +import { + Option, + CustomField, + DEFAULT_CUSTOM_FIELD, + DYNAMIC_FIELD_KEY, +} from "@/lib/dynamic/field-options"; +import { FormEvent, useState } from "react"; +import { useToast } from "@/components/ui/use-toast"; +import dynamic from "next/dynamic"; +import { type ISpace } from "@flatfile/react"; +import { SheetConfig } from "@flatfile/api/api"; +import { listener } from "@/lib/dynamic/listener"; + +const DynamicEmbeddedSpace = dynamic( + () => import("@/components/shared/embedded-space"), + { + loading: () =>
, + ssr: false, + } +); + +const generateConfig = ({ + sheet, + customFieldConfig, +}: { + sheet: SheetConfig; + customFieldConfig: any; +}) => { + const filteredConfig = { + name: sheet.name, + sheets: [ + { + name: sheet.name, + slug: sheet.slug, + fields: [...sheet.fields, ...[customFieldConfig]], + }, + ], + actions: sheet.actions, + }; + // console.log("filteredConfig", filteredConfig); + + return filteredConfig; +}; + +const customOptionsConfig = (options: Option[]) => { + const mappedOptions = options.map((o) => { + return { + value: o.input, + label: o.output, + }; + }); + + return { + config: { options: mappedOptions }, + }; +}; + +export default function Workspace({ + savedCustomField, +}: { + savedCustomField: CustomField | null; +}) { + const item = WORKFLOW_ITEMS[WorkflowType.Dynamic]; + const sheet = blueprint[0]; + + const [showSpace, setShowSpace] = useState(false); + const [customField, setCustomField] = useState( + savedCustomField || DEFAULT_CUSTOM_FIELD + ); + const { toast } = useToast(); + + const customFieldConfig = { + key: DYNAMIC_FIELD_KEY, + type: customField.type, + label: customField.name, + description: "Custom field", + ...(customField.required && { constraints: [{ type: "required" }] }), + ...(customField.type === "enum" && + customField.enumOptions && + customOptionsConfig(customField.enumOptions)), + }; + + const spaceProps: ISpace = { + publishableKey: process.env.NEXT_PUBLIC_FLATFILE_PUBLISHABLE_KEY, + environmentId: process.env.NEXT_PUBLIC_FLATFILE_ENVIRONMENT_ID, + name: "Dynamic Portal", + // themeConfig: theme("#71a3d2", "#3A7CB9"), + listener, + // document, + workbook: generateConfig({ + sheet, + customFieldConfig, + }), + spaceInfo: { + // userId, + }, + sidebarConfig: { + showDataChecklist: false, + showSidebar: true, + }, + spaceBody: { + // languageOverride: language, + metadata: { + customFieldValidations: { + decimals: customField.decimals, + dateFormat: customField.dateFormat, + }, + }, + }, + closeSpace: { + operation: "contacts:submit", + onClose: () => setShowSpace(false), + }, + }; + + const handleResetSubmit = async (e: FormEvent) => { + e.preventDefault(); + + try { + if (confirm("Reset workspace options?")) { + const response = await fetch("/api/custom-field", { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Error resetting workspace"); + } + + setCustomField(DEFAULT_CUSTOM_FIELD); + + toast({ + title: "Workspace was reset", + }); + } + } catch (error) { + console.error("Error Resetting Workspace:", error); + + toast({ + title: "Error resetting workspace", + }); + } + }; + + return ( +
+
+
+ +

+ {item.name} +

+
+ +
+ +

Customize your workspace

+

+ Adjust the field options below. Save each as you complete them and + then click Open Portal to add your data. +

+
+
+ +
+
+

Create Custom Fields

+

{item.description}

+
+ +
+
+
Field Name
+
Field Type
+
Required?
+
+ +
+ {sheet.fields.map((f) => { + return ( +
+
{f.label}
+
{f.type}
+
+ c.type === "required") !== + undefined + } + disabled + className="text-dynamic-portal" + /> +
+
+ ); + })} + + +
+
+
+ +
+
+

Generate your workspace

+

+ Click to generate the workspace with your custom config and input + your data. +

+
+ +
+ + + +
+
+ + {showSpace && } +
+ ); +} diff --git a/app/api/custom-field/route.ts b/app/api/custom-field/route.ts new file mode 100644 index 0000000..e2a8031 --- /dev/null +++ b/app/api/custom-field/route.ts @@ -0,0 +1,37 @@ +import { authenticatedRoute } from "@/lib/api-helpers"; +import { CustomFieldService } from "@/lib/services/custom-field"; +import { NextRequest, NextResponse } from "next/server"; + +export const POST = async (request: NextRequest, context: { params: any }) => { + return authenticatedRoute(request, context, async (rq, cxt) => { + const json = await request.json(); + + const customField = await CustomFieldService.upsert({ + userId: cxt.user.id, + data: { + userId: cxt.user.id, + name: json.name, + type: json.type, + required: json.required, + dateFormat: json.dateFormat, + decimals: json.decimals, + enumOptions: json.enumOptions, + }, + }); + + return NextResponse.json({ customField }, { status: 201 }); + }); +}; + +export const DELETE = async ( + request: NextRequest, + context: { params: any } +) => { + return authenticatedRoute(request, context, async (rq, cxt) => { + await CustomFieldService.delete({ + userId: cxt.user.id, + }); + + return NextResponse.json({}, { status: 201 }); + }); +}; diff --git a/app/globals.css b/app/globals.css index d82a429..03ac252 100644 --- a/app/globals.css +++ b/app/globals.css @@ -59,10 +59,8 @@ @apply p-6 md:p-10 rounded-xl; } -.card-bg-2 { - box-shadow: 0px 48px 48px 0px #00000033; - background: #2e323c99; - @apply p-6 md:p-10 rounded-xl; +.card-sm { + @apply px-3 py-4; } /** Resource Index */ diff --git a/components/shared/embedded-space.tsx b/components/shared/embedded-space.tsx new file mode 100644 index 0000000..b04b1be --- /dev/null +++ b/components/shared/embedded-space.tsx @@ -0,0 +1,13 @@ +import { ISpace, useSpace } from "@flatfile/react"; + +type Props = { + spaceProps: ISpace; +}; + +const EmbeddedSpace = ({ spaceProps }: Props) => { + const space = useSpace({ ...spaceProps }); + + return space; +}; + +export default EmbeddedSpace; diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 0000000..00e707c --- /dev/null +++ b/global.d.ts @@ -0,0 +1,7 @@ +// globals.d.ts +namespace NodeJS { + interface ProcessEnv { + NEXT_PUBLIC_FLATFILE_PUBLISHABLE_KEY: string; + NEXT_PUBLIC_FLATFILE_ENVIRONMENT_ID: string; + } +} diff --git a/lib/dynamic/blueprint.ts b/lib/dynamic/blueprint.ts new file mode 100644 index 0000000..3646351 --- /dev/null +++ b/lib/dynamic/blueprint.ts @@ -0,0 +1,105 @@ +import { SheetConfig } from "@flatfile/api/api"; + +// Benefit Elections Sheet +const sheet: SheetConfig = { + name: "Benefit Elections", + slug: "benefit-elections-sheet", + readonly: false, + fields: [ + //Validate against exisitng Employess in DB. If not found, throw an error in Flatfile. Open question around whether this could be a ReferenceField with a lookup to the Employee table. What should happen if an Emplpyee is not found? Should we create a new Employee record in Flatfile or should that occur in HCM.Show? + + { + key: "employeeId", + label: "Employee ID", + description: "Employee ID for existing Employee in HCM.Show.", + type: "string", + constraints: [{ type: "required" }], + }, + + // Validate against exisitng benefit plans in DB. If not found, throw an error in Flatfile. Open question around whether this could be a ReferenceField with a lookup to the Benefit Plan table. What should happen if a Benefit Plan is not found? Should we create a new Benefit Plan record in Flatfile or should that occur in HCM.Show? + + { + key: "benefitPlan", + label: "Benefit Plan", + description: "Benefit Plan for existing Benefit Plan in HCM.Show.", + type: "string", + constraints: [{ type: "required" }], + }, + + //Required checkbox → “required: true” validation + + { + key: "currentlyEnrolled", + label: "Currently Enrolled", + description: "Is the employee currently enrolled in this benefit plan?", + type: "boolean", + constraints: [{ type: "required" }], + }, + + //Date fields have a date format selection → updated target date format for SmartDateField + + { + key: "coverageStartDate", + label: "Coverage Start Date", + description: + "Date coverage begins for this benefit plan. Must be formatted as yyyy-MM-dd", + type: "date", + constraints: [{ type: "required" }], + }, + + //Round to two decimal places → validation / compute on Number fields for decimal places (trim and validate) + + { + key: "employerContribution", + label: "Employer Contribution", + type: "string", + description: + "Employer contribution for this benefit plan per plan frequency.", + constraints: [{ type: "required" }], + }, + + { + key: "benefitCoverageType", + label: "Benefit Coverage Type", + type: "enum", + description: + "Indicates the type of insurance, retirement savings, or other benefits that are provided by an employer to an employee.", + constraints: [{ type: "required" }], + config: { + options: [ + { + value: "Insurance_Coverage_Type_Insurance", + label: "Insurance", + }, + + { + value: "Health_Care_Coverage_Type_Medical", + label: "Medical", + }, + { + value: "Health_Care_Coverage_Type_Dental", + label: "Dental", + }, + { + value: "Retirement_Savings_Coverage_Type_Retirement", + label: "Retirement", + }, + { + value: "Additional_Benefits_Coverage_Type_Other", + label: "Other", + }, + ], + }, + }, + ], + actions: [ + { + operation: "dedupe-benefit-elections", + mode: "background", + label: "Dedupe benefit elections", + description: "Remove duplicate benefit elections", + }, + ], +}; + +export const blueprint = [sheet]; diff --git a/lib/dynamic/field-options.ts b/lib/dynamic/field-options.ts new file mode 100644 index 0000000..9deb780 --- /dev/null +++ b/lib/dynamic/field-options.ts @@ -0,0 +1,68 @@ +export interface Option { + id: number; + input: string; + output: string; +} + +export interface CustomField { + name: string; + type: keyof typeof FIELD_TYPES; + required: boolean; + dateFormat: keyof typeof DATE_FORMATS; + decimals: number; + enumOptions: Option[]; +} + +export const FIELD_TYPES = { + string: "Text", + number: "Number", + date: "Date", + enum: "Category", + boolean: "Checkbox", +}; + +export const DATE_FORMATS = { + "YYYY-MM-DD": "YYYY-MM-DD", + "MM-DD-YYYY": "MM-DD-YYYY", + "DD-MM-YYYY": "DD-MM-YYYY", +}; + +export const INITIAL_OPTIONS: Option[] = [ + { + id: 1, + input: "Insurance_Coverage_Type_Insurance", + output: "Insurance", + }, + + { + id: 2, + input: "Health_Care_Coverage_Type_Medical", + output: "Medical", + }, + { + id: 3, + input: "Health_Care_Coverage_Type_Dental", + output: "Dental", + }, + { + id: 4, + input: "Retirement_Savings_Coverage_Type_Retirement", + output: "Retirement", + }, + { + id: 5, + input: "Additional_Benefits_Coverage_Type_Other", + output: "Other", + }, +]; + +export const DYNAMIC_FIELD_KEY = "dynamicCustomField"; + +export const DEFAULT_CUSTOM_FIELD: CustomField = { + name: "Birthdate", + type: "date", + required: true, + dateFormat: "YYYY-MM-DD", + decimals: 2, + enumOptions: INITIAL_OPTIONS, +}; diff --git a/lib/dynamic/listener.ts b/lib/dynamic/listener.ts new file mode 100644 index 0000000..bbee137 --- /dev/null +++ b/lib/dynamic/listener.ts @@ -0,0 +1,20 @@ +import { FlatfileListener, Client } from "@flatfile/listener"; +import { ExcelExtractor } from "@flatfile/plugin-xlsx-extractor"; +import { JSONExtractor } from "@flatfile/plugin-json-extractor"; +import { spaceConfigure } from "@/lib/dynamic/space-configure"; + +export const listener = FlatfileListener.create((l: Client) => { + l.on("**", (event) => { + console.log( + `[${JSON.stringify(event.topic)}] + ${JSON.stringify(event.namespace)} + ${JSON.stringify(event.payload)}` + ); + }); + + l.namespace("space:servicesproject", (list) => { + list.use(spaceConfigure); + list.use(ExcelExtractor()); + list.use(JSONExtractor()); + }); +}); diff --git a/lib/dynamic/space-configure.ts b/lib/dynamic/space-configure.ts new file mode 100644 index 0000000..5747f48 --- /dev/null +++ b/lib/dynamic/space-configure.ts @@ -0,0 +1,33 @@ +import { configureSpace } from "@flatfile/plugin-space-configure"; +import { blueprint } from "@/lib/dynamic/blueprint"; +import { FlatfileListener } from "@flatfile/listener"; + +export function spaceConfigure(listener: FlatfileListener) { + listener.use( + configureSpace({ + space: { + metadata: { + theme: { + // add theme here + }, + }, + }, + workbooks: [ + { + name: "Field Services Import", + namespace: "fieldServicesImport", + sheets: [blueprint[0]], + actions: [ + { + operation: "submitAction", + mode: "foreground", + constraints: [{ type: "hasData" }], + label: "Submit Data", + primary: true, + }, + ], + }, + ], + }) + ); +} diff --git a/lib/services/custom-field.ts b/lib/services/custom-field.ts new file mode 100644 index 0000000..9f51583 --- /dev/null +++ b/lib/services/custom-field.ts @@ -0,0 +1,36 @@ +import { prismaClient } from "@/lib/prisma-client"; +import { Prisma } from "@prisma/client"; + +export class CustomFieldService { + static async get({ userId }: { userId: string }) { + return await prismaClient.customField.findUnique({ + where: { + userId, + }, + }); + } + + static async upsert({ + userId, + data, + }: { + userId: string; + data: Prisma.CustomFieldUncheckedCreateInput; + }) { + return await prismaClient.customField.upsert({ + where: { + userId, + }, + create: data, + update: data, + }); + } + + static async delete({ userId }: { userId: string }) { + return await prismaClient.customField.delete({ + where: { + userId, + }, + }); + } +} diff --git a/package-lock.json b/package-lock.json index 60328fd..e5667c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,10 @@ "version": "0.1.0", "dependencies": { "@flatfile/api": "^1.7.10", + "@flatfile/plugin-json-extractor": "^0.7.1", + "@flatfile/plugin-space-configure": "^0.3.4", + "@flatfile/plugin-xlsx-extractor": "^1.11.4", + "@flatfile/react": "^7.8.11", "@headlessui/react": "^1.7.18", "@heroicons/react": "^2.1.3", "@hookform/resolvers": "^3.3.4", @@ -185,6 +189,257 @@ "resolved": "https://registry.npmjs.org/@flatfile/cross-env-config/-/cross-env-config-0.0.4.tgz", "integrity": "sha512-mNaqtASTly4N09pjQts5zDnYXFLC891TCxJEiFUnil8p6lQciyd0gnPSnhJD0TTlO5817gX3mLE9RDoAETtIbg==" }, + "node_modules/@flatfile/embedded-utils": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@flatfile/embedded-utils/-/embedded-utils-1.1.13.tgz", + "integrity": "sha512-w7Ac+mUnc8sdVHl0qVSQX94bpHq0LCpIP5DOHYzdvKrEpPU92ZgG1TAronytgksOuXz8bhX49hVXlRLh5MeqNg==", + "dependencies": { + "@flatfile/api": "^1.6.7", + "@flatfile/listener": "^1.0.0", + "@flatfile/util-common": "^0.2.4", + "pubnub": "^7.2.2" + } + }, + "node_modules/@flatfile/hooks": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@flatfile/hooks/-/hooks-1.3.2.tgz", + "integrity": "sha512-5HUBar6CnhhMU7lr4DnD79QfV4MtR1dUjZQJdt50HCS5pxy+tbF70JJSnoF/6itj+0hATkSC/Ep5C1XfABAGYw==" + }, + "node_modules/@flatfile/listener": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@flatfile/listener/-/listener-1.0.1.tgz", + "integrity": "sha512-XClO1KhQDL9Q7zfTANcMeole7Q/2QaIhzttZI+p04PjB+bUlIvk+yUbHvhnLahNkvLHRoIth4p+oBj8tPC1cxA==", + "dependencies": { + "ansi-colors": "^4.1.3", + "cross-fetch": "^4.0.0", + "flat": "^5.0.2", + "pako": "^2.1.0", + "wildcard-match": "^5.1.2" + }, + "peerDependencies": { + "@flatfile/api": "^1.5.10" + } + }, + "node_modules/@flatfile/listener/node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, + "node_modules/@flatfile/plugin-job-handler": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@flatfile/plugin-job-handler/-/plugin-job-handler-0.4.1.tgz", + "integrity": "sha512-4n1iHp+0r++HMHRRrv4I3irOS29C8pW5VEEcSwJ4iTyzTauE3BOf20HyxKmZT1qW3y+YYJrMxM6LLZQCKTToZg==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/util-common": "^1.0.3" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@flatfile/listener": "^1.0.1" + } + }, + "node_modules/@flatfile/plugin-job-handler/node_modules/@flatfile/cross-env-config": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@flatfile/cross-env-config/-/cross-env-config-0.0.5.tgz", + "integrity": "sha512-4/hRTQ6BsD+CQKkrexcqd3wwIyRx7uilC0JOF6E0Q1K26/pgatuo1yBMO7Ofo3zs3ZqM5YISQps+0huggypMmg==" + }, + "node_modules/@flatfile/plugin-job-handler/node_modules/@flatfile/util-common": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-1.0.3.tgz", + "integrity": "sha512-naBUZTIr+NRMS4b4ZDzcuHlnT2r/hvj9nzeK9yMFSC4uqRIAZLgiV5PsVPNSaW+1SvTc6JT3Phv56ErgvhB88w==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/cross-env-config": "^0.0.5", + "cross-fetch": "^4.0.0" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@flatfile/listener": "^1.0.1" + } + }, + "node_modules/@flatfile/plugin-json-extractor": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@flatfile/plugin-json-extractor/-/plugin-json-extractor-0.7.1.tgz", + "integrity": "sha512-h1nJ4hMRWmeSG1hXOfIFh+Mpg8htQU4sZwX6wwdcosw0Rg2LExya05iosL57jyZeG8PuYKHqAeyjX77O8l/EgA==", + "dependencies": { + "@flatfile/util-extractor": "^0.5.2" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/@flatfile/plugin-record-hook": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.6.tgz", + "integrity": "sha512-XqYJJyFYUBlJKF32x9tLkLyM4i6wjGIuXH3ISFyPv1CVLrVHFekiOLwkHWbo5gJQ8r8UjncmulPahzbU1QYTqQ==", + "dependencies": { + "@flatfile/hooks": "^1.3.1", + "@flatfile/util-common": "^1.0.3" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/listener": "^1.0.1" + } + }, + "node_modules/@flatfile/plugin-record-hook/node_modules/@flatfile/cross-env-config": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@flatfile/cross-env-config/-/cross-env-config-0.0.5.tgz", + "integrity": "sha512-4/hRTQ6BsD+CQKkrexcqd3wwIyRx7uilC0JOF6E0Q1K26/pgatuo1yBMO7Ofo3zs3ZqM5YISQps+0huggypMmg==" + }, + "node_modules/@flatfile/plugin-record-hook/node_modules/@flatfile/util-common": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-1.0.3.tgz", + "integrity": "sha512-naBUZTIr+NRMS4b4ZDzcuHlnT2r/hvj9nzeK9yMFSC4uqRIAZLgiV5PsVPNSaW+1SvTc6JT3Phv56ErgvhB88w==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/cross-env-config": "^0.0.5", + "cross-fetch": "^4.0.0" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@flatfile/listener": "^1.0.1" + } + }, + "node_modules/@flatfile/plugin-space-configure": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@flatfile/plugin-space-configure/-/plugin-space-configure-0.3.4.tgz", + "integrity": "sha512-ODxZwZIU3CIW01gH7+agAKbF4gJbCQ4M/j8N8KdwyQF42BE7Uyh3DYGcNlE0zsB2zVDIT7VFxOBC4TwXXPfVKA==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/plugin-job-handler": "^0.4.1" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@flatfile/listener": "^1.0.1" + } + }, + "node_modules/@flatfile/plugin-xlsx-extractor": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@flatfile/plugin-xlsx-extractor/-/plugin-xlsx-extractor-1.11.4.tgz", + "integrity": "sha512-n4VYVGwIFwIxGS3GQupUZIka3NyKSj3sopYMsWv3RgX1WAZ1YRNARvc35HTjpgXOPfEIFNQuH+DMOHce3E4d8w==", + "dependencies": { + "@flatfile/util-extractor": "^0.5.5", + "remeda": "^1.14.0", + "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@flatfile/react": { + "version": "7.8.11", + "resolved": "https://registry.npmjs.org/@flatfile/react/-/react-7.8.11.tgz", + "integrity": "sha512-7H1J+R9dJYu36jUZZwDh/lPqH00w2b/KlWCqoOh90MvreV10xuere/c/cbnc8O4UE5EpEezFmoylRJFq0CuSeQ==", + "dependencies": { + "@flatfile/api": "^1.6.7", + "@flatfile/cross-env-config": "^0.0.5", + "@flatfile/embedded-utils": "^1.1.13", + "@flatfile/listener": "^1.0.1", + "@flatfile/plugin-record-hook": "^1.4.1", + "tinycolor2": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@flatfile/react/node_modules/@flatfile/cross-env-config": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@flatfile/cross-env-config/-/cross-env-config-0.0.5.tgz", + "integrity": "sha512-4/hRTQ6BsD+CQKkrexcqd3wwIyRx7uilC0JOF6E0Q1K26/pgatuo1yBMO7Ofo3zs3ZqM5YISQps+0huggypMmg==" + }, + "node_modules/@flatfile/util-common": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.2.5.tgz", + "integrity": "sha512-3Rwv4POI416OVDeIgSlXbF7FbxAeeChK/PDLw4jia0aArDWFATH2+51JHyxcdjMlKiDpr38Smf3QQdN22Ese/A==", + "dependencies": { + "@flatfile/api": "^1.6.0", + "@flatfile/listener": "^0.3.17" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/@flatfile/util-common/node_modules/@flatfile/listener": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@flatfile/listener/-/listener-0.3.19.tgz", + "integrity": "sha512-EywBIzQ2y1NjtXZdj/3EKJAnf+Kzw/o0cvCy1xj/r5HRP4O9S2qW9muIuSyhxWRQWlLyf64UKhGX1+Se++0S+A==", + "dependencies": { + "@rollup/plugin-json": "^6.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", + "ansi-colors": "^4.1.3", + "flat": "^5.0.2", + "pako": "^2.1.0", + "wildcard-match": "^5.1.2" + }, + "peerDependencies": { + "@flatfile/api": "^1.5.10", + "axios": "^1.4.0" + } + }, + "node_modules/@flatfile/util-common/node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, + "node_modules/@flatfile/util-extractor": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@flatfile/util-extractor/-/util-extractor-0.5.5.tgz", + "integrity": "sha512-RYoKzszMn8D8RJ/Flkv5pnGBovyhd8fWBP9SiDR3MQ2+9HDnxtAqjeP6jZ3hUB1XTNHfhbzC8ZSHmgkMeN28wQ==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/listener": "^1.0.1", + "@flatfile/util-common": "^1.0.0", + "@flatfile/util-file-buffer": "^0.2.1" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/@flatfile/util-extractor/node_modules/@flatfile/cross-env-config": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@flatfile/cross-env-config/-/cross-env-config-0.0.5.tgz", + "integrity": "sha512-4/hRTQ6BsD+CQKkrexcqd3wwIyRx7uilC0JOF6E0Q1K26/pgatuo1yBMO7Ofo3zs3ZqM5YISQps+0huggypMmg==" + }, + "node_modules/@flatfile/util-extractor/node_modules/@flatfile/util-common": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-1.0.3.tgz", + "integrity": "sha512-naBUZTIr+NRMS4b4ZDzcuHlnT2r/hvj9nzeK9yMFSC4uqRIAZLgiV5PsVPNSaW+1SvTc6JT3Phv56ErgvhB88w==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/cross-env-config": "^0.0.5", + "cross-fetch": "^4.0.0" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@flatfile/listener": "^1.0.1" + } + }, + "node_modules/@flatfile/util-file-buffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@flatfile/util-file-buffer/-/util-file-buffer-0.2.1.tgz", + "integrity": "sha512-uy4/CzR/CfvJyOfTs1UkJURYCDKoruK2XnFoy3w1W5c78IjAgmrhz1a3YrHI6OvTMapQy0kvp/rdZzCbSCp2Mw==", + "dependencies": { + "@flatfile/api": "^1.7.4", + "@flatfile/listener": "^1.0.1" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", @@ -1555,6 +1810,70 @@ "@babel/runtime": "^7.13.10" } }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.8.0.tgz", @@ -1594,6 +1913,11 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1627,6 +1951,11 @@ "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1673,6 +2002,11 @@ "@types/react": "*" } }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" + }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", @@ -1868,6 +2202,17 @@ "node": ">= 6.0.0" } }, + "node_modules/agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1884,6 +2229,14 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2142,6 +2495,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -2214,6 +2583,17 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "peer": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -2228,6 +2608,33 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bcrypt": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", @@ -2306,6 +2713,40 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -2372,6 +2813,16 @@ } ] }, + "node_modules/cbor-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cbor-js/-/cbor-js-0.1.0.tgz", + "integrity": "sha512-7sQ/TvDZPl7csT1Sif9G0+MA0I0JOVah8+wWlJVQdVEgIbCzlN/ab3x+uvMNsc34TUvO6osQTAmB2ls80JX6tw==" + }, + "node_modules/cbor-sync": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cbor-sync/-/cbor-sync-1.0.4.tgz", + "integrity": "sha512-GWlXN4wiz0vdWWXBU71Dvc1q3aBo0HytqwAZnXF1wOwjqNnDWA1vZ1gDMFLlqohak31VQzmhiYfiCX5QSSfagA==" + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2510,6 +2961,14 @@ "node": ">= 6" } }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2528,12 +2987,25 @@ "node": ">= 0.6" } }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2572,6 +3044,14 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "engines": { + "node": ">= 14" + } + }, "node_modules/data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", @@ -2645,6 +3125,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -2678,6 +3166,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2713,6 +3214,15 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -2966,6 +3476,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", @@ -3336,6 +3866,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -3364,16 +3906,19 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3424,6 +3969,11 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -3473,6 +4023,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -3493,6 +4051,26 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "peer": true, + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -3531,6 +4109,20 @@ "node": ">= 6" } }, + "node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -3544,6 +4136,19 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -3717,6 +4322,20 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/glob": { "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", @@ -3929,6 +4548,37 @@ "node": ">= 0.4" } }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "engines": { + "node": ">=8" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -3941,6 +4591,33 @@ "node": ">= 6" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -4011,6 +4688,18 @@ "loose-envify": "^1.0.0" } }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -4082,6 +4771,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -4098,7 +4801,6 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" }, @@ -4204,6 +4906,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -4459,6 +5166,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -4489,6 +5201,17 @@ "json5": "lib/cli.js" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -4544,6 +5267,11 @@ "node": ">= 0.8.0" } }, + "node_modules/lil-uuid": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/lil-uuid/-/lil-uuid-0.1.1.tgz", + "integrity": "sha512-GhWI8f61tBlMeqULZ1QWhFiiyFIFdPlg//S8Udq1wjq1FJhpFKTfnbduSxAQjueofeUtpr7UvQ/lIK/sKUF8dg==" + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -4645,6 +5373,14 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -4658,6 +5394,17 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -4779,6 +5526,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/next": { "version": "14.1.4", "resolved": "https://registry.npmjs.org/next/-/next-14.1.4.tgz", @@ -5180,6 +5935,59 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/pako": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.1.tgz", @@ -5226,8 +6034,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.10.1", @@ -5263,7 +6070,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -5508,6 +6314,74 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pubnub": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/pubnub/-/pubnub-7.6.2.tgz", + "integrity": "sha512-oeYja8FvKkoYh5JLPDCXAOtIaJVYyB+MJhSqyXNmCpCmtb3ES/E5rTu9QcstAfEligfV/T9eN9SR6StZI+PrIg==", + "dependencies": { + "agentkeepalive": "^3.5.2", + "buffer": "^6.0.3", + "cbor-js": "^0.1.0", + "cbor-sync": "^1.0.4", + "lil-uuid": "^0.1.1", + "proxy-agent": "^6.3.0", + "superagent": "^8.1.2" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5759,11 +6633,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/remeda": { + "version": "1.57.1", + "resolved": "https://registry.npmjs.org/remeda/-/remeda-1.57.1.tgz", + "integrity": "sha512-CHrQFjgGw7y7d5WDDG21nzES2Z3Ae+s1ZjVAYjLOsoCceM1EMzVrSd4dx+Eb3QooR16tbbHeJhzk0q8qsaquTg==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -6042,6 +6920,61 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -6050,6 +6983,11 @@ "node": ">=0.10.0" } }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -6292,6 +7230,26 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/superagent": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", + "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.1.2", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6308,7 +7266,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -6425,6 +7382,11 @@ "node": ">=0.8" } }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6668,6 +7630,14 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -6906,6 +7876,11 @@ "node": ">=8" } }, + "node_modules/wildcard-match": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/wildcard-match/-/wildcard-match-5.1.3.tgz", + "integrity": "sha512-a95hPUk+BNzSGLntNXYxsjz2Hooi5oL7xOfJR6CKwSsSALh7vUNuTlzsrZowtYy38JNduYFRVhFv19ocqNOZlg==" + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -7005,6 +7980,18 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xlsx": { + "version": "0.20.0", + "resolved": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz", + "integrity": "sha512-adg5edVTkXXGTnb0iWrc3Z47ViGgwmD47yx6VfSCZhfdKPtHcElYGs48OtcO4nwOu90Pjz5mmyl0HLcvbSRYTQ==", + "license": "Apache-2.0", + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 5fa4801..10cf2bd 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,10 @@ }, "dependencies": { "@flatfile/api": "^1.7.10", + "@flatfile/plugin-json-extractor": "^0.7.1", + "@flatfile/plugin-space-configure": "^0.3.4", + "@flatfile/plugin-xlsx-extractor": "^1.11.4", + "@flatfile/react": "^7.8.11", "@headlessui/react": "^1.7.18", "@heroicons/react": "^2.1.3", "@hookform/resolvers": "^3.3.4", diff --git a/preflight.js b/preflight.js index 16c2b45..c6e4f13 100644 --- a/preflight.js +++ b/preflight.js @@ -4,6 +4,8 @@ VARS = [ "FLATFILE_NAMESPACE", "FLATFILE_API_KEY", "FLATFILE_ENVIRONMENT_ID", + "NEXT_PUBLIC_FLATFILE_PUBLISHABLE_KEY", + "NEXT_PUBLIC_FLATFILE_ENVIRONMENT_ID", "NEXT_PUBLIC_APP_ID", "LISTENER_AUTH_TOKEN", ]; diff --git a/prisma/migrations/20240404195930_create_custom_field/migration.sql b/prisma/migrations/20240404195930_create_custom_field/migration.sql new file mode 100644 index 0000000..e53c34f --- /dev/null +++ b/prisma/migrations/20240404195930_create_custom_field/migration.sql @@ -0,0 +1,18 @@ +-- CreateTable +CREATE TABLE "CustomField" ( + "id" UUID NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "name" TEXT NOT NULL, + "type" TEXT NOT NULL, + "required" BOOLEAN NOT NULL, + "dateFormat" TEXT, + "decimals" INTEGER, + "enumOptions" JSONB, + "userId" UUID NOT NULL, + + CONSTRAINT "CustomField_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "CustomField" ADD CONSTRAINT "CustomField_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20240404200827_make_custom_field_unique_per_user/migration.sql b/prisma/migrations/20240404200827_make_custom_field_unique_per_user/migration.sql new file mode 100644 index 0000000..5fa92a4 --- /dev/null +++ b/prisma/migrations/20240404200827_make_custom_field_unique_per_user/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - A unique constraint covering the columns `[userId]` on the table `CustomField` will be added. If there are existing duplicate values, this will fail. + +*/ +-- CreateIndex +CREATE UNIQUE INDEX "CustomField_userId_key" ON "CustomField"("userId"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 37d616f..bb543b2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -22,11 +22,12 @@ model User { lastName String companyName String - Space Space[] - suppliers Supplier[] - Attribute Attribute[] - Category Category[] - Product Product[] + Space Space[] + suppliers Supplier[] + Attribute Attribute[] + Category Category[] + Product Product[] + CustomField CustomField? } model Space { @@ -108,3 +109,19 @@ model Category { @@unique([userId, externalCategoryId]) } + +model CustomField { + id String @id @default(uuid()) @db.Uuid + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + name String + type String + required Boolean + dateFormat String? + decimals Int? + enumOptions Json? @db.JsonB + + userId String @unique @db.Uuid + user User @relation(fields: [userId], references: [id]) +}