├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── workflows │ └── ci.yml ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── assets ├── apis │ ├── activecampaign.svg │ ├── airtable.svg │ ├── anfix.svg │ ├── apollo.svg │ ├── awsdynamodb.svg │ ├── awsredshift.svg │ ├── awss3.svg │ ├── awssqs.svg │ ├── azureblob.svg │ ├── brevo.svg │ ├── chartmogul-dark.svg │ ├── chartmogul-light.svg │ ├── chartmogul.svg │ ├── clickhouse.svg │ ├── clickup.svg │ ├── clientify.svg │ ├── cloudflare.svg │ ├── contpaqicomercial.svg │ ├── couchbase.svg │ ├── csv.svg │ ├── databricks.svg │ ├── devengo.svg │ ├── discord.svg │ ├── dripify.svg │ ├── elasticsearch.svg │ ├── factorial.svg │ ├── facturama.svg │ ├── fathomanalytics.svg │ ├── github-dark.svg │ ├── github-light.svg │ ├── github.svg │ ├── gmail.svg │ ├── googleappsheet.svg │ ├── googlebigquery.svg │ ├── googlebigtable.svg │ ├── googlecalendar.svg │ ├── googledrive.svg │ ├── googlemeet.svg │ ├── googlesheets.svg │ ├── googlestorage.svg │ ├── graphql.svg │ ├── holded.svg │ ├── hubspot.svg │ ├── intercom.svg │ ├── ipgeolocation.svg │ ├── json.svg │ ├── jsonplaceholder.svg │ ├── kafka.svg │ ├── keycloak.svg │ ├── mailchimp.svg │ ├── mailgun.svg │ ├── medium-dark.svg │ ├── medium-light.svg │ ├── medium.svg │ ├── meetalfred.svg │ ├── microsoft365.svg │ ├── monday.svg │ ├── mongodbatlasdata.svg │ ├── netzo.svg │ ├── notion-dark.svg │ ├── notion-light.svg │ ├── notion.svg │ ├── odoo.svg │ ├── okta.svg │ ├── openai-dark.svg │ ├── openai-light.svg │ ├── openai.svg │ ├── paddle.svg │ ├── pandadoc.svg │ ├── personio.svg │ ├── pipedrive.svg │ ├── rest.svg │ ├── saphana.svg │ ├── segment.svg │ ├── sendgrid.svg │ ├── shopify.svg │ ├── slack.svg │ ├── snowflake.svg │ ├── stripe.svg │ ├── supabase.svg │ ├── telegram.svg │ ├── tinybird.svg │ ├── twilio.svg │ ├── vonage.svg │ ├── waalaxy.svg │ ├── webhook.svg │ ├── whatsappbusiness.svg │ ├── wix-dark.svg │ ├── wix-light.svg │ ├── wix.svg │ ├── xml.svg │ ├── zendesk.svg │ └── zohocrm.svg ├── databases │ ├── firebase.svg │ ├── firestore.svg │ ├── mariadb-dark.svg │ ├── mariadb-light.svg │ ├── mongodb.svg │ ├── mssql.svg │ ├── mysql.svg │ ├── netzodb.svg │ ├── postgres.svg │ ├── postgresql.svg │ └── redis.svg ├── plugins │ ├── api-dark.svg │ ├── api-light.svg │ ├── auth-dark.svg │ ├── auth-light.svg │ ├── cron-dark.svg │ ├── cron-light.svg │ ├── environments-dark.svg │ ├── environments-light.svg │ ├── i18n-dark.svg │ ├── i18n-light.svg │ ├── mdx-dark.svg │ ├── mdx-light.svg │ └── unocss.svg └── storage │ ├── azure-app.svg │ └── azure-blob.svg ├── attributions.md ├── code_of_conduct.md ├── contributing.md ├── deno.jsonc ├── lib ├── apis │ ├── activecampaign.ts │ ├── airtable.ts │ ├── brevo.ts │ ├── chartmogul.ts │ ├── clickup.ts │ ├── cloudflare.ts │ ├── contpaqicomercial.ts │ ├── create-api │ │ ├── auth │ │ │ ├── mod.ts │ │ │ ├── oauth2.ts │ │ │ └── types.ts │ │ ├── mod.test.ts │ │ ├── mod.ts │ │ ├── pagination │ │ │ ├── mod.ts │ │ │ └── utils.ts │ │ ├── readme.md │ │ ├── types.ts │ │ └── utils.ts │ ├── discord.ts │ ├── facturama.ts │ ├── fathomanalytics.ts │ ├── github.ts │ ├── googleappsheet.ts │ ├── googledrive.ts │ ├── googlesheets.ts │ ├── holded.ts │ ├── hubspot.ts │ ├── ipgeolocation.ts │ ├── jsonplaceholder.test.ts │ ├── jsonplaceholder.ts │ ├── mailchimpmarketing.ts │ ├── mailgun.ts │ ├── medium.ts │ ├── microsoft365.ts │ ├── monday.ts │ ├── mongodbatlasdata.ts │ ├── netzo.ts │ ├── notion.ts │ ├── openai.ts │ ├── paddle.ts │ ├── pandadoc.ts │ ├── pipedrive.ts │ ├── rest.ts │ ├── sendgrid.ts │ ├── shopify.ts │ ├── stripe.ts │ ├── whatsappbusiness.ts │ └── wix.ts ├── cli │ ├── dev │ │ └── cli.ts │ ├── netzo.ts │ ├── src │ │ ├── args.ts │ │ ├── subcommands │ │ │ ├── deploy.ts │ │ │ └── upgrade.ts │ │ ├── utils │ │ │ ├── api.ts │ │ │ ├── entrypoint.ts │ │ │ ├── info.ts │ │ │ ├── mod.ts │ │ │ ├── netzo.ts │ │ │ └── walk.ts │ │ └── version.ts │ └── tests │ │ ├── help.test.ts │ │ └── utils.ts ├── components │ ├── accordion.tsx │ ├── alert-dialog.tsx │ ├── alert.tsx │ ├── aspect-ratio.tsx │ ├── avatar.tsx │ ├── badge.tsx │ ├── blocks │ │ ├── form-fetch.tsx │ │ ├── kanban │ │ │ ├── kanban.tsx │ │ │ ├── multiple-containers-keyboard-preset.ts │ │ │ └── utils.ts │ │ ├── nav.tsx │ │ ├── plot.tsx │ │ └── table │ │ │ ├── hooks │ │ │ └── use-table-pagination.ts │ │ │ ├── table-actions.tsx │ │ │ ├── table-column-cell.tsx │ │ │ ├── table-column-header.tsx │ │ │ ├── table-filters.tsx │ │ │ ├── table-pagination.tsx │ │ │ ├── table-row-actions.tsx │ │ │ ├── table-search.tsx │ │ │ ├── table-view-options.tsx │ │ │ └── table.tsx │ ├── breadcrumb.tsx │ ├── button-dark-mode.tsx │ ├── button.tsx │ ├── calendar.tsx │ ├── card.tsx │ ├── carousel.tsx │ ├── checkbox.tsx │ ├── client-only.tsx │ ├── collapsible.tsx │ ├── combobox-virtualized.tsx │ ├── combobox.tsx │ ├── command.tsx │ ├── context-menu.tsx │ ├── date-picker.tsx │ ├── dialog.tsx │ ├── drawer.tsx │ ├── dropdown-menu.tsx │ ├── form-fields.tsx │ ├── form.tsx │ ├── head.tsx │ ├── hover-card.tsx │ ├── icon-copy.tsx │ ├── input-otp.tsx │ ├── input.tsx │ ├── label.tsx │ ├── menubar.tsx │ ├── nav-link.tsx │ ├── navigation-menu.tsx │ ├── pagination.tsx │ ├── popover.tsx │ ├── progress.tsx │ ├── radio-group.tsx │ ├── resizable.tsx │ ├── scroll-area.tsx │ ├── select-multiple.tsx │ ├── select.tsx │ ├── separator.tsx │ ├── sheet.tsx │ ├── skeleton.tsx │ ├── slider.tsx │ ├── sooner.tsx │ ├── switch.tsx │ ├── table.tsx │ ├── tabs.tsx │ ├── textarea.tsx │ ├── toast.tsx │ ├── toaster.tsx │ ├── toggle-group.tsx │ ├── toggle.tsx │ ├── tooltip.tsx │ ├── use-dark-mode.ts │ ├── use-toast.ts │ └── utils.ts ├── database │ ├── mod.test.ts │ ├── mod.ts │ └── mod.utils.ts ├── datastore │ ├── mod.test.ts │ ├── mod.ts │ └── mod.utils.ts ├── deps │ ├── @dnd-kit │ │ ├── core.ts │ │ ├── sortable.ts │ │ └── utilities.ts │ ├── @feathersjs │ │ ├── feathers.ts │ │ └── socketio-client.ts │ ├── @hookform │ │ └── resolvers │ │ │ └── zod.ts │ ├── @libsql │ │ └── client.ts │ ├── @mdx-js │ │ └── mdx.ts │ ├── @netzo │ │ └── api │ │ │ └── mod.ts │ ├── @observablehq │ │ └── plot.ts │ ├── @radix-ui │ │ ├── colors.ts │ │ ├── react-accordion.ts │ │ ├── react-alert-dialog.ts │ │ ├── react-aspect-ratio.ts │ │ ├── react-avatar.ts │ │ ├── react-checkbox.ts │ │ ├── react-collapsible.ts │ │ ├── react-context-menu.ts │ │ ├── react-dialog.ts │ │ ├── react-dropdown-menu.ts │ │ ├── react-form.ts │ │ ├── react-hover-card.ts │ │ ├── react-label.ts │ │ ├── react-menubar.ts │ │ ├── react-navigation-menu.ts │ │ ├── react-popover.ts │ │ ├── react-progress.ts │ │ ├── react-radio-group.ts │ │ ├── react-scroll-area.ts │ │ ├── react-select.ts │ │ ├── react-separator.ts │ │ ├── react-slider.ts │ │ ├── react-slot.ts │ │ ├── react-switch.ts │ │ ├── react-tabs.ts │ │ ├── react-toast.ts │ │ ├── react-toggle-group.ts │ │ ├── react-toggle.ts │ │ ├── react-toolbar.ts │ │ └── react-tooltip.ts │ ├── @std │ │ ├── assert.ts │ │ ├── collections.ts │ │ ├── datetime.ts │ │ ├── dotenv.ts │ │ ├── encoding.ts │ │ ├── flags.ts │ │ ├── fmt │ │ │ └── colors.ts │ │ ├── fs.ts │ │ ├── fs │ │ │ └── exists.ts │ │ ├── http.ts │ │ ├── path.ts │ │ └── ulid.ts │ ├── @tanstack │ │ ├── react-table.ts │ │ └── react-virtual.ts │ ├── @tiptap │ │ ├── react.ts │ │ └── starter-kit.ts │ ├── @types │ │ └── hast.ts │ ├── @unocss │ │ ├── core.ts │ │ ├── preset-icons │ │ │ └── browser.ts │ │ ├── preset-mini.ts │ │ ├── preset-typography.ts │ │ ├── preset-uno.ts │ │ └── utils.ts │ ├── ajv-ts.ts │ ├── class-variance-authority.ts │ ├── clsx.ts │ ├── cmdk.ts │ ├── commander.ts │ ├── csso.ts │ ├── date-fns.ts │ ├── deep-parse-json.ts │ ├── deno_kv_oauth │ │ ├── deps.ts │ │ ├── dev_deps.ts │ │ ├── lib │ │ │ ├── _http.ts │ │ │ ├── _kv.ts │ │ │ ├── _test_utils.ts │ │ │ └── types.ts │ │ └── mod.ts │ ├── dotenv │ │ └── mod.ts │ ├── drizzle-orm │ │ ├── libsql.ts │ │ ├── mod.ts │ │ ├── sqlite-core.ts │ │ ├── sqlite-proxy.ts │ │ └── utils.ts │ ├── embla-carousel-react.ts │ ├── flat.ts │ ├── gridjs-react.ts │ ├── gridjs.ts │ ├── input-otp.ts │ ├── istextorbinary.ts │ ├── lodash.get.ts │ ├── mdast-util-mdxjs-esm.ts │ ├── mingo.ts │ ├── nanoid.ts │ ├── oauth2_client │ │ └── src │ │ │ ├── oauth2_client.ts │ │ │ └── types.ts │ ├── prettier.ts │ ├── question │ │ ├── KeyCombo.ts │ │ ├── checkbox.ts │ │ ├── config.ts │ │ ├── confirm.ts │ │ ├── input.ts │ │ ├── list.ts │ │ ├── mod.ts │ │ ├── password.ts │ │ ├── text-util.ts │ │ └── util.ts │ ├── react-day-picker.ts │ ├── react-hook-form.ts │ ├── react-resizable-panels.ts │ ├── react-twc.ts │ ├── remark-frontmatter.ts │ ├── remark-gfm.ts │ ├── semver │ │ └── mod.ts │ ├── socket.io-client.ts │ ├── sonner.ts │ ├── tailwind-merge.ts │ ├── ts-morph.ts │ ├── typescript.ts │ ├── ulid.ts │ ├── unist-util-visit.ts │ ├── usehooks-ts.ts │ ├── vaul.ts │ ├── wait │ │ └── mod.ts │ └── x │ │ └── case │ │ └── mod.ts ├── mod.ts ├── plugins │ ├── auth │ │ ├── i18n.ts │ │ ├── islands │ │ │ └── auth-form.tsx │ │ ├── middlewares │ │ │ └── mod.ts │ │ ├── plugin.ts │ │ ├── routes │ │ │ ├── auth.tsx │ │ │ └── mod.ts │ │ └── utils │ │ │ ├── adapter.ts │ │ │ ├── providers │ │ │ ├── auth0.ts │ │ │ ├── email.ts │ │ │ ├── github.ts │ │ │ ├── gitlab.ts │ │ │ ├── google.ts │ │ │ ├── mod.ts │ │ │ ├── netzo.handle_callback.ts │ │ │ ├── netzo.sign_in.ts │ │ │ ├── netzo.ts │ │ │ ├── netzolabs.ts │ │ │ ├── okta.ts │ │ │ └── slack.ts │ │ │ ├── schema.ts │ │ │ └── types.ts │ ├── cron │ │ ├── mod.ts │ │ └── plugin.ts │ ├── database │ │ └── plugin.ts │ ├── datastore │ │ └── plugin.ts │ ├── environments │ │ ├── mod.ts │ │ └── plugin.ts │ ├── hooks.ts │ ├── loader │ │ └── plugin.ts │ ├── mdx │ │ ├── plugin.ts │ │ └── utils.ts │ ├── middleware.ts │ ├── mod.ts │ ├── storage │ │ └── plugin.ts │ ├── toolbar │ │ ├── i18n.ts │ │ ├── islands │ │ │ └── netzo-toolbar.tsx │ │ ├── middlewares │ │ │ └── mod.ts │ │ └── plugin.ts │ ├── types.ts │ ├── unocss │ │ ├── plugin.ts │ │ ├── preset-icons │ │ │ └── collections │ │ │ │ └── mdi.json │ │ ├── preset-netzo.ts │ │ └── preset-shadcn │ │ │ ├── generate.ts │ │ │ ├── mod.ts │ │ │ ├── themes.ts │ │ │ └── types.ts │ └── utils.ts ├── readme.md └── storage │ ├── mod.test.ts │ └── mod.ts ├── license ├── readme.md ├── tasks ├── lint_analysis.ipynb └── release.ts └── tests ├── fixture-plugins-mdx ├── components │ └── Bar.tsx ├── deno.json ├── dev.ts ├── fresh.config.ts ├── fresh.gen.ts ├── islands │ └── Counter.tsx ├── main.ts ├── routes │ ├── _app.tsx │ └── foo.mdx ├── static │ ├── favicon.ico │ └── styles.css └── unocss.config.ts └── fixture-plugins-unocss ├── deno.json ├── dev.ts ├── fresh.config.ts ├── fresh.gen.ts ├── islands ├── CheckDuplication.tsx └── InsertCssRules.tsx ├── main.ts ├── routes └── index.tsx ├── uno.config.ts └── utils.ts /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** A clear and concise description of what the bug is. 10 | 11 | **To Reproduce** Steps to reproduce the behavior: 12 | 13 | 1. Go to '...' 14 | 2. Click on '....' 15 | 3. Scroll down to '....' 16 | 4. See error 17 | 18 | **Expected behavior** A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** If applicable, add screenshots to help explain your problem. 21 | 22 | **Desktop (please complete the following information):** 23 | 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | 30 | - Device: [e.g. iPhone6] 31 | - OS: [e.g. iOS8.1] 32 | - Browser [e.g. stock browser, safari] 33 | - Version [e.g. 22] 34 | 35 | **Additional context** Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** A clear and concise description 10 | of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** A clear and concise description of what you want to happen. 13 | 14 | **Describe alternatives you've considered** A clear and concise description of any alternative 15 | solutions or features you've considered. 16 | 17 | **Additional context** Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | build: 11 | name: ${{ matrix.kind }} ${{ matrix.os }} 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest] 16 | 17 | steps: 18 | - name: Get Latest Release 19 | id: latest_release 20 | uses: pozetroninc/github-action-get-latest-release@v0.7.0 21 | with: 22 | repository: 'netzo/netzo' 23 | 24 | - name: Set Latest Release as Env Variable 25 | run: echo "LATEST_RELEASE=${{ steps.latest_release.outputs.release }}" >> $GITHUB_ENV 26 | 27 | - name: Git Checkout 28 | uses: actions/checkout@v4 29 | 30 | - name: Setup Deno 31 | uses: denoland/setup-deno@v1 32 | 33 | - name: Format 34 | run: deno fmt --check 35 | 36 | - name: Lint 37 | run: deno lint --rules-exclude=no-explicit-any 38 | 39 | - name: Setup Git 40 | run: | 41 | git config --global user.email "you@example.com" 42 | git config --global user.name "CI Bot" 43 | 44 | - name: Test 45 | run: deno test -A lib/cli/tests/ 46 | 47 | # - name: Tests 48 | # run: deno test --allow-env --allow-net --allow-read --allow-run 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Netzo 2 | *.options.ts 3 | 4 | .env 5 | .production.env 6 | *.DS_Store 7 | cov/ 8 | cov.lcov 9 | .idea 10 | backup.json 11 | html_cov/ 12 | _fresh/ 13 | tmp/ 14 | vendor/ 15 | node_modules/ -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "denoland.vscode-deno", 4 | "antfu.iconify", 5 | "antfu.unocss", 6 | "ms-vscode.live-server" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.lint": true, 4 | "deno.unstable": true, 5 | "[typescriptreact]": { 6 | "editor.defaultFormatter": "denoland.vscode-deno" 7 | }, 8 | "[typescript]": { 9 | "editor.defaultFormatter": "denoland.vscode-deno" 10 | }, 11 | "[javascriptreact]": { 12 | "editor.defaultFormatter": "denoland.vscode-deno" 13 | }, 14 | "[javascript]": { 15 | "editor.defaultFormatter": "denoland.vscode-deno" 16 | }, 17 | "[markdown]": { 18 | "editor.defaultFormatter": "denoland.vscode-deno" 19 | }, 20 | "[json]": { 21 | "editor.defaultFormatter": "denoland.vscode-deno" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assets/apis/activecampaign.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/airtable.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/anfix.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/apollo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/awsdynamodb.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/awsredshift.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/awssqs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/chartmogul-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/chartmogul-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/chartmogul.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/clickhouse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/clickup.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/clientify.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/couchbase.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/databricks.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/devengo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/discord.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/dripify.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/factorial.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/facturama.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/github-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/github-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/gmail.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/googleappsheet.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/googledrive.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/googlemeet.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/holded.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/hubspot.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/ipgeolocation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/mailgun.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/monday.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/mongodbatlasdata.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/notion-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/notion-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/notion.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/odoo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/pandadoc.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/sendgrid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/stripe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/supabase.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/telegram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/tinybird.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/twilio.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/vonage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/wix-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/apis/wix-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/apis/wix.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assets/apis/xml.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/apis/zendesk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/databases/firestore.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Icon_24px_Firestore_Color 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /assets/databases/mongodb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/plugins/mdx-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/plugins/mdx-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/plugins/unocss.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/storage/azure-app.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /attributions.md: -------------------------------------------------------------------------------- 1 | # Open Source License Attribution 2 | 3 | This application uses Open Source components. You can find the source code of their open source 4 | projects along with license information below. We acknowledge and are grateful to these developers 5 | for their contributions to open source. 6 | 7 | ### [deployctl](https://github.com/denoland/fresh) 8 | 9 | by [Deno authors](https://github.com/denoland) is licensed under 10 | [MIT License](https://github.com/denoland/deployctl/blob/main/LICENSE) 11 | 12 | ### [fresh](https://github.com/denoland/fresh) 13 | 14 | by [Deno authors](https://github.com/denoland) is licensed under 15 | [MIT License](https://github.com/denoland/fresh/blob/master/LICENSE) 16 | 17 | ### [deno_kv_oauth](https://github.com/denoland/deno_kv_oauth) 18 | 19 | by [Deno authors](https://github.com/denoland) is licensed under 20 | [MIT License](https://github.com/denoland/deno_kv_oauth/blob/master/LICENSE) 21 | 22 | ### [saaskit](https://github.com/denoland/saaskit) 23 | 24 | by [Deno authors](https://github.com/denoland) is licensed under 25 | [MIT License](https://github.com/denoland/saaskit/blob/master/LICENSE) 26 | 27 | ### [shadcn-ui](https://github.com/shadcn-ui/ui) 28 | 29 | by [shadcn](https://github.com/shadcn-ui) is licensed under 30 | [MIT License](https://github.com/shadcn-ui/ui/blob/main/LICENS.md) 31 | 32 | ### [@feathersjs/feathers](https://github.com/feathersjs/feathers) 33 | 34 | by [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) is licensed 35 | under [MIT License](https://github.com/feathersjs/feathers/blob/dove/LICENSE) 36 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Netzo Open Source 2 | 3 | Thank you for your interest in contributing to Netzo Open Source! This document is a set of 4 | guidelines to help you contribute to this project. 5 | 6 | ## Code of Conduct 7 | 8 | By participating in this project, you are expected to uphold our [Code of Conduct][code_of_conduct]. 9 | 10 | [code_of_conduct]: https://opensource.creativecommons.org/community/code-of-conduct/ 11 | 12 | ## Project Documentation 13 | 14 | The `README` in the root of the repository should contain or link to project documentation. If you 15 | cannot find the documentation you're looking for, please file a GitHub issue with details of what 16 | you'd like to see documented. 17 | 18 | ## How to Contribute 19 | 20 | Please follow the processes in our general [Contributing Code][contributing] guidelines on the 21 | Creative Common Open Source website. 22 | 23 | [contributing]: https://opensource.creativecommons.org/contributing-code/ 24 | 25 | ## Questions or Thoughts? 26 | 27 | Talk to us over at our [Discord community chat][community]. 28 | 29 | [community]: https://discord.gg/tbDUpRQCTk 30 | -------------------------------------------------------------------------------- /lib/apis/activecampaign.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type ActiveCampaignOptions = { 5 | accountName: string; 6 | apiKey: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the ActiveCampaign API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/activecampaign 13 | * 14 | * @param {string} accountName - the account name to construct the base URL 15 | * @param {string} apiKey - the API key to use for authentication 16 | * @returns {object} - an API client instance 17 | */ 18 | export const activecampaign = ({ 19 | accountName = Deno.env.get("ACTIVECAMPAIGN_ACCOUNT_NAME")!, 20 | apiKey = Deno.env.get("ACTIVECAMPAIGN_API_KEY")!, 21 | }: ActiveCampaignOptions) => { 22 | const api = createApi({ 23 | baseURL: `https://${accountName}.api-us1.com/api/3`, 24 | headers: { 25 | "content-type": "application/json", 26 | }, 27 | ignoreResponseError: true, 28 | async onRequest(ctx) { 29 | await auth({ 30 | type: "apiKey", 31 | in: "header", 32 | name: "Api-Token", 33 | value: apiKey, 34 | }, ctx); 35 | }, 36 | }); 37 | 38 | return api; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/apis/airtable.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type AirtableOptions = { 5 | personalAccessToken: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Airtable API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/airtable 12 | * 13 | * @param {string} personalAccessToken - the token to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const airtable = ({ 17 | personalAccessToken = Deno.env.get("AIRTABLE_PERSONAL_ACCESS_TOKEN")!, 18 | }: AirtableOptions) => { 19 | const api = createApi({ 20 | baseURL: `https://api.airtable.com/v0`, 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "bearer", 28 | token: personalAccessToken, 29 | }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/brevo.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type BrevoOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Brevo API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/brevo 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const brevo = ({ 17 | apiKey = Deno.env.get("BREVO_API_KEY")!, 18 | }: BrevoOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.brevo.com/v3", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "api-key", 30 | value: apiKey, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/chartmogul.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type ChartmogulOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the ChartMogul API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/chartmogul 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const chartmogul = ({ 17 | apiKey = Deno.env.get("CHARTMOGUL_API_KEY")!, 18 | }: ChartmogulOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.chartmogul.com/v1", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "basic", 28 | value: apiKey, 29 | }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/clickup.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type ClickupOptions = { 5 | personalApiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Clickup API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/clickup 12 | * 13 | * @param {string} personalApiKey - the personal API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const clickup = ({ 17 | personalApiKey = Deno.env.get("CLICKUP_PERSONAL_API_KEY")!, 18 | }: ClickupOptions) => { 19 | const api = createApi({ 20 | baseURL: `https://api.clickup.com/api/v2`, 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "Authorization", 30 | value: personalApiKey, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/cloudflare.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type CloudflareOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Cloudflare API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/cloudflare 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const cloudflare = ({ 17 | apiKey = Deno.env.get("CLOUDFLARE_API_KEY")!, 18 | }: CloudflareOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.cloudflare.com/client/v4", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "Authorization", 30 | value: `Bearer ${apiKey}`, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/contpaqicomercial.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type ContpaqiComercialOptions = { 5 | apiKey: string; 6 | companyRfc: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the ContpaqiComercial API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/contpaqicomercial 13 | * 14 | * @param {string} apiKey - the API key to use for authentication 15 | * @param {string} companyRfc - the company RFC to use for authentication 16 | * @returns {object} - an API client instance 17 | */ 18 | export const ContpaqiComercial = ({ 19 | apiKey = Deno.env.get("CONTPAQICOMERCIAL_API_KEY")!, 20 | companyRfc = Deno.env.get("CONTPAQICOMERCIAL_COMPANY_RFC")!, 21 | }: ContpaqiComercialOptions) => { 22 | const api = createApi({ 23 | baseURL: `https://contpaqiapim.azure-api.net/comercial`, 24 | headers: { 25 | "x-Empresa-Rfc": companyRfc, 26 | "content-type": "application/json", 27 | }, 28 | async onRequest(ctx) { 29 | await auth({ 30 | type: "apiKey", 31 | in: "header", 32 | name: "Ocp-Apim-Subscription-Key", 33 | value: apiKey, 34 | }, ctx); 35 | }, 36 | }); 37 | 38 | return api; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/apis/create-api/pagination/utils.ts: -------------------------------------------------------------------------------- 1 | import { base64 } from "https://deno.land/std/encoding/base64.ts"; 2 | 3 | // Offset Pagination: 4 | 5 | export function encodeOffsetCursor(offset: number): string { 6 | return base64.encode(`offset::${offset}`); 7 | } 8 | 9 | export function decodeOffsetCursor(cursor: string): number { 10 | const decoded = base64.decode(cursor); 11 | const [type, value] = decoded.split("::"); 12 | if (type === "offset") return parseInt(value, 10); 13 | throw new Error("Invalid cursor"); 14 | } 15 | 16 | // Cursor Pagination: 17 | 18 | export function encodeCursorCursor(cursor: string): string { 19 | return base64.encode(`cursor::${cursor}`); 20 | } 21 | 22 | export function decodeCursorCursor(cursor: string): string { 23 | const decoded = base64.decode(cursor); 24 | const [type, value] = decoded.split("::"); 25 | if (type === "cursor") return value; 26 | throw new Error("Invalid cursor"); 27 | } 28 | 29 | // Link Pagination: 30 | 31 | export function encodeLinkCursor(url: string): string { 32 | return base64.encode(`link::${url}`); 33 | } 34 | 35 | export function decodeLinkCursor(cursor: string): string { 36 | const decoded = base64.decode(cursor); 37 | const [type, value] = decoded.split("::"); 38 | if (type === "link") return value; 39 | throw new Error("Invalid cursor"); 40 | } 41 | -------------------------------------------------------------------------------- /lib/apis/create-api/types.ts: -------------------------------------------------------------------------------- 1 | // deno-lint-ignore-file no-explicit-any 2 | import type { FetchContext, FetchOptions } from "https://esm.sh/ofetch@1.1.1"; 3 | import type { QueryObject } from "https://esm.sh/ufo@1.2.0"; 4 | 5 | export type { FetchContext, FetchOptions }; 6 | 7 | export type ResponseMap = { 8 | blob: Blob; 9 | text: string; 10 | arrayBuffer: ArrayBuffer; 11 | }; 12 | 13 | export type ResponseType = keyof ResponseMap | "json"; 14 | export type MappedType = R extends keyof ResponseMap 15 | ? ResponseMap[R] 16 | : JsonType; 17 | 18 | export type ApiMethodHandlerGET = < 19 | T = any, 20 | R extends ResponseType = "json", 21 | >( 22 | query?: Query, 23 | options?: Omit, "baseURL" | "method">, 24 | ) => Promise>; 25 | 26 | export type ApiMethodHandler = < 27 | T = any, 28 | R extends ResponseType = "json", 29 | >( 30 | data?: Data, 31 | query?: Query, 32 | options?: Omit, "baseURL" | "method">, 33 | ) => Promise>; 34 | 35 | export type ApiClient = { 36 | [key: string]: ApiClient; 37 | (...segmentsOrIds: (string | number)[]): ApiClient; 38 | } & { 39 | get: ApiMethodHandlerGET; 40 | post: ApiMethodHandler; 41 | put: ApiMethodHandler; 42 | patch: ApiMethodHandler; 43 | delete: ApiMethodHandler; 44 | }; 45 | -------------------------------------------------------------------------------- /lib/apis/create-api/utils.ts: -------------------------------------------------------------------------------- 1 | export function headersToObject(headers: HeadersInit = {}) { 2 | // SSR compatibility for `Headers` prototype 3 | if (typeof Headers !== "undefined" && headers instanceof Headers) { 4 | return Object.fromEntries([...(headers as Headers).entries()]); 5 | } 6 | 7 | if (Array.isArray(headers)) { 8 | return Object.fromEntries(headers); 9 | } 10 | 11 | return headers; 12 | } 13 | 14 | /** 15 | * Simple heuristic to check if a client is an API client 16 | * @param client {Record} - the object to check 17 | * @returns {boolean} - true if the object is an API client 18 | */ 19 | export const isApiClient = (client: Record) => { 20 | const METHODS = ["get", "post", "put", "patch", "delete"]; 21 | return METHODS.some((method: string) => client[method]); 22 | }; 23 | -------------------------------------------------------------------------------- /lib/apis/discord.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type DiscordOptions = { 5 | tokenType: string; 6 | token: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Discord API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/discord 13 | * 14 | * @param {string} tokenType - the token type to use for authentication 15 | * @param {string} token - the token to use for authentication 16 | * @returns {object} - an API client instance 17 | */ 18 | export const discord = ({ 19 | tokenType = Deno.env.get("DISCORD_TOKEN_TYPE") ?? "Bot", 20 | token = Deno.env.get("DISCORD_TOKEN")!, 21 | }: DiscordOptions) => { 22 | const api = createApi({ 23 | baseURL: "https://discord.com/api/v10", 24 | headers: { 25 | "content-type": "application/json", 26 | }, 27 | ignoreResponseError: true, 28 | async onRequest(ctx) { 29 | await auth({ 30 | type: "apiKey", 31 | in: "header", 32 | name: "Authorization", 33 | value: `${tokenType} ${token}`, 34 | }, ctx); 35 | }, 36 | }); 37 | 38 | return api; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/apis/facturama.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | export type FacturamaOptions = { 4 | username: string; 5 | password: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Facturama API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/facturama 12 | * 13 | * @param {string} username - the username to use for authentication 14 | * @param {string} password - the password to use for authentication 15 | * @returns {object} - an API client instance 16 | */ 17 | export const facturama = ({ 18 | username = Deno.env.get("FACTURAMA_USERNAME")!, 19 | password = Deno.env.get("FACTURAMA_PASSWORD")!, 20 | }: FacturamaOptions) => { 21 | const api = createApi({ 22 | baseURL: "https://api.facturama.mx", 23 | headers: { 24 | "content-type": "application/json", 25 | }, 26 | ignoreResponseError: true, 27 | async onRequest(ctx) { 28 | await auth({ type: "basic", username, password }, ctx); 29 | }, 30 | }); 31 | 32 | return api; 33 | }; 34 | -------------------------------------------------------------------------------- /lib/apis/fathomanalytics.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type FathomAnalyticsOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Fathom Analytics API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/fathomanalytics 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const fathomanalytics = ({ 17 | apiKey = Deno.env.get("FATHOMANALYTICS_API_KEY")!, 18 | }: FathomAnalyticsOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.usefathom.com/v1", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "Authorization", 30 | value: `Bearer ${apiKey}`, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/github.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type GithubOptions = { 5 | personalAccessToken: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the GitHub API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/github 12 | * 13 | * @param {string} personalAccessToken - the token to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const github = ({ 17 | personalAccessToken = Deno.env.get("GITHUB_PERSONAL_ACCESS_TOKEN")!, 18 | }: GithubOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.github.com", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "bearer", 28 | token: personalAccessToken, 29 | }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/googleappsheet.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type GoogleappsheetOptions = { 5 | appId: string; 6 | applicationAccessKey: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Google Appsheet API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/googleappsheet 13 | * 14 | * @param {string} apiKey - the API key to use for authentication 15 | * @returns {object} - an API client instance 16 | */ 17 | export const googleappsheet = ({ 18 | appId = Deno.env.get("GOOGLEAPPSHEET_APP_ID")!, 19 | applicationAccessKey = Deno.env.get("GOOGLEAPPSHEET_APPLICATION_ACCESS_KEY")!, 20 | }: GoogleappsheetOptions) => { 21 | const api = createApi({ 22 | baseURL: `https://api.appsheet.com/api/v2/apps/${appId}/tables`, 23 | headers: { 24 | "content-type": "application/json", 25 | }, 26 | ignoreResponseError: true, 27 | async onRequest(ctx) { 28 | await auth({ 29 | type: "apiKey", 30 | in: "header", 31 | name: "ApplicationAccessKey", 32 | value: applicationAccessKey, 33 | }, ctx); 34 | }, 35 | }); 36 | 37 | return api; 38 | }; 39 | -------------------------------------------------------------------------------- /lib/apis/googledrive.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type GoogledriveOptions = { 5 | googleServiceAccountCredentials: string; 6 | scope?: Array< 7 | | "drive" 8 | | "drive.appdata" 9 | | "drive.file" 10 | | "drive.metadata" 11 | | "drive.metadata.readonly" 12 | | "drive.photos.readonly" 13 | | "drive.readonly" 14 | | "drive.scripts" 15 | >; 16 | }; 17 | 18 | /** 19 | * Factory function for the Google Drive API 20 | * 21 | * @see https://netzo.io/docs/modules/integrations/apis/googledrive 22 | * 23 | * @param {string} googleServiceAccountCredentials - the Google Service Account Credentials to use for authentication 24 | * @param {string} scope - the scope to use for authentication (default: ['drive.readonly']) 25 | * @returns {object} - an API client instance 26 | */ 27 | export const googledrive = ({ 28 | googleServiceAccountCredentials = Deno.env.get( 29 | "GOOGLE_SERVICE_ACCOUNT_CREDENTIALS", 30 | )!, 31 | scope = ["drive.readonly"], 32 | }: GoogledriveOptions) => { 33 | const api = createApi({ 34 | baseURL: `https://www.googleapis.com/drive/v3`, 35 | headers: { 36 | "content-type": "application/json", 37 | }, 38 | ignoreResponseError: true, 39 | async onRequest(ctx) { 40 | await auth({ 41 | type: "googlejwtsa", 42 | googleServiceAccountCredentials, 43 | googleAuthOptions: { 44 | scope: scope.map((s) => `https://www.googleapis.com/auth/${s}`), 45 | }, 46 | }, ctx); 47 | }, 48 | }); 49 | 50 | return api; 51 | }; 52 | -------------------------------------------------------------------------------- /lib/apis/holded.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type HoldedOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Holded API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/holded 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const holded = ({ 17 | apiKey = Deno.env.get("HOLDED_API_KEY")!, 18 | }: HoldedOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.holded.com/api", 21 | headers: { 22 | "accept": "application/json", 23 | "content-type": "application/json", 24 | }, 25 | ignoreResponseError: true, 26 | async onRequest(ctx) { 27 | await auth({ 28 | type: "apiKey", 29 | in: "header", 30 | name: "key", 31 | value: apiKey, 32 | }, ctx); 33 | }, 34 | }); 35 | 36 | return api; 37 | }; 38 | -------------------------------------------------------------------------------- /lib/apis/hubspot.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type HubspotOptions = { 5 | privateAppAccessToken: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Hubspot API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/hubspot 12 | * 13 | * @param {string} privateAppAccessToken - the token to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const hubspot = ({ 17 | privateAppAccessToken = Deno.env.get("HUBSPOT_PRIVATE_APP_ACCESS_TOKEN")!, 18 | }: HubspotOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.hubapi.com", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "bearer", 28 | token: privateAppAccessToken, 29 | }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/ipgeolocation.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type IpGeolocationOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Ip Geolocation API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/ipgeolocation 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const ipgeolocation = ({ 17 | apiKey = Deno.env.get("IPGEOLOCATION_API_KEY")!, 18 | }: IpGeolocationOptions) => { 19 | const api = createApi({ 20 | baseURL: `https://api.ipgeolocation.io/`, 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "query", 29 | name: "apiKey", 30 | value: apiKey, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/jsonplaceholder.test.ts: -------------------------------------------------------------------------------- 1 | import { assertEquals, assertExists } from "../deps/@std/assert.ts"; 2 | import { jsonplaceholder } from "./jsonplaceholder.ts"; 3 | 4 | Deno.test("[apis] jsonplaceholder", async (t) => { 5 | const api = jsonplaceholder(); 6 | 7 | await t.step("find todos", async () => { 8 | const resultData = await api.todos.get(); 9 | assertExists(resultData); 10 | assertEquals(Array.isArray(resultData), true); 11 | }); 12 | 13 | await t.step("get todos", async () => { 14 | const resultData = await api.todos["5"].get(); 15 | assertExists(resultData); 16 | assertEquals(typeof resultData, "object"); 17 | }); 18 | 19 | await t.step("add todo", async () => { 20 | const resultData = await api.todos.post({ 21 | userId: 1, 22 | title: "New task", 23 | }); 24 | assertExists(resultData); 25 | assertEquals(typeof resultData, "object"); 26 | }); 27 | 28 | await t.step("update todo", async () => { 29 | const resultData = await api.todos["1"].put({ 30 | userId: 1, 31 | title: "Updated task", 32 | id: 1, 33 | completed: true, 34 | }); 35 | assertExists(resultData); 36 | assertEquals(typeof resultData, "object"); 37 | }); 38 | 39 | await t.step("delete todo", async () => { 40 | const resultData = await api.todos["1"].delete(); 41 | assertExists(resultData); 42 | assertEquals(typeof resultData, "object"); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /lib/apis/jsonplaceholder.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | /** 4 | * Factory function for the JSONPlaceholder API 5 | * 6 | * @see https://netzo.io/docs/modules/integrations/apis/jsonplaceholder 7 | * 8 | * @returns {object} - an API client instance 9 | */ 10 | export const jsonplaceholder = () => { 11 | const api = createApi({ 12 | baseURL: "https://jsonplaceholder.typicode.com", 13 | headers: { 14 | "content-type": "application/json", 15 | }, 16 | ignoreResponseError: true, 17 | async onRequest(ctx) { 18 | await auth({ type: "none" }, ctx); 19 | }, 20 | }); 21 | 22 | return api; 23 | }; 24 | -------------------------------------------------------------------------------- /lib/apis/mailchimpmarketing.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type MailchimpOptions = { 5 | marketingApiKey: string; 6 | dataCenter: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Mailchimp API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/mailchimp 13 | * 14 | * @param {string} marketingApiKey - the marketing API key to use for authentication 15 | * @param {string} dataCenter - the data center to construct the base URL 16 | * @returns {object} - an API client instance 17 | */ 18 | export const mailchimpmarketing = ({ 19 | marketingApiKey = Deno.env.get("MAILCHIMP_MARKETING_API_KEY")!, 20 | dataCenter = Deno.env.get("MAILCHIMP_MARKETING_DATA_CENTER")!, 21 | }: MailchimpOptions) => { 22 | const api = createApi({ 23 | baseURL: ` https://${dataCenter}.api.mailchimp.com/3.0`, 24 | headers: { 25 | "content-type": "application/json", 26 | }, 27 | ignoreResponseError: true, 28 | async onRequest(ctx) { 29 | await auth({ 30 | type: "bearer", 31 | token: marketingApiKey, 32 | }, ctx); 33 | }, 34 | }); 35 | 36 | return api; 37 | }; 38 | -------------------------------------------------------------------------------- /lib/apis/mailgun.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type MailgunOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Mailgun API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/mailgun 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const mailgun = ({ 17 | apiKey = Deno.env.get("MAILGUN_API_KEY")!, 18 | }: MailgunOptions) => { 19 | const api = createApi({ 20 | baseURL: `https://api.mailgun.net`, 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "api", 30 | value: `${apiKey}`, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/medium.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type MediumOptions = { 5 | accessToken: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Medium API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/medium 12 | * 13 | * @param {string} accessToken - the token to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const medium = ({ 17 | accessToken = Deno.env.get("MEDIUM_ACCESS_TOKEN")!, 18 | }: MediumOptions) => { 19 | const api = createApi({ 20 | baseURL: `https://api.medium.com/v1`, 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "bearer", 28 | token: accessToken, 29 | }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/monday.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type MondayOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Monday API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/monday 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const monday = ({ 17 | apiKey = Deno.env.get("MONDAY_API_KEY")!, 18 | }: MondayOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.monday.com/v2", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "Authorization", 30 | value: apiKey, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/mongodbatlasdata.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type MongoDbAtlasDataOptions = { 5 | dataApiAppId: string; 6 | apiKey: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Mongodb Atlas Data API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/mongodbatlasdata 13 | * 14 | * @param {string} apiKey - the API key to use for authentication 15 | * @returns {object} - an API client instance 16 | */ 17 | export const mongodbatlasdata = ({ 18 | dataApiAppId = Deno.env.get("MONGODBATLASDATA_DATA_API_APP_ID")!, 19 | apiKey = Deno.env.get("MONGODBATLASDATA_API_KEY")!, 20 | }: MongoDbAtlasDataOptions) => { 21 | const api = createApi({ 22 | baseURL: `https://data.mongodb-api.com/app/${dataApiAppId}/endpoint/data/v1`, 23 | headers: { 24 | "content-type": "application/json", 25 | }, 26 | ignoreResponseError: true, 27 | async onRequest(ctx) { 28 | await auth({ 29 | type: "apiKey", 30 | in: "header", 31 | name: "api-key", 32 | value: apiKey, 33 | }, ctx); 34 | }, 35 | }); 36 | 37 | return api; 38 | }; 39 | -------------------------------------------------------------------------------- /lib/apis/netzo.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type NetzoOptions = { 5 | apiKey: string; 6 | baseURL?: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Netzo API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/netzo 13 | * 14 | * @param {string} apiKey - the API key to use for authentication 15 | * @param {string} baseURL - (internal) the base URL to use for the API 16 | * @returns {object} - an API client instance 17 | */ 18 | export const netzo = ({ 19 | apiKey = Deno.env.get("NETZO_API_KEY")!, 20 | baseURL = Deno.env.get("NETZO_API_URL") || "https://api.netzo.io", 21 | }: NetzoOptions) => { 22 | const api = createApi({ 23 | baseURL, 24 | headers: { 25 | "content-type": "application/json", 26 | }, 27 | ignoreResponseError: true, 28 | async onRequest(ctx) { 29 | await auth({ 30 | type: "apiKey", 31 | in: "header", 32 | // heuristic to determine if apiKey (64) or envVarApiKey (128) 33 | name: apiKey.length === 64 ? "x-api-key" : "x-env-var-api-key", 34 | value: apiKey, 35 | }, ctx); 36 | }, 37 | }); 38 | 39 | return api; 40 | }; 41 | -------------------------------------------------------------------------------- /lib/apis/notion.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type NotionOptions = { 5 | internalIntegrationToken: string; 6 | notionVersion: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Notion API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/notion 13 | * 14 | * @param {string} internalIntegrationToken - the token to use for authentication 15 | * @param {string} notionVersion - the Notion API version to use (a date string) 16 | * @returns {object} - an API client instance 17 | */ 18 | export const notion = ({ 19 | internalIntegrationToken = Deno.env.get("NOTION_INTERNAL_INTEGRATION_TOKEN")!, 20 | notionVersion = Deno.env.get("NOTION_VERSION")!, 21 | }: NotionOptions) => { 22 | const api = createApi({ 23 | baseURL: `https://api.notion.com/v1`, 24 | headers: { 25 | "content-type": "application/json", 26 | "Notion-Version": notionVersion, 27 | }, 28 | ignoreResponseError: true, 29 | async onRequest(ctx) { 30 | await auth({ 31 | type: "bearer", 32 | token: internalIntegrationToken, 33 | }, ctx); 34 | }, 35 | }); 36 | 37 | return api; 38 | }; 39 | -------------------------------------------------------------------------------- /lib/apis/openai.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type OpenAIOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the OpenAI API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/openai 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const openai = ({ 17 | apiKey = Deno.env.get("OPENAI_API_KEY")!, 18 | }: OpenAIOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.openai.com/v1", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "Authorization", 30 | value: apiKey, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/paddle.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | // TODO: import type { } from "./types.ts"; 4 | 5 | export type PaddleOptions = { 6 | apiKey: string; 7 | baseURL?: string; 8 | }; 9 | 10 | /** 11 | * Factory function for the Paddle API 12 | * 13 | * @see https://developer.paddle.com/api/overview 14 | * 15 | * @param {string} apiKey - the API key to use for authentication 16 | * @param {string} baseURL - the base URL to use for the API 17 | * @returns {object} - an API client instance 18 | */ 19 | export const paddle = ({ 20 | apiKey = Deno.env.get("PADDLE_API_KEY")!, 21 | baseURL = "https://api.paddle.com/", // or https://sandbox-api.paddle.com/ 22 | }: PaddleOptions) => { 23 | const api = createApi({ 24 | baseURL, 25 | headers: { 26 | "content-type": "application/json", 27 | "Paddle-Version": "1", 28 | }, 29 | ignoreResponseError: true, 30 | async onRequest(ctx) { 31 | await auth({ 32 | type: "bearer", 33 | token: apiKey, 34 | }, ctx); 35 | }, 36 | }); 37 | 38 | return api; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/apis/pandadoc.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type PandaDocOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the PandaDoc API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/pandadoc 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const pandadoc = ({ 17 | apiKey = Deno.env.get("PANDADOC_API_KEY")!, 18 | }: PandaDocOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.pandadoc.com/public/v1", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "apiKey", 28 | in: "header", 29 | name: "Authorization", 30 | value: `API-Key ${apiKey}`, 31 | }, ctx); 32 | }, 33 | }); 34 | 35 | return api; 36 | }; 37 | -------------------------------------------------------------------------------- /lib/apis/pipedrive.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type PipeDriveOptions = { 5 | apiToken: string; 6 | companyDomain: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the Pipedrive API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/pipedrive 13 | * 14 | * @param {string} apiToken - the token to use for authentication 15 | * @param {string} companyDomain - the company domain to use for authentication 16 | * @returns {object} - an API client instance 17 | */ 18 | export const pipedrive = ({ 19 | apiToken = Deno.env.get("PIPEDRIVE_API_TOKEN")!, 20 | companyDomain = Deno.env.get("PIPEDRIVE_COMPANY_DOMAIN")!, 21 | }: PipeDriveOptions) => { 22 | const api = createApi({ 23 | baseURL: `https://${companyDomain}.pipedrive.com/v1`, 24 | headers: { 25 | "content-type": "application/json", 26 | }, 27 | ignoreResponseError: true, 28 | async onRequest(ctx) { 29 | await auth({ 30 | type: "apiKey", 31 | in: "query", 32 | name: "api_token", 33 | value: apiToken, 34 | }, ctx); 35 | }, 36 | }); 37 | 38 | return api; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/apis/rest.ts: -------------------------------------------------------------------------------- 1 | import { createApi } from "./create-api/mod.ts"; 2 | 3 | export type RestOptions = Parameters[0]; 4 | 5 | /** 6 | * Factory function for REST APIs 7 | * 8 | * @see https://netzo.io/docs/modules/integrations/apis/rest 9 | * 10 | * @param {string} options - the configuration for the API 11 | * @returns {object} - an API client instance 12 | */ 13 | export const rest = (options: RestOptions) => { 14 | const api = createApi(options); 15 | 16 | return api; 17 | }; 18 | -------------------------------------------------------------------------------- /lib/apis/sendgrid.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type SendgridOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Sendgrid API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/sendgrid 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const sendgrid = ({ 17 | apiKey = Deno.env.get("SENDGRID_API_KEY")!, 18 | }: SendgridOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.sendgrid.com/v3", 21 | headers: { 22 | "content-type": "application/json", 23 | }, 24 | ignoreResponseError: true, 25 | async onRequest(ctx) { 26 | await auth({ 27 | type: "bearer", 28 | token: apiKey, 29 | }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/shopify.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type ShopifyOptions = { 5 | storeName: string; 6 | apiVersion: string; 7 | apiKey: string; 8 | }; 9 | 10 | /** 11 | * Factory function for the Shopify Admin API 12 | * 13 | * @see https://netzo.io/docs/modules/integrations/apis/shopify 14 | * 15 | * @param {string} storeName - the store name to construct the base URL 16 | * @param {string} apiVersion - the version to use for the base URL 17 | * @param {string} apiKey - the API key to use for authentication 18 | * @returns {object} - an API client instance 19 | */ 20 | export const shopify = ({ 21 | storeName = Deno.env.get("SHOPIFY_STORE_NAME")!, 22 | apiVersion = Deno.env.get("SHOPIFY_API_VERSION")!, 23 | apiKey = Deno.env.get("SHOPIFY_API_KEY")!, 24 | }: ShopifyOptions) => { 25 | const api = createApi({ 26 | baseURL: `https://${storeName}.myshopify.com/admin/api/${apiVersion}`, 27 | headers: { 28 | "content-type": "application/json", 29 | }, 30 | ignoreResponseError: true, 31 | async onRequest(ctx) { 32 | await auth({ 33 | type: "apiKey", 34 | in: "header", 35 | name: "X-Shopify-Access-Token", 36 | value: apiKey, 37 | }, ctx); 38 | }, 39 | }); 40 | 41 | return api; 42 | }; 43 | -------------------------------------------------------------------------------- /lib/apis/stripe.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type StripeOptions = { 5 | apiKey: string; 6 | }; 7 | 8 | /** 9 | * Factory function for the Stripe API 10 | * 11 | * @see https://netzo.io/docs/modules/integrations/apis/stripe 12 | * 13 | * @param {string} apiKey - the API key to use for authentication 14 | * @returns {object} - an API client instance 15 | */ 16 | export const stripe = ({ 17 | apiKey = Deno.env.get("STRIPE_API_KEY")!, 18 | }: StripeOptions) => { 19 | const api = createApi({ 20 | baseURL: "https://api.stripe.com/v1", 21 | // NOTE: use new URLSearchParams() for body with [] 22 | // syntax for nested fields, for example: 23 | // const body = new URLSearchParams({ 24 | // amount: "1999", // in cents not euros 25 | // currency: "eur", 26 | // "automatic_payment_methods[enabled]": "true", 27 | // }) 28 | headers: { 29 | "accept": "application/json", 30 | "content-type": "application/x-www-form-urlencoded", 31 | }, 32 | ignoreResponseError: true, 33 | async onRequest(ctx) { 34 | await auth({ 35 | type: "bearer", 36 | token: apiKey, 37 | }, ctx); 38 | }, 39 | }); 40 | 41 | return api; 42 | }; 43 | -------------------------------------------------------------------------------- /lib/apis/whatsappbusiness.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type WhatsappBusinessOptions = { 5 | businessAccountId: string; 6 | permanentToken: string; 7 | }; 8 | 9 | /** 10 | * Factory function for the WhatsApp Business API 11 | * 12 | * @see https://netzo.io/docs/modules/integrations/apis/whatsappbusiness 13 | * 14 | * @param {string} apiKey - the API key to use for authentication 15 | * @returns {object} - an API client instance 16 | */ 17 | export const whatsappbusiness = ({ 18 | businessAccountId = Deno.env.get("WHATSAPPBUSINESS_BUSINESS_ACCOUNT_ID") || 19 | "", 20 | permanentToken = Deno.env.get("WHATSAPPBUSINESS_PERMANENT_TOKEN")!, 21 | }: WhatsappBusinessOptions) => { 22 | const api = createApi({ 23 | baseURL: `https://graph.facebook.com/v17.0/${businessAccountId}`, 24 | headers: { 25 | "content-type": "application/json", 26 | }, 27 | ignoreResponseError: true, 28 | async onRequest(ctx) { 29 | await auth({ type: "bearer", token: permanentToken }, ctx); 30 | }, 31 | }); 32 | 33 | return api; 34 | }; 35 | -------------------------------------------------------------------------------- /lib/apis/wix.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "./create-api/auth/mod.ts"; 2 | import { createApi } from "./create-api/mod.ts"; 3 | 4 | export type WixOptions = { 5 | accountId: string; 6 | siteId: string; 7 | apiKey: string; 8 | }; 9 | 10 | /** 11 | * Factory function for the Wix API 12 | * 13 | * @see https://netzo.io/docs/modules/integrations/apis/wix 14 | * 15 | * @param {string} accountId - the account id to construct the request headers 16 | * @param {string} siteId - the site id to construct the request headers 17 | * @param {string} apiKey - the API key to use for authentication 18 | * @returns {object} - an API client instance 19 | */ 20 | export const wix = ({ 21 | accountId = Deno.env.get("WIX_ACCOUNT_ID")!, 22 | siteId = Deno.env.get("WIX_SITE_ID")!, 23 | apiKey = Deno.env.get("WIX_API_KEY")!, 24 | }: WixOptions) => { 25 | const api = createApi({ 26 | baseURL: `https://www.wixapis.com`, 27 | headers: { 28 | "content-type": "application/json", 29 | "wix-account-id": accountId, 30 | "wix-site-id": siteId, 31 | }, 32 | ignoreResponseError: true, 33 | async onRequest(ctx) { 34 | await auth({ 35 | type: "apiKey", 36 | in: "header", 37 | name: "Authorization", 38 | value: apiKey, 39 | }, ctx); 40 | }, 41 | }); 42 | 43 | return api; 44 | }; 45 | -------------------------------------------------------------------------------- /lib/cli/dev/cli.ts: -------------------------------------------------------------------------------- 1 | // adapted from https://github.com/denoland/fresh/blob/main/src/dev/cli.ts 2 | import { type FreshConfig } from "fresh/server.ts"; 3 | import { manifest } from "fresh/src/dev/mod.ts"; 4 | import { join, toFileUrl } from "../../deps/@std/path.ts"; 5 | 6 | const [cmd, configURL] = Deno.args; 7 | 8 | switch (cmd) { 9 | case "manifest": { 10 | if (configURL) { 11 | const CONFIG_TS_PATH = join(configURL, "netzo.config.ts"); 12 | const url = toFileUrl(CONFIG_TS_PATH).toString(); 13 | const config: FreshConfig = (await import(url)).default; 14 | await manifest(configURL, config?.router?.ignoreFilePattern); 15 | } else { 16 | console.error("Missing input for manifest command"); 17 | Deno.exit(1); 18 | } 19 | break; 20 | } 21 | default: { 22 | console.error("Invalid command"); 23 | Deno.exit(1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/cli/src/args.ts: -------------------------------------------------------------------------------- 1 | import { parse } from "../../deps/@std/flags.ts"; 2 | 3 | export function parseArgs(args: string[]) { 4 | const parsed = parse(args, { 5 | alias: { 6 | "help": "h", 7 | "version": "V", 8 | "dir": "d", 9 | "project": "p", 10 | }, 11 | boolean: [ 12 | "help", 13 | "build", 14 | "production", 15 | "static", 16 | "version", 17 | "dry-run", 18 | ], 19 | string: [ 20 | "project", 21 | "api-key", 22 | "include", 23 | "exclude", 24 | "import-map", 25 | "lock-file", 26 | "deployment", 27 | "api-url", 28 | "app-url", 29 | ], 30 | collect: ["include", "exclude"], 31 | default: { 32 | static: true, 33 | apiKey: Deno.env.get("NETZO_API_KEY"), 34 | apiUrl: Deno.env.get("NETZO_API_URL"), 35 | appUrl: Deno.env.get("NETZO_APP_URL"), 36 | }, 37 | }); 38 | return parsed; 39 | } 40 | 41 | export type Args = ReturnType; 42 | -------------------------------------------------------------------------------- /lib/cli/src/utils/api.ts: -------------------------------------------------------------------------------- 1 | export type RequestOptions = { 2 | method?: string; 3 | body?: unknown; 4 | }; 5 | 6 | export class APIError extends Error { 7 | code: string; 8 | xDenoRay: string | null; 9 | 10 | name = "APIError"; 11 | 12 | constructor(code: string, message: string, xDenoRay: string | null) { 13 | super(message); 14 | this.code = code; 15 | this.xDenoRay = xDenoRay; 16 | } 17 | 18 | toString() { 19 | let error = `${this.name}: ${this.message}`; 20 | if (this.xDenoRay !== null) { 21 | error += `\nx-deno-ray: ${this.xDenoRay}`; 22 | error += "\nIf you encounter this error frequently," + 23 | " contact us at help@netzo.io with the above x-deno-ray."; 24 | } 25 | return error; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/cli/src/utils/entrypoint.ts: -------------------------------------------------------------------------------- 1 | import { resolve, toFileUrl } from "../../../deps/@std/path.ts"; 2 | 3 | /** 4 | * Parses the entrypoint to a URL. 5 | * Ensures the file exists when the entrypoint is a local file. 6 | */ 7 | export async function parseEntrypoint( 8 | entrypoint: string, 9 | root?: string, 10 | diagnosticName = "entrypoint", 11 | ): Promise { 12 | let entrypointSpecifier: URL; 13 | try { 14 | if ( 15 | entrypoint.startsWith("https://") || entrypoint.startsWith("http://") || 16 | entrypoint.startsWith("file://") 17 | ) { 18 | entrypointSpecifier = new URL(entrypoint); 19 | } else { 20 | entrypointSpecifier = toFileUrl(resolve(root ?? Deno.cwd(), entrypoint)); 21 | } 22 | } catch (err) { 23 | throw `Failed to parse ${diagnosticName} specifier '${entrypoint}': ${err.message}`; 24 | } 25 | 26 | if (entrypointSpecifier.protocol == "file:") { 27 | try { 28 | await Deno.lstat(entrypointSpecifier); 29 | } catch (err) { 30 | throw `Failed to open ${diagnosticName} file at '${entrypointSpecifier}': ${err.message}`; 31 | } 32 | } 33 | 34 | return entrypointSpecifier; 35 | } 36 | -------------------------------------------------------------------------------- /lib/cli/src/utils/info.ts: -------------------------------------------------------------------------------- 1 | import { join } from "../../../deps/@std/path.ts"; 2 | import { getVersions } from "../subcommands/upgrade.ts"; 3 | 4 | export function getConfigPaths() { 5 | const homeDir = Deno.build.os == "windows" ? Deno.env.get("USERPROFILE")! : Deno.env.get("HOME")!; 6 | const configDir = join(homeDir, ".deno", "netzo"); 7 | 8 | return { 9 | configDir, 10 | updatePath: join(configDir, "update.json"), 11 | }; 12 | } 13 | 14 | export async function fetchReleases() { 15 | try { 16 | const { latest } = await getVersions(); 17 | const updateInfo = { lastFetched: Date.now(), latest }; 18 | const { updatePath, configDir } = getConfigPaths(); 19 | await Deno.mkdir(configDir, { recursive: true }); 20 | await Deno.writeFile( 21 | updatePath, 22 | new TextEncoder().encode(JSON.stringify(updateInfo, null, 2)), 23 | ); 24 | } catch (_) { 25 | // We will try again later when the fetch isn't successful, 26 | // so we shouldn't report errors. 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/cli/src/utils/mod.ts: -------------------------------------------------------------------------------- 1 | export { fromFileUrl, resolve } from "../../../deps/@std/path.ts"; 2 | export { APIError } from "./api.ts"; 3 | export { parseEntrypoint } from "./entrypoint.ts"; 4 | export { walk } from "./walk.ts"; 5 | -------------------------------------------------------------------------------- /lib/cli/src/version.ts: -------------------------------------------------------------------------------- 1 | // latest version of netzo/cli (see https://github.com/netzo/netzo/releases) 2 | export const VERSION = "0.5.119"; 3 | 4 | // minimum version of Deno required to run this CLI 5 | // (see https://github.com/denoland/deployctl/blob/main/src/version.ts) 6 | export const MINIMUM_DENO_VERSION = "1.44.4"; 7 | -------------------------------------------------------------------------------- /lib/cli/tests/utils.ts: -------------------------------------------------------------------------------- 1 | export type Permissions = { 2 | net: boolean; 3 | read: boolean; 4 | write: boolean; 5 | env: boolean; 6 | run: boolean; 7 | }; 8 | 9 | export function netzo( 10 | args: string[], 11 | permissions: Permissions = { 12 | net: true, 13 | read: true, 14 | write: true, 15 | env: true, 16 | run: true, 17 | }, 18 | ): Deno.ChildProcess { 19 | const deno = [ 20 | Deno.execPath(), 21 | "run", 22 | ]; 23 | 24 | if (permissions?.net) deno.push("--allow-net"); 25 | if (permissions?.read) deno.push("--allow-read"); 26 | if (permissions?.write) deno.push("--allow-write"); 27 | if (permissions?.env) deno.push("--allow-env"); 28 | if (permissions?.run) deno.push("--allow-run"); 29 | 30 | deno.push(new URL("../netzo.ts", import.meta.url).toString()); 31 | 32 | const cmd = Deno.build.os == "linux" 33 | ? ["bash", "-c", [...deno, ...args].join(" ")] 34 | : [...deno, ...args]; 35 | 36 | return new Deno.Command(cmd[0], { 37 | args: cmd.slice(1), 38 | stdin: "null", 39 | stdout: "piped", 40 | stderr: "piped", 41 | }).spawn(); 42 | } 43 | 44 | export type TestOptions = { 45 | args: string[]; 46 | name?: string; 47 | permissions?: Permissions; 48 | }; 49 | 50 | export async function output( 51 | proc: Deno.ChildProcess, 52 | ): Promise<[string, string, Deno.CommandStatus]> { 53 | const [status, { stdout, stderr }] = await Promise.all([ 54 | proc.status, 55 | proc.output(), 56 | ]); 57 | return [ 58 | new TextDecoder().decode(stdout), 59 | new TextDecoder().decode(stderr), 60 | status, 61 | ]; 62 | } 63 | -------------------------------------------------------------------------------- /lib/components/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | 3 | import * as AspectRatioPrimitive from "../deps/@radix-ui/react-aspect-ratio.ts"; 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root; 6 | 7 | export { AspectRatio }; 8 | -------------------------------------------------------------------------------- /lib/components/avatar.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as AvatarPrimitive from "../deps/@radix-ui/react-avatar.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Avatar = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | )); 20 | Avatar.displayName = AvatarPrimitive.Root.displayName; 21 | 22 | const AvatarImage = React.forwardRef< 23 | React.ElementRef, 24 | React.ComponentPropsWithoutRef 25 | >(({ className, ...props }, ref) => ( 26 | 31 | )); 32 | AvatarImage.displayName = AvatarPrimitive.Image.displayName; 33 | 34 | const AvatarFallback = React.forwardRef< 35 | React.ElementRef, 36 | React.ComponentPropsWithoutRef 37 | >(({ className, ...props }, ref) => ( 38 | 46 | )); 47 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; 48 | 49 | export { Avatar, AvatarFallback, AvatarImage }; 50 | -------------------------------------------------------------------------------- /lib/components/badge.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { cva, type VariantProps } from "../deps/class-variance-authority.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const badgeVariants = cva( 8 | "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 9 | { 10 | variants: { 11 | variant: { 12 | default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-opacity-80", 13 | secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-opacity-80", 14 | destructive: 15 | "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-opacity-80", 16 | outline: "text-foreground", 17 | }, 18 | }, 19 | defaultVariants: { 20 | variant: "default", 21 | }, 22 | }, 23 | ); 24 | 25 | export interface BadgeProps 26 | extends React.HTMLAttributes, VariantProps {} 27 | 28 | function Badge({ className, variant, ...props }: BadgeProps) { 29 | return
; 30 | } 31 | 32 | export { Badge, badgeVariants }; 33 | -------------------------------------------------------------------------------- /lib/components/blocks/kanban/utils.ts: -------------------------------------------------------------------------------- 1 | // adapted from https://github.com/Georgegriff/react-dnd-kit-tailwind-shadcn-ui/blob/main/src/components/utils.ts 2 | import { Active, DataRef, Over } from "../../../deps/@dnd-kit/core.ts"; 3 | import type { CardDragData, GroupDragData } from "./kanban.tsx"; 4 | 5 | type DraggableData = GroupDragData | CardDragData; 6 | 7 | export function hasDraggableData( 8 | entry: T | null | undefined, 9 | ): entry is T & { 10 | data: DataRef; 11 | } { 12 | if (!entry) return false; 13 | 14 | const data = entry.data.current; 15 | 16 | if (data?.type === "Group" || data?.type === "Item") return true; 17 | 18 | return false; 19 | } 20 | -------------------------------------------------------------------------------- /lib/components/blocks/table/hooks/use-table-pagination.ts: -------------------------------------------------------------------------------- 1 | import type { Table } from "../table.tsx"; 2 | 3 | export const useTablePagination = >( 4 | table: Table, 5 | ) => { 6 | const { pageIndex, pageSize } = table.getState().pagination; 7 | const from = pageIndex * pageSize + 1; 8 | const to = from + pageSize - 1; 9 | const total = table.getFilteredRowModel().rows.length; 10 | return { pageIndex, pageSize, from, to, total }; 11 | }; 12 | -------------------------------------------------------------------------------- /lib/components/blocks/table/table-actions.tsx: -------------------------------------------------------------------------------- 1 | import type { JSX } from "preact"; 2 | import type { Table } from "../../../deps/@tanstack/react-table.ts"; 3 | import { Button } from "../../button.tsx"; 4 | import { cn } from "../../utils.ts"; 5 | 6 | export function TableActionsReload({ 7 | className, 8 | table, 9 | }: JSX.IntrinsicElements["button"] & { table: Table }) { 10 | return ( 11 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /lib/components/blocks/table/table-row-actions.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { Button } from "../../button.tsx"; 5 | import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "../../dropdown-menu.tsx"; 6 | 7 | export function TableRowActions(props: { children?: React.ReactNode }) { 8 | return ( 9 | 10 | 11 | 18 | 19 | 20 | {props.children} 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/components/blocks/table/table-search.tsx: -------------------------------------------------------------------------------- 1 | import type { JSX } from "preact"; 2 | import { Input } from "../../input.tsx"; 3 | import { cn } from "../../utils.ts"; 4 | import { type Table } from "./table.tsx"; 5 | 6 | export type TableSearch = { 7 | column: string; 8 | placeholder?: string; 9 | }; 10 | 11 | export function TableSearch({ 12 | className, 13 | table, 14 | }: JSX.IntrinsicElements["input"] & { table: Table }) { 15 | if (!table.options?.initialState?.search) { 16 | console.error(`Missing "search" property in table.options.initialState`); 17 | return null; 18 | } 19 | 20 | const { column, placeholder } = table.options.initialState 21 | ?.search as TableSearch; 22 | 23 | return ( 24 | table.getColumn(column)?.setFilterValue(e.target.value)} 29 | className={cn("h-8 w-[150px] lg:w-[250px]", className)} 30 | autocomplete="off" 31 | /> 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /lib/components/button-dark-mode.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { IS_BROWSER } from "fresh/runtime.ts"; 5 | import { Button, type ButtonProps } from "./button.tsx"; 6 | import { useDarkMode } from "./use-dark-mode.ts"; 7 | import { cn } from "./utils.ts"; 8 | 9 | export type ButtonDarkModeProps = ButtonProps; 10 | 11 | export function ButtonDarkMode({ className, ...props }: ButtonDarkModeProps) { 12 | const darkMode = useDarkMode(); 13 | 14 | return ( 15 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /lib/components/checkbox.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as CheckboxPrimitive from "../deps/@radix-ui/react-checkbox.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Checkbox = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 22 | 23 | 24 | 25 | )); 26 | Checkbox.displayName = CheckboxPrimitive.Root.displayName; 27 | 28 | export { Checkbox }; 29 | -------------------------------------------------------------------------------- /lib/components/client-only.tsx: -------------------------------------------------------------------------------- 1 | import { IS_BROWSER } from "fresh/runtime.ts"; 2 | import type { ComponentChildren } from "preact"; 3 | 4 | export const ClientOnly = ({ children }: { children: ComponentChildren }) => { 5 | return IS_BROWSER ? children : null; 6 | }; 7 | -------------------------------------------------------------------------------- /lib/components/collapsible.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | 3 | import * as CollapsiblePrimitive from "../deps/@radix-ui/react-collapsible.ts"; 4 | 5 | const Collapsible = CollapsiblePrimitive.Root; 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger; 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent; 10 | 11 | export { Collapsible, CollapsibleContent, CollapsibleTrigger }; 12 | -------------------------------------------------------------------------------- /lib/components/date-picker.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { format } from "../deps/date-fns.ts"; 5 | import { Button } from "./button.tsx"; 6 | import { Calendar } from "./calendar.tsx"; 7 | import { Popover, PopoverContent, PopoverTrigger } from "./popover.tsx"; 8 | import { cn } from "./utils.ts"; 9 | 10 | export const DatePicker = React.forwardRef< 11 | HTMLDivElement, 12 | { 13 | date?: Date; 14 | setDate: (date?: Date) => void; 15 | } 16 | >(function DatePickerCmp({ date, setDate }, ref) { 17 | return ( 18 | 19 | 20 | 30 | 31 | 32 | 38 | 39 | 40 | ); 41 | }); 42 | -------------------------------------------------------------------------------- /lib/components/hover-card.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as HoverCardPrimitive from "../deps/@radix-ui/react-hover-card.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const HoverCard = HoverCardPrimitive.Root; 8 | 9 | const HoverCardTrigger = HoverCardPrimitive.Trigger; 10 | 11 | const HoverCardContent = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef 14 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 15 | 25 | )); 26 | HoverCardContent.displayName = HoverCardPrimitive.Content.displayName; 27 | 28 | export { HoverCard, HoverCardContent, HoverCardTrigger }; 29 | -------------------------------------------------------------------------------- /lib/components/icon-copy.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { useSignal } from "@preact/signals"; 5 | import { cn } from "./utils.ts"; 6 | 7 | type IconCopyProps = { 8 | value: string; 9 | tooltip?: string; 10 | }; 11 | 12 | export function IconCopy({ value, tooltip = "Copy" }: IconCopyProps) { 13 | const isCopied = useSignal(false); 14 | const handleCopy = () => { 15 | navigator.clipboard.writeText(value); 16 | isCopied.value = true; 17 | setTimeout(() => isCopied.value = false, 500); 18 | }; 19 | 20 | return ( 21 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /lib/components/input.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { IS_BROWSER } from "fresh/runtime.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | // deno-lint-ignore no-empty-interface 8 | export interface InputProps extends React.InputHTMLAttributes {} 9 | 10 | const Input = React.forwardRef( 11 | ({ className, type, ...props }, ref) => { 12 | return ( 13 | 23 | ); 24 | }, 25 | ); 26 | Input.displayName = "Input"; 27 | 28 | export { Input }; 29 | -------------------------------------------------------------------------------- /lib/components/label.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as LabelPrimitive from "../deps/@radix-ui/react-label.ts"; 5 | import { cva, type VariantProps } from "../deps/class-variance-authority.ts"; 6 | import { cn } from "./utils.ts"; 7 | 8 | const labelVariants = cva( 9 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", 10 | ); 11 | 12 | const Label = React.forwardRef< 13 | React.ElementRef, 14 | & React.ComponentPropsWithoutRef 15 | & VariantProps 16 | >(({ className, ...props }, ref) => ( 17 | 22 | )); 23 | Label.displayName = LabelPrimitive.Root.displayName; 24 | 25 | export { Label }; 26 | -------------------------------------------------------------------------------- /lib/components/nav-link.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | // adapted from https://github.com/shadcn-ui/ui/issues/414#issuecomment-1772421366 5 | import type { JSX } from "preact"; 6 | import { Slot } from "../deps/@radix-ui/react-slot.ts"; 7 | import { type VariantProps } from "../deps/class-variance-authority.ts"; 8 | import { buttonVariants } from "./button.tsx"; // Assuming Button.tsx is in the same directory 9 | import { cn } from "./utils.ts"; 10 | 11 | export interface NavLinkProps 12 | extends Omit, "size">, VariantProps { 13 | asChild?: boolean; 14 | } 15 | 16 | const NavLink = React.forwardRef(({ 17 | className, 18 | variant, 19 | asChild = false, 20 | ...props 21 | }, ref) => { 22 | const Comp = asChild ? Slot : "a"; 23 | return ( 24 | 33 | ); 34 | }); 35 | NavLink.displayName = "NavLink"; 36 | 37 | export { NavLink }; 38 | -------------------------------------------------------------------------------- /lib/components/popover.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as PopoverPrimitive from "../deps/@radix-ui/react-popover.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Popover = PopoverPrimitive.Root; 8 | 9 | const PopoverTrigger = PopoverPrimitive.Trigger; 10 | 11 | const PopoverAnchor = PopoverPrimitive.Anchor; 12 | 13 | const PopoverContent = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef 16 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 17 | 18 | 28 | 29 | )); 30 | PopoverContent.displayName = PopoverPrimitive.Content.displayName; 31 | 32 | export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger }; 33 | -------------------------------------------------------------------------------- /lib/components/progress.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as ProgressPrimitive from "../deps/@radix-ui/react-progress.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Progress = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, value, ...props }, ref) => ( 11 | 19 | 23 | 24 | )); 25 | Progress.displayName = ProgressPrimitive.Root.displayName; 26 | 27 | export { Progress }; 28 | -------------------------------------------------------------------------------- /lib/components/radio-group.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as RadioGroupPrimitive from "../deps/@radix-ui/react-radio-group.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const RadioGroup = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => { 11 | return ( 12 | 17 | ); 18 | }); 19 | RadioGroup.displayName = RadioGroupPrimitive.Root.displayName; 20 | 21 | const RadioGroupItem = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, ...props }, ref) => { 25 | return ( 26 | 34 | 35 | 36 | 37 | 38 | ); 39 | }); 40 | RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName; 41 | 42 | export { RadioGroup, RadioGroupItem }; 43 | -------------------------------------------------------------------------------- /lib/components/separator.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as SeparatorPrimitive from "../deps/@radix-ui/react-separator.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Separator = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >( 11 | ( 12 | { className, orientation = "horizontal", decorative = true, ...props }, 13 | ref, 14 | ) => ( 15 | 26 | ), 27 | ); 28 | Separator.displayName = SeparatorPrimitive.Root.displayName; 29 | 30 | export { Separator }; 31 | -------------------------------------------------------------------------------- /lib/components/skeleton.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { cn } from "./utils.ts"; 5 | 6 | function Skeleton({ 7 | className, 8 | ...props 9 | }: React.HTMLAttributes) { 10 | return ( 11 |
15 | ); 16 | } 17 | 18 | export { Skeleton }; 19 | -------------------------------------------------------------------------------- /lib/components/slider.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as SliderPrimitive from "../deps/@radix-ui/react-slider.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Slider = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 20 | 21 | 22 | 23 | 24 | )); 25 | Slider.displayName = SliderPrimitive.Root.displayName; 26 | 27 | export { Slider }; 28 | -------------------------------------------------------------------------------- /lib/components/sooner.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { Toaster as Sonner } from "../deps/sonner.ts"; 5 | import { useDarkMode } from "./use-dark-mode.ts"; 6 | 7 | type ToasterProps = React.ComponentProps; 8 | 9 | const Toaster = ({ ...props }: ToasterProps) => { 10 | const darkMode = useDarkMode(); 11 | 12 | const theme = darkMode.value ? "dark" : "light"; 13 | 14 | return ( 15 | 29 | ); 30 | }; 31 | 32 | export { Toaster }; 33 | -------------------------------------------------------------------------------- /lib/components/switch.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import * as SwitchPrimitives from "../deps/@radix-ui/react-switch.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | const Switch = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 24 | 25 | )); 26 | Switch.displayName = SwitchPrimitives.Root.displayName; 27 | 28 | export { Switch }; 29 | -------------------------------------------------------------------------------- /lib/components/textarea.tsx: -------------------------------------------------------------------------------- 1 | // @deno-types="npm:@types/react@18.2.60" 2 | import * as React from "react"; 3 | 4 | import { IS_BROWSER } from "fresh/runtime.ts"; 5 | import { cn } from "./utils.ts"; 6 | 7 | // deno-lint-ignore no-empty-interface 8 | export interface TextareaProps extends React.TextareaHTMLAttributes {} 9 | 10 | const Textarea = React.forwardRef( 11 | ({ className, ...props }, ref) => { 12 | return ( 13 |