{"_id":"@abdellahi/formfacade","_rev":"3-0e351afe18c41a35e14f8cebc9c20c41","name":"@abdellahi/formfacade","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@abdellahi/formfacade","version":"0.1.0","keywords":["react","google-forms","forms","formfacade"],"author":{"name":"Abdellahi Brahim","email":"abdellahi@student.dei.uc.pt"},"license":"MIT","_id":"@abdellahi/formfacade@0.1.0","maintainers":[{"name":"abdellahi","email":"uchihaabdellahi@gmail.com"}],"homepage":"https://github.com/abdellahi-brahim/formfacade#readme","bugs":{"url":"https://github.com/abdellahi-brahim/formfacade/issues"},"dist":{"shasum":"011fd830376c6c8d5dae12985dfaf33b76deadd3","tarball":"https://registry.npmjs.org/@abdellahi/formfacade/-/formfacade-0.1.0.tgz","fileCount":11,"integrity":"sha512-CmutjFoV7ZK638AEXsRMmzOkJktkgLYn2wlbqoOX+gZ2r7MZJKoldx2AWvo6JLQbFS5ZvwYftd7ybgfRruxX2Q==","signatures":[{"sig":"MEYCIQDObfV6Lis5aC1yc69Vkk1+Ik4uBD/Lf2wf8G0Ru15UhAIhAOIDvgQYUPfZQLEToxoXJ+brZjaqJr9AfxSZM2XJ9Chi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15565},"main":"./dist/formfacade-react.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/formfacade-react.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/formfacade-react.js","require":"./dist/formfacade-react.cjs"}},"gitHead":"5c2c65384ced9dfd1ba0e8edf1fa626710d52f6b","scripts":{"dev":"vite","build":"vite build && tsc --emitDeclarationOnly","check":"npm run typecheck && npm run build","prepack":"npm run check","typecheck":"tsc --noEmit --emitDeclarationOnly false --declaration false --declarationMap false"},"_npmUser":{"name":"abdellahi","email":"uchihaabdellahi@gmail.com"},"repository":{"url":"git+https://github.com/abdellahi-brahim/formfacade.git","type":"git"},"_npmVersion":"10.9.2","description":"A headless React bridge for submitting custom forms to Google Forms.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.0","react":"^19.0.0","react-dom":"^19.0.0","typescript":"^5.9.0","@types/react":"^19.0.0","@vitejs/plugin-react":"^5.0.0"},"peerDependencies":{"react":">=18"},"_npmOperationalInternal":{"tmp":"tmp/formfacade_0.1.0_1787190424912_0.6552759263257284","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@abdellahi/formfacade","version":"0.1.1","keywords":["react","google-forms","forms","formfacade"],"author":{"name":"Abdellahi Brahim","email":"abdellahi@student.dei.uc.pt"},"license":"MIT","_id":"@abdellahi/formfacade@0.1.1","maintainers":[{"name":"abdellahi","email":"uchihaabdellahi@gmail.com"}],"homepage":"https://github.com/abdellahi-brahim/formfacade#readme","bugs":{"url":"https://github.com/abdellahi-brahim/formfacade/issues"},"dist":{"shasum":"2909b930e99bf14a389f9629dd06055a78d17d5b","tarball":"https://registry.npmjs.org/@abdellahi/formfacade/-/formfacade-0.1.1.tgz","fileCount":11,"integrity":"sha512-R+skpOQJGQEgDr8Kv+jgNF5irGbOxjpWP7U/ck/rW0tsRioGAnTHuoyxyvqzNjSTsVbGh65I63GatpKri6zepA==","signatures":[{"sig":"MEUCIDBlnS7HPY/RSshy/2kIDifuiSv9WKXnxeVX/sJMCslAAiEArZz+gK5oe5H+eWxhdLSb6EClWl/ceJjNe3wC11bVFj0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15551},"main":"./dist/formfacade-react.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/formfacade-react.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/formfacade-react.js","require":"./dist/formfacade-react.cjs"}},"gitHead":"5c2c65384ced9dfd1ba0e8edf1fa626710d52f6b","scripts":{"dev":"vite","build":"vite build && tsc --emitDeclarationOnly","check":"npm run typecheck && npm run build","prepack":"npm run check","typecheck":"tsc --noEmit --emitDeclarationOnly false --declaration false --declarationMap false"},"_npmUser":{"name":"abdellahi","email":"uchihaabdellahi@gmail.com"},"repository":{"url":"git+https://github.com/abdellahi-brahim/formfacade.git","type":"git"},"_npmVersion":"10.9.2","description":"A headless React bridge for submitting custom forms to Google Forms.","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.0","react":"^19.0.0","react-dom":"^19.0.0","typescript":"^5.9.0","@types/react":"^19.0.0","@vitejs/plugin-react":"^5.0.0"},"peerDependencies":{"react":">=18"},"_npmOperationalInternal":{"tmp":"tmp/formfacade_0.1.1_1787190578057_0.6005042039238051","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@abdellahi/formfacade","version":"0.2.0","description":"A headless React bridge and zero-auth inspector for Google Forms.","author":{"name":"Abdellahi Brahim","email":"abdellahi@student.dei.uc.pt"},"homepage":"https://github.com/abdellahi-brahim/formfacade#readme","repository":{"type":"git","url":"git+https://github.com/abdellahi-brahim/formfacade.git"},"bugs":{"url":"https://github.com/abdellahi-brahim/formfacade/issues"},"type":"module","bin":{"formfacade":"bin/formfacade.js"},"main":"./dist/formfacade-react.cjs","module":"./dist/formfacade-react.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/formfacade-react.js","require":"./dist/formfacade-react.cjs"},"./inspect":{"types":"./dist/inspectGoogleForm.d.ts","import":"./dist/inspect.js","require":"./dist/inspect.cjs"}},"sideEffects":false,"scripts":{"dev":"vite","build":"vite build && tsc --emitDeclarationOnly","typecheck":"tsc --noEmit --emitDeclarationOnly false --declaration false --declarationMap false","test":"npm run build && node --test","check":"npm run typecheck && npm run build && node --test","prepack":"npm run check"},"peerDependencies":{"react":">=18"},"devDependencies":{"@vitejs/plugin-react":"^5.0.0","vite":"^7.0.0","react":"^19.0.0","react-dom":"^19.0.0","typescript":"^5.9.0","@types/react":"^19.0.0"},"keywords":["react","google-forms","forms","cli","formfacade"],"license":"MIT","engines":{"node":">=20"},"publishConfig":{"access":"public","provenance":true},"gitHead":"aa34b93454b2304be3097b10c22d06dc4d18f42f","_id":"@abdellahi/formfacade@0.2.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-kZirQRsxnHkm+g1OnmU6DP7LQBhniugaUvIlyYgsyYoO3Jn2LZNGDskiahQG0O0UhOfX06/5h8vBZZMaFF50FQ==","shasum":"9676c08ff5dd0252767d684d8550db2e6551a0ed","tarball":"https://registry.npmjs.org/@abdellahi/formfacade/-/formfacade-0.2.0.tgz","fileCount":16,"unpackedSize":31085,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abdellahi%2fformfacade@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIB9wyL+FIt4B0oNZTRtJJ6R5bIBdIwWnaUz509vKD244AiALzhz/0ufFQNt4WLhlNpb/NBVoJiw+X9Jmu6/oUkAikA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8f55c3e3-dedb-458a-bbb9-1598fa89d3f6"}},"directories":{},"maintainers":[{"name":"abdellahi","email":"uchihaabdellahi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/formfacade_0.2.0_1787227685004_0.48670742609709294"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-20T01:47:04.726Z","modified":"2026-08-20T12:08:05.525Z","0.1.0":"2026-08-20T01:47:05.058Z","0.1.1":"2026-08-20T01:49:38.214Z","0.2.0":"2026-08-20T12:08:05.157Z"},"bugs":{"url":"https://github.com/abdellahi-brahim/formfacade/issues"},"author":{"name":"Abdellahi Brahim","email":"abdellahi@student.dei.uc.pt"},"license":"MIT","homepage":"https://github.com/abdellahi-brahim/formfacade#readme","keywords":["react","google-forms","forms","cli","formfacade"],"repository":{"type":"git","url":"git+https://github.com/abdellahi-brahim/formfacade.git"},"description":"A headless React bridge and zero-auth inspector for Google Forms.","maintainers":[{"name":"abdellahi","email":"uchihaabdellahi@gmail.com"}],"readme":"# @abdellahi/formfacade\n\n[![CI](https://github.com/abdellahi-brahim/formfacade/actions/workflows/ci.yml/badge.svg)](https://github.com/abdellahi-brahim/formfacade/actions/workflows/ci.yml)\n[![npm version](https://img.shields.io/npm/v/%40abdellahi%2Fformfacade)](https://www.npmjs.com/package/@abdellahi/formfacade)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\nA headless bridge between your own React form and Google Forms. The package\nrenders nothing, owns no field state, and ships no CSS. Your application keeps\ncomplete control of its inputs, validation, components, and styling.\n\n## Install\n\n```bash\nnpm install @abdellahi/formfacade\n```\n\n## Inspect a Google Form\n\nPass a published form URL to the CLI. It reads the public form metadata and\nprints the field names and `entry.*` IDs without an API key or Google login.\n\n```bash\nnpx @abdellahi/formfacade inspect \"https://docs.google.com/forms/d/e/YOUR_FORM_ID/viewform\"\n```\n\n```text\nFields (2)\n\n  emailAddress\n    Email Address\n    entry.123456 · short-answer · required\n\n  message\n    Message\n    entry.789012 · paragraph · optional\n\nfieldMap\nconst fieldMap = {\n  emailAddress: \"entry.123456\",\n  message: \"entry.789012\",\n};\n```\n\nAdd `--json` for machine-readable output:\n\n```bash\nnpx @abdellahi/formfacade inspect \"FORM_URL\" --json\n```\n\nThe same inspector is available from Node.js:\n\n```js\nimport { inspectGoogleForm } from \"@abdellahi/formfacade/inspect\";\n\nconst form = await inspectGoogleForm(FORM_URL);\nconsole.log(form.fieldMap);\n```\n\nThe inspector reads metadata embedded in the public form page. Google does not\ndocument that page format, so inspection can break if Google changes it. It also\ncannot inspect forms that require sign-in.\n\n## React hook\n\n```jsx\nimport { useState } from \"react\";\nimport { useGoogleForm } from \"@abdellahi/formfacade\";\n\nconst FORM_URL =\n  \"https://docs.google.com/forms/d/e/YOUR_FORM_ID/viewform\";\n\nexport default function WaitlistForm() {\n  const [email, setEmail] = useState(\"\");\n  const { submit, isSubmitting, isSuccess, error } = useGoogleForm({\n    formUrl: FORM_URL,\n    fieldMap: {\n      email: \"entry.YOUR_EMAIL_FIELD_ID\",\n    },\n  });\n\n  if (isSuccess) return <p>You're on the list.</p>;\n\n  return (\n    <form\n      onSubmit={async (event) => {\n        event.preventDefault();\n        await submit({ email });\n      }}\n    >\n      <input\n        type=\"email\"\n        value={email}\n        onChange={(event) => setEmail(event.target.value)}\n        required\n      />\n      <button disabled={isSubmitting}>\n        {isSubmitting ? \"Joining…\" : \"Join waitlist\"}\n      </button>\n      {error && <p>Could not submit the form.</p>}\n    </form>\n  );\n}\n```\n\n`fieldMap` maps the names used by your application to the `entry.*` IDs used by\nGoogle Forms. Arrays are submitted as repeated fields for checkbox questions.\n\n## Framework-neutral function\n\nThe low-level function can be used without the React hook:\n\n```js\nimport { submitGoogleForm } from \"@abdellahi/formfacade\";\n\nawait submitGoogleForm({\n  formUrl: FORM_URL,\n  fieldMap: { email: \"entry.YOUR_EMAIL_FIELD_ID\" },\n  values: { email: \"person@example.com\" },\n});\n```\n\nYou may omit `fieldMap` when `values` already uses Google entry IDs:\n\n```js\nawait submitGoogleForm({\n  formUrl: FORM_URL,\n  values: { \"entry.YOUR_EMAIL_FIELD_ID\": \"person@example.com\" },\n});\n```\n\n## Important limitation\n\nGoogle Forms accepts the cross-origin POST but does not expose a browser-readable\nresponse. A resolved promise means the browser sent the request; it cannot prove\nthat Google accepted or stored the response. The result therefore explicitly\ncontains `verified: false`. Use your own server endpoint when confirmed delivery\nis required.\n\n## Development\n\nTo build the publishable ESM, CommonJS, and TypeScript declaration files:\n\n```bash\nnpm install\nnpm run build\n```\n\n## Contributing\n\nBug reports and pull requests are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md)\nbefore starting a larger change. Report security issues using the process in\n[SECURITY.md](SECURITY.md).\n\n## License\n\nMIT © Abdellahi Brahim. See [LICENSE](LICENSE).\n","readmeFilename":"README.md"}