Showing preview only (4,711K chars total). Download the full file or copy to clipboard to get everything.
Repository: gitroomhq/postiz-app
Branch: main
Commit: cf2a980dd8b2
Files: 803
Total size: 4.3 MB
Directory structure:
gitextract_ft7oghrf/
├── .coderabbit.yaml
├── .devcontainer/
│ └── devcontainer.json
├── .dockerignore
├── .eslintignore
├── .github/
│ ├── Dependabot.yml
│ ├── FUNDING.yaml
│ ├── ISSUE_TEMPLATE/
│ │ ├── 01_bug_report.yml
│ │ ├── 02_feature_request.yml
│ │ └── config.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── copilot-instructions.md
│ └── workflows/
│ ├── build-containers.yml
│ ├── build-extension.yaml
│ ├── build.yml
│ ├── codeql.yml
│ ├── eslint
│ ├── issue-label-triggers.yml
│ ├── pr-docker-build.yml
│ ├── pr-quality.yml
│ ├── publish-extension.yml
│ └── stale.yml
├── .gitignore
├── .gitmodules
├── .npmrc
├── .prettierignore
├── .prettierrc
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile.dev
├── Jenkins/
│ ├── Build.Jenkinsfile
│ └── BuildPR.Jenkinsfile
├── LICENSE
├── README.md
├── SECURITY.md
├── apps/
│ ├── backend/
│ │ ├── .gitignore
│ │ ├── nest-cli.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── api/
│ │ │ │ ├── api.module.ts
│ │ │ │ └── routes/
│ │ │ │ ├── analytics.controller.ts
│ │ │ │ ├── approved-apps.controller.ts
│ │ │ │ ├── auth.controller.ts
│ │ │ │ ├── autopost.controller.ts
│ │ │ │ ├── billing.controller.ts
│ │ │ │ ├── copilot.controller.ts
│ │ │ │ ├── enterprise.controller.ts
│ │ │ │ ├── integrations.controller.ts
│ │ │ │ ├── media.controller.ts
│ │ │ │ ├── monitor.controller.ts
│ │ │ │ ├── no.auth.integrations.controller.ts
│ │ │ │ ├── notifications.controller.ts
│ │ │ │ ├── oauth-app.controller.ts
│ │ │ │ ├── oauth.controller.ts
│ │ │ │ ├── posts.controller.ts
│ │ │ │ ├── public.controller.ts
│ │ │ │ ├── root.controller.ts
│ │ │ │ ├── sets.controller.ts
│ │ │ │ ├── settings.controller.ts
│ │ │ │ ├── signature.controller.ts
│ │ │ │ ├── stripe.controller.ts
│ │ │ │ ├── third-party.controller.ts
│ │ │ │ ├── users.controller.ts
│ │ │ │ └── webhooks.controller.ts
│ │ │ ├── app.module.ts
│ │ │ ├── assets/
│ │ │ │ └── .gitkeep
│ │ │ ├── main.ts
│ │ │ ├── public-api/
│ │ │ │ ├── public.api.module.ts
│ │ │ │ └── routes/
│ │ │ │ └── v1/
│ │ │ │ └── public.integrations.controller.ts
│ │ │ └── services/
│ │ │ └── auth/
│ │ │ ├── auth.middleware.ts
│ │ │ ├── auth.service.ts
│ │ │ ├── permissions/
│ │ │ │ ├── permission.exception.class.ts
│ │ │ │ ├── permissions.ability.ts
│ │ │ │ ├── permissions.guard.ts
│ │ │ │ ├── permissions.service.ts
│ │ │ │ └── subscription.exception.ts
│ │ │ ├── providers/
│ │ │ │ ├── farcaster.provider.ts
│ │ │ │ ├── github.provider.ts
│ │ │ │ ├── google.provider.ts
│ │ │ │ ├── oauth.provider.ts
│ │ │ │ ├── providers.manager.ts
│ │ │ │ └── wallet.provider.ts
│ │ │ ├── providers.interface.ts
│ │ │ └── public.auth.middleware.ts
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ ├── cli/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── CHANGELOG.md
│ │ ├── FEATURES.md
│ │ ├── HOW_TO_RUN.md
│ │ ├── INTEGRATION_SETTINGS_DISCOVERY.md
│ │ ├── INTEGRATION_TOOLS_WORKFLOW.md
│ │ ├── PROJECT_STRUCTURE.md
│ │ ├── PROVIDER_SETTINGS.md
│ │ ├── PROVIDER_SETTINGS_SUMMARY.md
│ │ ├── PUBLISHING.md
│ │ ├── QUICK_START.md
│ │ ├── README.md
│ │ ├── SKILL.md
│ │ ├── SUMMARY.md
│ │ ├── SUPPORTED_FILE_TYPES.md
│ │ ├── SYNTAX_UPGRADE.md
│ │ ├── examples/
│ │ │ ├── COMMAND_LINE_GUIDE.md
│ │ │ ├── EXAMPLES.md
│ │ │ ├── ai-agent-example.js
│ │ │ ├── basic-usage.sh
│ │ │ ├── command-line-examples.sh
│ │ │ ├── multi-platform-post.json
│ │ │ ├── multi-platform-with-settings.json
│ │ │ ├── post-with-comments.json
│ │ │ ├── reddit-post.json
│ │ │ ├── thread-post.json
│ │ │ ├── tiktok-video.json
│ │ │ └── youtube-video.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── api.ts
│ │ │ ├── commands/
│ │ │ │ ├── integrations.ts
│ │ │ │ ├── posts.ts
│ │ │ │ └── upload.ts
│ │ │ ├── config.ts
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsup.config.ts
│ ├── commands/
│ │ ├── .gitignore
│ │ ├── nest-cli.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── command.module.ts
│ │ │ ├── main.ts
│ │ │ └── tasks/
│ │ │ ├── agent.run.ts
│ │ │ ├── configuration.ts
│ │ │ └── refresh.tokens.ts
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ ├── extension/
│ │ ├── .gitignore
│ │ ├── custom-vite-plugins.ts
│ │ ├── manifest.dev.json
│ │ ├── manifest.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── background.ts
│ │ │ ├── providers/
│ │ │ │ ├── cookie-provider.interface.ts
│ │ │ │ ├── list/
│ │ │ │ │ └── skool.provider.ts
│ │ │ │ └── provider.registry.ts
│ │ │ └── types/
│ │ │ └── messages.ts
│ │ ├── tsconfig.json
│ │ ├── vite.config.base.ts
│ │ ├── vite.config.chrome.ts
│ │ └── vite.config.ts
│ ├── frontend/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── postcss.config.mjs
│ │ ├── public/
│ │ │ ├── .gitkeep
│ │ │ └── f.js
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── (app)/
│ │ │ │ │ ├── (preview)/
│ │ │ │ │ │ └── p/
│ │ │ │ │ │ └── [id]/
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── (site)/
│ │ │ │ │ │ ├── agents/
│ │ │ │ │ │ │ ├── [id]/
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── analytics/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── billing/
│ │ │ │ │ │ │ ├── lifetime/
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── err/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── launches/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── media/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── plugs/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── settings/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── third-party/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── api/
│ │ │ │ │ │ └── uploads/
│ │ │ │ │ │ └── [[...path]]/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── auth/
│ │ │ │ │ │ ├── activate/
│ │ │ │ │ │ │ ├── [code]/
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── forgot/
│ │ │ │ │ │ │ ├── [token]/
│ │ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── layout.tsx
│ │ │ │ │ │ ├── login/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── login-required/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── return.url.component.tsx
│ │ │ │ │ ├── integrations/
│ │ │ │ │ │ └── social/
│ │ │ │ │ │ ├── [provider]/
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── layout.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── oauth/
│ │ │ │ │ └── authorize/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── (extension)/
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── modal/
│ │ │ │ │ ├── [style]/
│ │ │ │ │ │ └── [platform]/
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── layout.tsx
│ │ │ │ ├── colors.scss
│ │ │ │ ├── global-error.tsx
│ │ │ │ ├── global.scss
│ │ │ │ └── polonto.css
│ │ │ ├── chrome.d.ts
│ │ │ ├── components/
│ │ │ │ ├── agents/
│ │ │ │ │ ├── agent.chat.tsx
│ │ │ │ │ ├── agent.input.tsx
│ │ │ │ │ ├── agent.textarea.tsx
│ │ │ │ │ └── agent.tsx
│ │ │ │ ├── analytics/
│ │ │ │ │ ├── analytics.component.tsx
│ │ │ │ │ ├── chart-social.tsx
│ │ │ │ │ ├── chart.tsx
│ │ │ │ │ ├── stars.and.forks.interface.ts
│ │ │ │ │ ├── stars.and.forks.tsx
│ │ │ │ │ └── stars.table.component.tsx
│ │ │ │ ├── approved-apps/
│ │ │ │ │ └── approved-apps.component.tsx
│ │ │ │ ├── auth/
│ │ │ │ │ ├── activate.tsx
│ │ │ │ │ ├── after.activate.tsx
│ │ │ │ │ ├── forgot-return.tsx
│ │ │ │ │ ├── forgot.tsx
│ │ │ │ │ ├── login.tsx
│ │ │ │ │ ├── login.with.oidc.tsx
│ │ │ │ │ ├── nayner.auth.button.tsx
│ │ │ │ │ ├── providers/
│ │ │ │ │ │ ├── farcaster.provider.tsx
│ │ │ │ │ │ ├── github.provider.tsx
│ │ │ │ │ │ ├── google.provider.tsx
│ │ │ │ │ │ ├── oauth.provider.tsx
│ │ │ │ │ │ ├── placeholder/
│ │ │ │ │ │ │ └── wallet.ui.provider.tsx
│ │ │ │ │ │ └── wallet.provider.tsx
│ │ │ │ │ ├── register.tsx
│ │ │ │ │ ├── testimonial.component.tsx
│ │ │ │ │ └── testimonial.tsx
│ │ │ │ ├── autopost/
│ │ │ │ │ └── autopost.tsx
│ │ │ │ ├── billing/
│ │ │ │ │ ├── billing.component.tsx
│ │ │ │ │ ├── embedded.billing.tsx
│ │ │ │ │ ├── faq.component.tsx
│ │ │ │ │ ├── finish.trial.tsx
│ │ │ │ │ ├── first.billing.component.tsx
│ │ │ │ │ ├── lifetime.deal.tsx
│ │ │ │ │ ├── main.billing.component.tsx
│ │ │ │ │ └── purchase.crypto.tsx
│ │ │ │ ├── developer/
│ │ │ │ │ └── developer.component.tsx
│ │ │ │ ├── launches/
│ │ │ │ │ ├── add.provider.component.tsx
│ │ │ │ │ ├── ai.image.tsx
│ │ │ │ │ ├── ai.video.tsx
│ │ │ │ │ ├── bot.picture.tsx
│ │ │ │ │ ├── calendar.context.tsx
│ │ │ │ │ ├── calendar.tsx
│ │ │ │ │ ├── comments/
│ │ │ │ │ │ └── comment.component.tsx
│ │ │ │ │ ├── continue.integration.tsx
│ │ │ │ │ ├── customer.modal.tsx
│ │ │ │ │ ├── filters.tsx
│ │ │ │ │ ├── general.preview.component.tsx
│ │ │ │ │ ├── generator/
│ │ │ │ │ │ └── generator.tsx
│ │ │ │ │ ├── helpers/
│ │ │ │ │ │ ├── date.picker.tsx
│ │ │ │ │ │ ├── dnd.provider.tsx
│ │ │ │ │ │ ├── isuscitizen.utils.tsx
│ │ │ │ │ │ ├── linkedin.component.tsx
│ │ │ │ │ │ ├── media.settings.component.tsx
│ │ │ │ │ │ ├── pick.platform.component.tsx
│ │ │ │ │ │ ├── top.title.component.tsx
│ │ │ │ │ │ ├── use.custom.provider.function.ts
│ │ │ │ │ │ ├── use.existing.data.tsx
│ │ │ │ │ │ ├── use.expend.tsx
│ │ │ │ │ │ ├── use.formatting.ts
│ │ │ │ │ │ ├── use.hide.top.editor.tsx
│ │ │ │ │ │ ├── use.integration.list.tsx
│ │ │ │ │ │ ├── use.integration.ts
│ │ │ │ │ │ ├── use.move.to.integration.tsx
│ │ │ │ │ │ └── use.values.ts
│ │ │ │ │ ├── information.component.tsx
│ │ │ │ │ ├── integration.redirect.component.tsx
│ │ │ │ │ ├── internal.channels.tsx
│ │ │ │ │ ├── launches.component.tsx
│ │ │ │ │ ├── layout.standalone.tsx
│ │ │ │ │ ├── menu/
│ │ │ │ │ │ └── menu.tsx
│ │ │ │ │ ├── merge.post.tsx
│ │ │ │ │ ├── missing-release.modal.tsx
│ │ │ │ │ ├── new.post.tsx
│ │ │ │ │ ├── polonto/
│ │ │ │ │ │ └── polonto.picture.generation.tsx
│ │ │ │ │ ├── polonto.tsx
│ │ │ │ │ ├── repeat.component.tsx
│ │ │ │ │ ├── select.customer.tsx
│ │ │ │ │ ├── separate.post.tsx
│ │ │ │ │ ├── settings.modal.tsx
│ │ │ │ │ ├── statistics.tsx
│ │ │ │ │ ├── tags.component.tsx
│ │ │ │ │ ├── time.table.tsx
│ │ │ │ │ ├── up.down.arrow.tsx
│ │ │ │ │ └── web3/
│ │ │ │ │ ├── providers/
│ │ │ │ │ │ ├── moltbook.provider.tsx
│ │ │ │ │ │ ├── telegram.provider.tsx
│ │ │ │ │ │ └── wrapcaster.provider.tsx
│ │ │ │ │ ├── web3.list.tsx
│ │ │ │ │ └── web3.provider.interface.ts
│ │ │ │ ├── layout/
│ │ │ │ │ ├── check.payment.tsx
│ │ │ │ │ ├── chrome.extension.component.tsx
│ │ │ │ │ ├── click.outside.tsx
│ │ │ │ │ ├── continue.provider.tsx
│ │ │ │ │ ├── drop.files.tsx
│ │ │ │ │ ├── dubAnalytics.tsx
│ │ │ │ │ ├── facebook.component.tsx
│ │ │ │ │ ├── html.component.tsx
│ │ │ │ │ ├── impersonate.tsx
│ │ │ │ │ ├── language.component.tsx
│ │ │ │ │ ├── layout.context.tsx
│ │ │ │ │ ├── loading.tsx
│ │ │ │ │ ├── logout.component.tsx
│ │ │ │ │ ├── mode.component.tsx
│ │ │ │ │ ├── new-modal.tsx
│ │ │ │ │ ├── new.subscription.tsx
│ │ │ │ │ ├── organization.selector.tsx
│ │ │ │ │ ├── pre-condition.component.tsx
│ │ │ │ │ ├── redirect.tsx
│ │ │ │ │ ├── sentry.component.tsx
│ │ │ │ │ ├── set.timezone.tsx
│ │ │ │ │ ├── settings.component.tsx
│ │ │ │ │ ├── streak.component.tsx
│ │ │ │ │ ├── support.tsx
│ │ │ │ │ ├── title.tsx
│ │ │ │ │ ├── top.menu.tsx
│ │ │ │ │ ├── top.tip.tsx
│ │ │ │ │ └── user.context.tsx
│ │ │ │ ├── media/
│ │ │ │ │ ├── media.component.tsx
│ │ │ │ │ └── new.uploader.tsx
│ │ │ │ ├── new-launch/
│ │ │ │ │ ├── a.component.tsx
│ │ │ │ │ ├── add.edit.modal.tsx
│ │ │ │ │ ├── add.post.button.tsx
│ │ │ │ │ ├── bold.text.tsx
│ │ │ │ │ ├── bullets.component.tsx
│ │ │ │ │ ├── delay.component.tsx
│ │ │ │ │ ├── dummy.code.component.tsx
│ │ │ │ │ ├── editor.tsx
│ │ │ │ │ ├── finisher/
│ │ │ │ │ │ └── thread.finisher.tsx
│ │ │ │ │ ├── heading.component.tsx
│ │ │ │ │ ├── manage.modal.tsx
│ │ │ │ │ ├── mention.component.tsx
│ │ │ │ │ ├── modal.wrapper.component.tsx
│ │ │ │ │ ├── picks.socials.component.tsx
│ │ │ │ │ ├── providers/
│ │ │ │ │ │ ├── bluesky/
│ │ │ │ │ │ │ └── bluesky.provider.tsx
│ │ │ │ │ │ ├── continue-provider/
│ │ │ │ │ │ │ ├── facebook/
│ │ │ │ │ │ │ │ └── facebook.continue.tsx
│ │ │ │ │ │ │ ├── gmb/
│ │ │ │ │ │ │ │ └── gmb.continue.tsx
│ │ │ │ │ │ │ ├── instagram/
│ │ │ │ │ │ │ │ └── instagram.continue.tsx
│ │ │ │ │ │ │ ├── linkedin/
│ │ │ │ │ │ │ │ └── linkedin.continue.tsx
│ │ │ │ │ │ │ ├── list.tsx
│ │ │ │ │ │ │ ├── with-continue-provider.tsx
│ │ │ │ │ │ │ └── youtube/
│ │ │ │ │ │ │ └── youtube.continue.tsx
│ │ │ │ │ │ ├── devto/
│ │ │ │ │ │ │ ├── devto.provider.tsx
│ │ │ │ │ │ │ ├── devto.tags.tsx
│ │ │ │ │ │ │ └── select.organization.tsx
│ │ │ │ │ │ ├── discord/
│ │ │ │ │ │ │ ├── discord.channel.select.tsx
│ │ │ │ │ │ │ └── discord.provider.tsx
│ │ │ │ │ │ ├── dribbble/
│ │ │ │ │ │ │ ├── dribbble.provider.tsx
│ │ │ │ │ │ │ └── dribbble.teams.tsx
│ │ │ │ │ │ ├── facebook/
│ │ │ │ │ │ │ ├── facebook.preview.tsx
│ │ │ │ │ │ │ └── facebook.provider.tsx
│ │ │ │ │ │ ├── gmb/
│ │ │ │ │ │ │ └── gmb.provider.tsx
│ │ │ │ │ │ ├── hashnode/
│ │ │ │ │ │ │ ├── hashnode.provider.tsx
│ │ │ │ │ │ │ ├── hashnode.publications.tsx
│ │ │ │ │ │ │ └── hashnode.tags.tsx
│ │ │ │ │ │ ├── high.order.provider.tsx
│ │ │ │ │ │ ├── instagram/
│ │ │ │ │ │ │ ├── instagram.collaborators.tsx
│ │ │ │ │ │ │ ├── instagram.preview.tsx
│ │ │ │ │ │ │ └── instagram.tags.tsx
│ │ │ │ │ │ ├── kick/
│ │ │ │ │ │ │ └── kick.provider.tsx
│ │ │ │ │ │ ├── lemmy/
│ │ │ │ │ │ │ ├── lemmy.provider.tsx
│ │ │ │ │ │ │ └── subreddit.tsx
│ │ │ │ │ │ ├── linkedin/
│ │ │ │ │ │ │ ├── linkedin.preview.tsx
│ │ │ │ │ │ │ └── linkedin.provider.tsx
│ │ │ │ │ │ ├── listmonk/
│ │ │ │ │ │ │ ├── listmonk.provider.tsx
│ │ │ │ │ │ │ ├── select.list.tsx
│ │ │ │ │ │ │ └── select.templates.tsx
│ │ │ │ │ │ ├── mastodon/
│ │ │ │ │ │ │ └── mastodon.provider.tsx
│ │ │ │ │ │ ├── medium/
│ │ │ │ │ │ │ ├── fonts/
│ │ │ │ │ │ │ │ └── stylesheet.css
│ │ │ │ │ │ │ ├── medium.provider.tsx
│ │ │ │ │ │ │ ├── medium.publications.tsx
│ │ │ │ │ │ │ └── medium.tags.tsx
│ │ │ │ │ │ ├── mewe/
│ │ │ │ │ │ │ ├── mewe.group.select.tsx
│ │ │ │ │ │ │ └── mewe.provider.tsx
│ │ │ │ │ │ ├── moltbook/
│ │ │ │ │ │ │ └── moltbook.provider.tsx
│ │ │ │ │ │ ├── nostr/
│ │ │ │ │ │ │ └── nostr.provider.tsx
│ │ │ │ │ │ ├── pinterest/
│ │ │ │ │ │ │ ├── pinterest.board.tsx
│ │ │ │ │ │ │ ├── pinterest.preview.tsx
│ │ │ │ │ │ │ └── pinterest.provider.tsx
│ │ │ │ │ │ ├── reddit/
│ │ │ │ │ │ │ ├── reddit.provider.tsx
│ │ │ │ │ │ │ └── subreddit.tsx
│ │ │ │ │ │ ├── show.all.providers.tsx
│ │ │ │ │ │ ├── skool/
│ │ │ │ │ │ │ ├── skool.group.select.tsx
│ │ │ │ │ │ │ ├── skool.label.select.tsx
│ │ │ │ │ │ │ └── skool.provider.tsx
│ │ │ │ │ │ ├── slack/
│ │ │ │ │ │ │ ├── slack.channel.select.tsx
│ │ │ │ │ │ │ └── slack.provider.tsx
│ │ │ │ │ │ ├── telegram/
│ │ │ │ │ │ │ └── telegram.provider.tsx
│ │ │ │ │ │ ├── threads/
│ │ │ │ │ │ │ └── threads.provider.tsx
│ │ │ │ │ │ ├── tiktok/
│ │ │ │ │ │ │ ├── tiktok.preview.tsx
│ │ │ │ │ │ │ └── tiktok.provider.tsx
│ │ │ │ │ │ ├── twitch/
│ │ │ │ │ │ │ └── twitch.provider.tsx
│ │ │ │ │ │ ├── vk/
│ │ │ │ │ │ │ └── vk.provider.tsx
│ │ │ │ │ │ ├── warpcast/
│ │ │ │ │ │ │ ├── subreddit.tsx
│ │ │ │ │ │ │ └── warpcast.provider.tsx
│ │ │ │ │ │ ├── whop/
│ │ │ │ │ │ │ ├── whop.company.select.tsx
│ │ │ │ │ │ │ ├── whop.experience.select.tsx
│ │ │ │ │ │ │ └── whop.provider.tsx
│ │ │ │ │ │ ├── wordpress/
│ │ │ │ │ │ │ ├── wordpress.post.type.tsx
│ │ │ │ │ │ │ └── wordpress.provider.tsx
│ │ │ │ │ │ ├── x/
│ │ │ │ │ │ │ └── x.provider.tsx
│ │ │ │ │ │ └── youtube/
│ │ │ │ │ │ ├── youtube.preview.tsx
│ │ │ │ │ │ └── youtube.provider.tsx
│ │ │ │ │ ├── select.current.tsx
│ │ │ │ │ ├── store.ts
│ │ │ │ │ └── u.text.tsx
│ │ │ │ ├── new-layout/
│ │ │ │ │ ├── billing.after.tsx
│ │ │ │ │ ├── layout.component.tsx
│ │ │ │ │ ├── layout.media.component.tsx
│ │ │ │ │ ├── logo.tsx
│ │ │ │ │ ├── menu-item.tsx
│ │ │ │ │ └── sentry.feedback.component.tsx
│ │ │ │ ├── notifications/
│ │ │ │ │ └── notification.component.tsx
│ │ │ │ ├── onboarding/
│ │ │ │ │ ├── github.onboarding.tsx
│ │ │ │ │ ├── onboarding.modal.tsx
│ │ │ │ │ └── onboarding.tsx
│ │ │ │ ├── platform-analytics/
│ │ │ │ │ ├── platform.analytics.tsx
│ │ │ │ │ └── render.analytics.tsx
│ │ │ │ ├── plugs/
│ │ │ │ │ ├── plug.tsx
│ │ │ │ │ ├── plugs.context.ts
│ │ │ │ │ └── plugs.tsx
│ │ │ │ ├── post-url-selector/
│ │ │ │ │ └── post.url.selector.tsx
│ │ │ │ ├── preview/
│ │ │ │ │ ├── comments.components.tsx
│ │ │ │ │ ├── copy.client.tsx
│ │ │ │ │ ├── preview.wrapper.tsx
│ │ │ │ │ └── render.preview.date.tsx
│ │ │ │ ├── public-api/
│ │ │ │ │ └── public.component.tsx
│ │ │ │ ├── sets/
│ │ │ │ │ └── sets.tsx
│ │ │ │ ├── settings/
│ │ │ │ │ ├── email-notifications.component.tsx
│ │ │ │ │ ├── github.component.tsx
│ │ │ │ │ ├── global.settings.tsx
│ │ │ │ │ ├── metric.component.tsx
│ │ │ │ │ ├── shortlink-preference.component.tsx
│ │ │ │ │ ├── signatures.component.tsx
│ │ │ │ │ └── teams.component.tsx
│ │ │ │ ├── signature.tsx
│ │ │ │ ├── standalone-modal/
│ │ │ │ │ └── standalone.modal.tsx
│ │ │ │ ├── third-parties/
│ │ │ │ │ ├── providers/
│ │ │ │ │ │ └── heygen.provider.tsx
│ │ │ │ │ ├── slider.component.tsx
│ │ │ │ │ ├── third-party.component.tsx
│ │ │ │ │ ├── third-party.function.tsx
│ │ │ │ │ ├── third-party.list.component.tsx
│ │ │ │ │ ├── third-party.media.tsx
│ │ │ │ │ └── third-party.wrapper.tsx
│ │ │ │ ├── ui/
│ │ │ │ │ ├── check.icon.component.tsx
│ │ │ │ │ ├── icons/
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── is.scroll.hook.tsx
│ │ │ │ │ ├── logo-text.component.tsx
│ │ │ │ │ └── translated-label.tsx
│ │ │ │ ├── videos/
│ │ │ │ │ ├── providers/
│ │ │ │ │ │ ├── image-text-slides.provider.tsx
│ │ │ │ │ │ └── veo3.provider.tsx
│ │ │ │ │ ├── video.context.wrapper.tsx
│ │ │ │ │ ├── video.render.component.tsx
│ │ │ │ │ └── video.wrapper.tsx
│ │ │ │ └── webhooks/
│ │ │ │ └── webhooks.tsx
│ │ │ ├── instrumentation.ts
│ │ │ ├── middleware.ts
│ │ │ ├── sentry.edge.config.ts
│ │ │ └── sentry.server.config.ts
│ │ ├── tailwind.config.js
│ │ └── tsconfig.json
│ ├── orchestrator/
│ │ ├── .gitignore
│ │ ├── .swcrc
│ │ ├── nest-cli.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── activities/
│ │ │ │ ├── autopost.activity.ts
│ │ │ │ ├── email.activity.ts
│ │ │ │ ├── integrations.activity.ts
│ │ │ │ └── post.activity.ts
│ │ │ ├── app.module.ts
│ │ │ ├── main.ts
│ │ │ ├── signals/
│ │ │ │ ├── email.signal.ts
│ │ │ │ └── send.email.signal.ts
│ │ │ └── workflows/
│ │ │ ├── autopost.workflow.ts
│ │ │ ├── digest.email.workflow.ts
│ │ │ ├── index.ts
│ │ │ ├── missing.post.workflow.ts
│ │ │ ├── post-workflows/
│ │ │ │ └── post.workflow.v1.0.1.ts
│ │ │ ├── refresh.token.workflow.ts
│ │ │ ├── send.email.workflow.ts
│ │ │ └── streak.workflow.ts
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ └── sdk/
│ ├── .babelrc
│ ├── .npmignore
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ └── index.ts
│ ├── tsconfig.json
│ └── tsup.config.ts
├── docker-compose.dev.yaml
├── docker-compose.yaml
├── dynamicconfig/
│ ├── development-cass.yaml
│ └── development-sql.yaml
├── eslint.config.mjs
├── i18n.json
├── jest.config.ts
├── jest.preset.js
├── libraries/
│ ├── helpers/
│ │ └── src/
│ │ ├── auth/
│ │ │ └── auth.service.ts
│ │ ├── configuration/
│ │ │ └── configuration.checker.ts
│ │ ├── decorators/
│ │ │ ├── plug.decorator.ts
│ │ │ └── post.plug.ts
│ │ ├── subdomain/
│ │ │ ├── all.two.level.subdomain.ts
│ │ │ └── subdomain.management.ts
│ │ ├── swagger/
│ │ │ └── load.swagger.ts
│ │ └── utils/
│ │ ├── count.length.ts
│ │ ├── custom.fetch.func.ts
│ │ ├── custom.fetch.tsx
│ │ ├── internal.fetch.ts
│ │ ├── is.dev.ts
│ │ ├── is.general.server.side.ts
│ │ ├── linkedin.company.prevent.remove.ts
│ │ ├── posts.list.minify.ts
│ │ ├── read.or.fetch.ts
│ │ ├── remove.markdown.ts
│ │ ├── strip.html.validation.ts
│ │ ├── timer.ts
│ │ ├── use.fire.events.ts
│ │ ├── use.wait.for.class.tsx
│ │ ├── utm.saver.tsx
│ │ ├── valid.images.ts
│ │ └── valid.url.path.ts
│ ├── nestjs-libraries/
│ │ ├── .eslintrc.json
│ │ ├── README.md
│ │ ├── src/
│ │ │ ├── 3rdparties/
│ │ │ │ ├── heygen/
│ │ │ │ │ └── heygen.provider.ts
│ │ │ │ ├── thirdparty.interface.ts
│ │ │ │ ├── thirdparty.manager.ts
│ │ │ │ └── thirdparty.module.ts
│ │ │ ├── agent/
│ │ │ │ ├── agent.categories.ts
│ │ │ │ ├── agent.graph.insert.service.ts
│ │ │ │ ├── agent.graph.service.ts
│ │ │ │ ├── agent.module.ts
│ │ │ │ └── agent.topics.ts
│ │ │ ├── chat/
│ │ │ │ ├── agent.tool.interface.ts
│ │ │ │ ├── async.storage.ts
│ │ │ │ ├── auth.context.ts
│ │ │ │ ├── chat.module.ts
│ │ │ │ ├── load.tools.service.ts
│ │ │ │ ├── mastra.service.ts
│ │ │ │ ├── mastra.store.ts
│ │ │ │ ├── rules.description.decorator.ts
│ │ │ │ ├── start.mcp.ts
│ │ │ │ ├── tools/
│ │ │ │ │ ├── generate.image.tool.ts
│ │ │ │ │ ├── generate.video.options.tool.ts
│ │ │ │ │ ├── generate.video.tool.ts
│ │ │ │ │ ├── integration.list.tool.ts
│ │ │ │ │ ├── integration.schedule.post.ts
│ │ │ │ │ ├── integration.trigger.tool.ts
│ │ │ │ │ ├── integration.validation.tool.ts
│ │ │ │ │ ├── tool.list.ts
│ │ │ │ │ └── video.function.tool.ts
│ │ │ │ └── validation.schemas.helper.ts
│ │ │ ├── crypto/
│ │ │ │ └── nowpayments.ts
│ │ │ ├── database/
│ │ │ │ └── prisma/
│ │ │ │ ├── agencies/
│ │ │ │ │ ├── agencies.repository.ts
│ │ │ │ │ └── agencies.service.ts
│ │ │ │ ├── autopost/
│ │ │ │ │ ├── autopost.repository.ts
│ │ │ │ │ └── autopost.service.ts
│ │ │ │ ├── database.module.ts
│ │ │ │ ├── integrations/
│ │ │ │ │ ├── integration.repository.ts
│ │ │ │ │ └── integration.service.ts
│ │ │ │ ├── media/
│ │ │ │ │ ├── media.repository.ts
│ │ │ │ │ └── media.service.ts
│ │ │ │ ├── notifications/
│ │ │ │ │ ├── notification.service.ts
│ │ │ │ │ └── notifications.repository.ts
│ │ │ │ ├── oauth/
│ │ │ │ │ ├── oauth.repository.ts
│ │ │ │ │ └── oauth.service.ts
│ │ │ │ ├── organizations/
│ │ │ │ │ ├── organization.repository.ts
│ │ │ │ │ └── organization.service.ts
│ │ │ │ ├── posts/
│ │ │ │ │ ├── posts.repository.ts
│ │ │ │ │ └── posts.service.ts
│ │ │ │ ├── prisma.service.ts
│ │ │ │ ├── schema.prisma
│ │ │ │ ├── sets/
│ │ │ │ │ ├── sets.repository.ts
│ │ │ │ │ └── sets.service.ts
│ │ │ │ ├── signatures/
│ │ │ │ │ ├── signature.repository.ts
│ │ │ │ │ └── signature.service.ts
│ │ │ │ ├── subscriptions/
│ │ │ │ │ ├── pricing.ts
│ │ │ │ │ ├── subscription.repository.ts
│ │ │ │ │ └── subscription.service.ts
│ │ │ │ ├── third-party/
│ │ │ │ │ ├── third-party.repository.ts
│ │ │ │ │ └── third-party.service.ts
│ │ │ │ ├── users/
│ │ │ │ │ ├── users.repository.ts
│ │ │ │ │ └── users.service.ts
│ │ │ │ └── webhooks/
│ │ │ │ ├── webhooks.repository.ts
│ │ │ │ └── webhooks.service.ts
│ │ │ ├── dtos/
│ │ │ │ ├── agencies/
│ │ │ │ │ └── create.agency.dto.ts
│ │ │ │ ├── analytics/
│ │ │ │ │ └── stars.list.dto.ts
│ │ │ │ ├── auth/
│ │ │ │ │ ├── create.org.user.dto.ts
│ │ │ │ │ ├── forgot-return.password.dto.ts
│ │ │ │ │ ├── forgot.password.dto.ts
│ │ │ │ │ ├── login.user.dto.ts
│ │ │ │ │ └── resend-activation.dto.ts
│ │ │ │ ├── autopost/
│ │ │ │ │ └── autopost.dto.ts
│ │ │ │ ├── billing/
│ │ │ │ │ └── billing.subscribe.dto.ts
│ │ │ │ ├── comments/
│ │ │ │ │ └── add.comment.dto.ts
│ │ │ │ ├── generator/
│ │ │ │ │ ├── create.generated.posts.dto.ts
│ │ │ │ │ └── generator.dto.ts
│ │ │ │ ├── integrations/
│ │ │ │ │ ├── api.key.dto.ts
│ │ │ │ │ ├── connect.integration.dto.ts
│ │ │ │ │ ├── integration.function.dto.ts
│ │ │ │ │ └── integration.time.dto.ts
│ │ │ │ ├── media/
│ │ │ │ │ ├── media.dto.ts
│ │ │ │ │ ├── save.media.information.dto.ts
│ │ │ │ │ └── upload.dto.ts
│ │ │ │ ├── notifications/
│ │ │ │ │ └── get.notifications.dto.ts
│ │ │ │ ├── oauth/
│ │ │ │ │ ├── authorize-oauth.dto.ts
│ │ │ │ │ ├── create-oauth-app.dto.ts
│ │ │ │ │ ├── token-exchange.dto.ts
│ │ │ │ │ └── update-oauth-app.dto.ts
│ │ │ │ ├── plugs/
│ │ │ │ │ └── plug.dto.ts
│ │ │ │ ├── posts/
│ │ │ │ │ ├── create.post.dto.ts
│ │ │ │ │ ├── create.tag.dto.ts
│ │ │ │ │ ├── get.posts.dto.ts
│ │ │ │ │ ├── get.posts.list.dto.ts
│ │ │ │ │ ├── providers-settings/
│ │ │ │ │ │ ├── all.providers.settings.ts
│ │ │ │ │ │ ├── dev.to.settings.dto.ts
│ │ │ │ │ │ ├── dev.to.tags.settings.dto.ts
│ │ │ │ │ │ ├── discord.dto.ts
│ │ │ │ │ │ ├── dribbble.dto.ts
│ │ │ │ │ │ ├── facebook.dto.ts
│ │ │ │ │ │ ├── farcaster.dto.ts
│ │ │ │ │ │ ├── gmb.settings.dto.ts
│ │ │ │ │ │ ├── hashnode.settings.dto.ts
│ │ │ │ │ │ ├── instagram.dto.ts
│ │ │ │ │ │ ├── kick.dto.ts
│ │ │ │ │ │ ├── lemmy.dto.ts
│ │ │ │ │ │ ├── linkedin.dto.ts
│ │ │ │ │ │ ├── listmonk.dto.ts
│ │ │ │ │ │ ├── medium.settings.dto.ts
│ │ │ │ │ │ ├── mewe.dto.ts
│ │ │ │ │ │ ├── moltbook.dto.ts
│ │ │ │ │ │ ├── pinterest.dto.ts
│ │ │ │ │ │ ├── reddit.dto.ts
│ │ │ │ │ │ ├── skool.dto.ts
│ │ │ │ │ │ ├── slack.dto.ts
│ │ │ │ │ │ ├── tiktok.dto.ts
│ │ │ │ │ │ ├── twitch.dto.ts
│ │ │ │ │ │ ├── whop.dto.ts
│ │ │ │ │ │ ├── wordpress.dto.ts
│ │ │ │ │ │ ├── x.dto.ts
│ │ │ │ │ │ └── youtube.settings.dto.ts
│ │ │ │ │ └── transformers/
│ │ │ │ │ └── integration.settings.transformer.ts
│ │ │ │ ├── sets/
│ │ │ │ │ └── sets.dto.ts
│ │ │ │ ├── settings/
│ │ │ │ │ ├── add.team.member.dto.ts
│ │ │ │ │ └── shortlink-preference.dto.ts
│ │ │ │ ├── signature/
│ │ │ │ │ └── signature.dto.ts
│ │ │ │ ├── users/
│ │ │ │ │ ├── email-notifications.dto.ts
│ │ │ │ │ └── user.details.dto.ts
│ │ │ │ ├── videos/
│ │ │ │ │ ├── video.dto.ts
│ │ │ │ │ └── video.function.dto.ts
│ │ │ │ └── webhooks/
│ │ │ │ └── webhooks.dto.ts
│ │ │ ├── emails/
│ │ │ │ ├── email.interface.ts
│ │ │ │ ├── empty.provider.ts
│ │ │ │ ├── node.mailer.provider.ts
│ │ │ │ └── resend.provider.ts
│ │ │ ├── integrations/
│ │ │ │ ├── integration.manager.ts
│ │ │ │ ├── integration.missing.scopes.ts
│ │ │ │ ├── refresh.integration.service.ts
│ │ │ │ ├── social/
│ │ │ │ │ ├── bluesky.provider.ts
│ │ │ │ │ ├── dev.to.provider.ts
│ │ │ │ │ ├── discord.provider.ts
│ │ │ │ │ ├── dribbble.provider.ts
│ │ │ │ │ ├── facebook.provider.ts
│ │ │ │ │ ├── farcaster.provider.ts
│ │ │ │ │ ├── gmb.provider.ts
│ │ │ │ │ ├── hashnode.provider.ts
│ │ │ │ │ ├── hashnode.tags.ts
│ │ │ │ │ ├── instagram.provider.ts
│ │ │ │ │ ├── instagram.standalone.provider.ts
│ │ │ │ │ ├── kick.provider.ts
│ │ │ │ │ ├── lemmy.provider.ts
│ │ │ │ │ ├── linkedin.page.provider.ts
│ │ │ │ │ ├── linkedin.provider.ts
│ │ │ │ │ ├── listmonk.provider.ts
│ │ │ │ │ ├── mastodon.custom.provider.ts
│ │ │ │ │ ├── mastodon.provider.ts
│ │ │ │ │ ├── medium.provider.ts
│ │ │ │ │ ├── mewe.provider.ts
│ │ │ │ │ ├── moltbook.provider.ts
│ │ │ │ │ ├── nostr.provider.ts
│ │ │ │ │ ├── pinterest.provider.ts
│ │ │ │ │ ├── reddit.provider.ts
│ │ │ │ │ ├── skool.provider.ts
│ │ │ │ │ ├── slack.provider.ts
│ │ │ │ │ ├── social.integrations.interface.ts
│ │ │ │ │ ├── telegram.provider.ts
│ │ │ │ │ ├── threads.provider.ts
│ │ │ │ │ ├── tiktok.provider.ts
│ │ │ │ │ ├── twitch.provider.ts
│ │ │ │ │ ├── vk.provider.ts
│ │ │ │ │ ├── whop.provider.ts
│ │ │ │ │ ├── wordpress.provider.ts
│ │ │ │ │ ├── x.provider.ts
│ │ │ │ │ └── youtube.provider.ts
│ │ │ │ ├── social.abstract.ts
│ │ │ │ └── tool.decorator.ts
│ │ │ ├── newsletter/
│ │ │ │ ├── newsletter.interface.ts
│ │ │ │ ├── newsletter.service.ts
│ │ │ │ ├── providers/
│ │ │ │ │ ├── beehiiv.provider.ts
│ │ │ │ │ ├── email-empty.provider.ts
│ │ │ │ │ └── listmonk.provider.ts
│ │ │ │ └── providers.ts
│ │ │ ├── openai/
│ │ │ │ ├── extract.content.service.ts
│ │ │ │ ├── fal.service.ts
│ │ │ │ └── openai.service.ts
│ │ │ ├── redis/
│ │ │ │ └── redis.service.ts
│ │ │ ├── sentry/
│ │ │ │ ├── initialize.sentry.ts
│ │ │ │ └── sentry.exception.ts
│ │ │ ├── services/
│ │ │ │ ├── codes.service.ts
│ │ │ │ ├── email.service.ts
│ │ │ │ ├── exception.filter.ts
│ │ │ │ ├── make.is.ts
│ │ │ │ ├── stripe.country.list.ts
│ │ │ │ └── stripe.service.ts
│ │ │ ├── short-linking/
│ │ │ │ ├── providers/
│ │ │ │ │ ├── dub.ts
│ │ │ │ │ ├── empty.ts
│ │ │ │ │ ├── kutt.ts
│ │ │ │ │ ├── linkdrip.ts
│ │ │ │ │ └── short.io.ts
│ │ │ │ ├── short-linking.interface.ts
│ │ │ │ └── short.link.service.ts
│ │ │ ├── temporal/
│ │ │ │ ├── infinite.workflow.register.ts
│ │ │ │ ├── temporal.module.ts
│ │ │ │ ├── temporal.register.ts
│ │ │ │ └── temporal.search.attribute.ts
│ │ │ ├── throttler/
│ │ │ │ └── throttler.provider.ts
│ │ │ ├── track/
│ │ │ │ └── track.service.ts
│ │ │ ├── upload/
│ │ │ │ ├── cloudflare.storage.ts
│ │ │ │ ├── custom.upload.validation.ts
│ │ │ │ ├── local.storage.ts
│ │ │ │ ├── r2.uploader.ts
│ │ │ │ ├── upload.factory.ts
│ │ │ │ ├── upload.interface.ts
│ │ │ │ └── upload.module.ts
│ │ │ ├── user/
│ │ │ │ ├── org.from.request.ts
│ │ │ │ ├── track.enum.ts
│ │ │ │ ├── user.agent.ts
│ │ │ │ └── user.from.request.ts
│ │ │ └── videos/
│ │ │ ├── images-slides/
│ │ │ │ └── images.slides.ts
│ │ │ ├── veo3/
│ │ │ │ └── veo3.ts
│ │ │ ├── video.interface.ts
│ │ │ ├── video.manager.ts
│ │ │ └── video.module.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.lib.json
│ └── react-shared-libraries/
│ ├── .eslintrc.json
│ ├── README.md
│ ├── src/
│ │ ├── form/
│ │ │ ├── button.tsx
│ │ │ ├── canonical.tsx
│ │ │ ├── checkbox.tsx
│ │ │ ├── color.picker.tsx
│ │ │ ├── custom.select.tsx
│ │ │ ├── input.tsx
│ │ │ ├── select.tsx
│ │ │ ├── slider.tsx
│ │ │ ├── textarea.tsx
│ │ │ └── total.tsx
│ │ ├── helpers/
│ │ │ ├── delete.dialog.tsx
│ │ │ ├── image.with.fallback.tsx
│ │ │ ├── is.general.tsx
│ │ │ ├── mantine.wrapper.tsx
│ │ │ ├── posthog.tsx
│ │ │ ├── testomonials.tsx
│ │ │ ├── uppy.upload.ts
│ │ │ ├── use.is.visible.tsx
│ │ │ ├── use.media.directory.ts
│ │ │ ├── use.prevent.window.unload.tsx
│ │ │ ├── use.state.callback.ts
│ │ │ ├── use.track.tsx
│ │ │ ├── utc.date.render.tsx
│ │ │ ├── variable.context.tsx
│ │ │ ├── video.frame.tsx
│ │ │ └── video.or.image.tsx
│ │ ├── sentry/
│ │ │ ├── initialize.sentry.client.ts
│ │ │ ├── initialize.sentry.next.basic.ts
│ │ │ └── initialize.sentry.server.ts
│ │ ├── toaster/
│ │ │ └── toaster.tsx
│ │ └── translation/
│ │ ├── get.transation.service.client.ts
│ │ ├── get.translation.service.backend.ts
│ │ ├── i18n.config.ts
│ │ ├── i18next.ts
│ │ ├── locales/
│ │ │ ├── ar/
│ │ │ │ └── translation.json
│ │ │ ├── bn/
│ │ │ │ └── translation.json
│ │ │ ├── de/
│ │ │ │ └── translation.json
│ │ │ ├── en/
│ │ │ │ └── translation.json
│ │ │ ├── es/
│ │ │ │ └── translation.json
│ │ │ ├── fr/
│ │ │ │ └── translation.json
│ │ │ ├── he/
│ │ │ │ └── translation.json
│ │ │ ├── it/
│ │ │ │ └── translation.json
│ │ │ ├── ja/
│ │ │ │ └── translation.json
│ │ │ ├── ka_ge/
│ │ │ │ └── translation.json
│ │ │ ├── ko/
│ │ │ │ └── translation.json
│ │ │ ├── pt/
│ │ │ │ └── translation.json
│ │ │ ├── ru/
│ │ │ │ └── translation.json
│ │ │ ├── tr/
│ │ │ │ └── translation.json
│ │ │ ├── vi/
│ │ │ │ └── translation.json
│ │ │ └── zh/
│ │ │ └── translation.json
│ │ └── translated-label.tsx
│ ├── tsconfig.json
│ └── tsconfig.lib.json
├── package.json
├── pnpm-workspace.yaml
├── railway.toml
├── reports/
│ └── junit.xml
├── sonar-project.properties
├── tsconfig.base.json
├── tsconfig.json
├── var/
│ └── docker/
│ ├── create-namespace-default.sh
│ ├── docker-build.sh
│ ├── docker-create.sh
│ └── nginx.conf
└── version.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .coderabbit.yaml
================================================
language: en-US
tone_instructions: ''
early_access: false
enable_free_tier: true
reviews:
profile: chill
request_changes_workflow: false
high_level_summary: true
high_level_summary_placeholder: '@coderabbitai summary'
high_level_summary_in_walkthrough: false
auto_title_placeholder: '@coderabbitai'
auto_title_instructions: ''
review_status: false
commit_status: true
fail_commit_status: false
collapse_walkthrough: false
changed_files_summary: true
sequence_diagrams: true
estimate_code_review_effort: true
assess_linked_issues: true
related_issues: true
related_prs: true
suggested_labels: true
auto_apply_labels: false
suggested_reviewers: true
auto_assign_reviewers: false
poem: true
labeling_instructions: []
path_filters: []
path_instructions: []
abort_on_close: true
disable_cache: false
auto_review:
enabled: false
auto_incremental_review: true
ignore_title_keywords: []
labels: []
drafts: false
base_branches: []
finishing_touches:
docstrings:
enabled: true
unit_tests:
enabled: true
pre_merge_checks:
docstrings:
mode: warning
threshold: 80
title:
mode: warning
requirements: ''
description:
mode: warning
issue_assessment:
mode: warning
tools:
ast-grep:
rule_dirs: []
util_dirs: []
essential_rules: true
packages: []
shellcheck:
enabled: true
ruff:
enabled: true
markdownlint:
enabled: true
github-checks:
enabled: true
timeout_ms: 90000
languagetool:
enabled: true
enabled_rules: []
disabled_rules: []
enabled_categories: []
disabled_categories: []
enabled_only: false
level: default
biome:
enabled: true
hadolint:
enabled: true
swiftlint:
enabled: true
phpstan:
enabled: true
level: default
phpmd:
enabled: true
phpcs:
enabled: true
golangci-lint:
enabled: true
yamllint:
enabled: true
gitleaks:
enabled: true
checkov:
enabled: true
detekt:
enabled: true
eslint:
enabled: true
flake8:
enabled: true
rubocop:
enabled: true
buf:
enabled: true
regal:
enabled: true
actionlint:
enabled: true
pmd:
enabled: true
cppcheck:
enabled: true
semgrep:
enabled: true
circleci:
enabled: true
clippy:
enabled: true
sqlfluff:
enabled: true
prismaLint:
enabled: true
pylint:
enabled: true
oxc:
enabled: true
shopifyThemeCheck:
enabled: true
luacheck:
enabled: true
brakeman:
enabled: true
dotenvLint:
enabled: true
htmlhint:
enabled: true
checkmake:
enabled: true
chat:
auto_reply: true
integrations:
jira:
usage: auto
linear:
usage: auto
knowledge_base:
opt_out: false
web_search:
enabled: true
code_guidelines:
enabled: true
filePatterns: []
learnings:
scope: auto
issues:
scope: auto
jira:
usage: auto
project_keys: []
linear:
usage: auto
team_keys: []
pull_requests:
scope: auto
code_generation:
docstrings:
language: en-US
path_instructions: []
unit_tests:
path_instructions: []
autopilot:
enabled: false
================================================
FILE: .devcontainer/devcontainer.json
================================================
{
"name": "Postiz Dev Container",
"image": "localhost/postiz-devcontainer",
"features": {},
"customizations": {
"vscode": {
"settings": {},
"extensions": []
}
},
"forwardPorts": ["4200:4200", "3000:3000"],
"mounts": ["source=/apps,destination=/apps/dist/,type=bind,consistency=cached"]
}
================================================
FILE: .dockerignore
================================================
# We want the docker builds to be clean, and as fast as possible. Don't send
# any half-built stuff in the build context as a pre-caution (also saves copying
# 180k files in node_modules that isn't used!).
**/node_modules
node_modules/*
node_modules
docker-data/*
dist
.nx
/apps/frontend/.next
/apps/backend/dist
/apps/workers/dist
/apps/cron/dist
/apps/commands/dist
.devcontainer
**/.git
**/*.md
**/LICENSE
**/npm-debug.log
**/*.vscode
.git
.github
reports
================================================
FILE: .eslintignore
================================================
node_modules
================================================
FILE: .github/Dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
================================================
FILE: .github/FUNDING.yaml
================================================
#patreon: Postiz
open_collective: postiz
# github: gitroomhq
================================================
FILE: .github/ISSUE_TEMPLATE/01_bug_report.yml
================================================
name: "🐛 Bug Report"
description: "Submit a bug report to help us improve,\nif you have a problem installing the app please join our https://discord.postiz.com instead for help."
title: "Give your bug report a good title "
labels: ["type: bug"]
body:
- type: markdown
attributes:
value: We value your time and effort to submit this bug report. 🙏
- type: textarea
id: description
validations:
required: true
attributes:
label: "📜 Description"
description: "A clear and concise description of what the bug is."
placeholder: "It bugs out when ..."
validations:
required: true
- type: textarea
id: steps-to-reproduce
validations:
required: true
attributes:
label: "👟 Reproduction steps"
description: "How do you trigger this bug? Please walk us through it step by step."
placeholder: "1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error"
- type: textarea
id: expected-behavior
validations:
required: true
attributes:
label: "👍 Expected behavior"
description: "What did you think should happen?"
placeholder: "It should ..."
- type: textarea
id: actual-behavior
validations:
required: true
attributes:
label: "👎 Actual Behavior with Screenshots"
description: "What did actually happen? Add screenshots, if applicable."
placeholder: "It actually ..."
- type: dropdown
id: operating-system
attributes:
label: "💻 Operating system"
description: "What OS is your app running on?"
options:
- Linux
- MacOS
- Windows
- Something else
validations:
required: true
- type: input
id: node-version
validations:
required: true
attributes:
label: "🤖 Node Version"
description: >
What Node version are you using?
- type: textarea
id: additional-context
validations:
required: false
attributes:
label: "📃 Provide any additional context for the Bug."
description: "Add any other context about the problem here."
placeholder: "It actually ..."
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "👀 Have you spent some time to check if this bug has been raised before?"
options:
- label: "I checked and didn't find similar issue"
required: true
- type: dropdown
attributes:
label: Are you willing to submit PR?
description: This is absolutely not required, but we are happy to guide you in the contribution process. Find us in help-needed channel on [Discord](https://discord.gitroom.com)!
options:
- "Yes I am willing to submit a PR!"
================================================
FILE: .github/ISSUE_TEMPLATE/02_feature_request.yml
================================================
name: 🚀 Feature
description: "Submit a proposal for a new feature"
title: "Give your feature request a title"
labels: ["type: feature-request"]
body:
- type: markdown
attributes:
value: |
We value your time and efforts to submit this Feature request form. 🙏
- type: textarea
id: feature-description
validations:
required: true
attributes:
label: "🔖 Feature description"
description: "A clear and concise description of what the feature is."
placeholder: "You should add ..."
- type: textarea
id: pitch
validations:
required: true
attributes:
label: "🎤 Why is this feature needed ?"
description: "Please explain why this feature should be implemented and how it would be used. Add examples, if applicable."
placeholder: "In my use-case, ..."
- type: textarea
id: solution
validations:
required: true
attributes:
label: "✌️ How do you aim to achieve this?"
description: "A clear and concise description of what you want to happen."
placeholder: "I want this feature to, ..."
- type: textarea
id: alternative
validations:
required: false
attributes:
label: "🔄️ Additional Information"
description: "A clear and concise description of any alternative solutions or additional solutions you've considered."
placeholder: "I tried, ..."
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "👀 Have you spent some time to check if this feature request has been raised before?"
options:
- label: "I checked and didn't find similar issue"
required: true
- type: dropdown
id: willing-to-submit-pr
attributes:
label: Are you willing to submit PR?
description: This is absolutely not required, but we are happy to guide you in the contribution process. Find us in help-needed channel on [Discord](https://discord.gitroom.com)!
options:
- "Yes I am willing to submit a PR!"
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
# Disable the default option to open a blank issue
blank_issues_enabled: true
# Define your custom links
contact_links:
# The first link definition
- name: 🙏 Installation Issue
url: https://discord.postiz.com
about: If you have an installation / configuration issue.
# You can add more links if needed
- name: Security Issue
url: https://github.com/gitroomhq/postiz-app/security/advisories/new
about: Please submit security Issues our GitHub Security Advisories.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
# What kind of change does this PR introduce?
eg: Bug fix, feature, docs update, ...
# Why was this change needed?
Please link to related issues when possible, and explain WHY you changed things, not WHAT you changed.
# Other information:
eg: Did you discuss this change with anybody before working on it (not required, but can be a good idea for bigger changes). Any plans for the future, etc?
# Checklist:
Put a "X" in the boxes below to indicate you have followed the checklist;
- [ ] I have read the [CONTRIBUTING](https://github.com/gitroomhq/postiz-app/blob/main/CONTRIBUTING.md) guide.
- [ ] I checked that there were not similar issues or PRs already open for this.
- [ ] This PR fixes just ONE issue (do not include multiple issues or types of change in the same PR) For example, don't try and fix a UI issue and include new dependencies in the same PR.
================================================
FILE: .github/copilot-instructions.md
================================================
# Copilot Coding Agent Instructions for Postiz
## Project Architecture
- Monorepo managed by NX, with apps in `apps/` and shared code in `libraries/`.
- Main services: `frontend` (Next.js), `backend` (NestJS), `cron`, `commands`, `extension`, `sdk`, and `workers`.
- Data layer uses Prisma ORM (`libraries/nestjs-libraries/src/database/prisma/schema.prisma`) with PostgreSQL as the default database.
- Redis (BullMQ) is used for queues and caching.
- Email notifications via Resend.
- Social login integrations (Instagram, Facebook) and Make.com/N8N integrations.
## Developer Workflows
- Use Node.js 20.17.0 and pnpm 8+.
- Install dependencies: `pnpm install`
- Build all apps: `pnpm run build`
- Run all apps in dev mode: `pnpm run dev`
- Test: `pnpm test` (Jest, coverage enabled)
- Individual app scripts are in each app's `package.json` (e.g., `pnpm --filter ./apps/backend run dev`).
- Prisma DB commands: `pnpm run prisma-generate`, `pnpm run prisma-db-push`, `pnpm run prisma-reset`.
- Docker: `docker compose -f ./docker-compose.dev.yaml up -d`
## Conventions & Patterns
- Use conventional commits (`feat:`, `fix:`, `chore:`).
- PRs should include clear descriptions, related issue links, and UI screenshots/GIFs if relevant.
- Comments are required for complex logic.
- Shared code lives in `libraries/` (e.g., helpers, React shared libraries, NestJS modules).
- Environment variables are managed via `.env` and referenced in Docker and scripts.
- Make sure to keep the `.env.example` file updated with new environment variables.
## Integration Points
- External APIs: Social media (Instagram, Facebook), Make.com, N8N, Resend, Stripe, etc.
- SDK (`apps/sdk`) provides programmatic access to Postiz features.
- Extension (`apps/extension`) is built with Vite, React, TypeScript, and Tailwind CSS.
## Key Files & Directories
- `apps/` — Main services and applications
- `libraries/` — Shared code and modules
- `docker-compose.dev.yaml` — Local development Docker setup
- `.env` — Environment configuration
- `jest.config.ts` — Test configuration
- `pnpm-workspace.yaml` — Workspace package management
- `README.md` — General project overview
- `libraries/nestjs-libraries/src/database/prisma/schema.prisma` — Database schema
## Documentation
- Main docs: https://docs.postiz.com/
- Developer guide: https://docs.postiz.com/developer-guide
- Public API: https://docs.postiz.com/public-api
---
# Logs
- Where logs are used, ensure Sentry is imported using `import * as Sentry from "@sentry/nextjs"`
- Enable logging in Sentry using `Sentry.init({ enableLogs: true })`
- Reference the logger using `const { logger } = Sentry`
- Sentry offers a `consoleLoggingIntegration` that can be used to log specific console error types automatically without instrumenting the individual logger calls
## Configuration
The Sentry initialization needs to be updated to enable the logs feature.
### Baseline
```javascript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
enableLogs: true,
});
```
### Logger Integration
```javascript
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
integrations: [
// send console.log, console.error, and console.warn calls as logs to Sentry
Sentry.consoleLoggingIntegration({ levels: ["log", "error", "warn"] }),
],
});
```
## Logger Examples
`logger.fmt` is a template literal function that should be used to bring variables into the structured logs.
```javascript
import * as Sentry from "@sentry/nextjs";
const { logger } = Sentry;
logger.trace("Starting database connection", { database: "users" });
logger.debug(logger.fmt`Cache miss for user: ${userId}`);
logger.info("Updated profile", { profileId: 345 });
logger.warn("Rate limit reached for endpoint", {
endpoint: "/api/results/",
isEnterprise: false,
});
logger.error("Failed to process payment", {
orderId: "order_123",
amount: 99.99,
});
logger.fatal("Database connection pool exhausted", {
database: "users",
activeConnections: 100,
});
```
---
For questions or unclear conventions, check the main README or ask for clarification in your PR description.
================================================
FILE: .github/workflows/build-containers.yml
================================================
---
name: "Build Containers"
on:
workflow_dispatch:
push:
tags:
- '*'
jobs:
build-containers-common:
runs-on: ubuntu-latest
outputs:
containerver: ${{ steps.getcontainerver.outputs.containerver }}
steps:
- name: Get Container Version
id: getcontainerver
run: |
echo "containerver=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
build-containers:
needs: build-containers-common
strategy:
matrix:
include:
- runnertags: ubuntu-latest
arch: amd64
- runnertags: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runnertags }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ghcr
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Build and Push Image
env:
CONTAINERVER: ${{ needs.build-containers-common.outputs.containerver }}
NEXT_PUBLIC_VERSION: ${{ github.ref_name }}
run: |
docker buildx build --platform linux/${{ matrix.arch }} \
-f Dockerfile.dev \
-t ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-${{ matrix.arch }} \
--build-arg NEXT_PUBLIC_VERSION=${{ env.NEXT_PUBLIC_VERSION }} \
--pull \
--no-cache \
--provenance=false --sbom=false \
--output "type=registry,name=ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-${{ matrix.arch }}" .
build-container-manifest:
needs: [build-containers, build-containers-common]
runs-on: ubuntu-latest
steps:
- name: Login to ghcr
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Create Docker Manifest
env:
CONTAINERVER: ${{ needs.build-containers-common.outputs.containerver }}
run: |
# Verify the architecture images
echo "Verifying AMD64 image:"
docker buildx imagetools inspect ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-amd64
echo "Verifying ARM64 image:"
docker buildx imagetools inspect ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-arm64
# Try to remove any existing manifests first
docker manifest rm ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }} || true
docker manifest rm ghcr.io/gitroomhq/postiz-app:latest || true
# Create and push the version-specific manifest
docker manifest create ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }} \
--amend ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-amd64 \
--amend ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-arm64
docker manifest push ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}
# Create and push the latest manifest
docker manifest create ghcr.io/gitroomhq/postiz-app:latest \
--amend ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-amd64 \
--amend ghcr.io/gitroomhq/postiz-app:${{ env.CONTAINERVER }}-arm64
docker manifest push ghcr.io/gitroomhq/postiz-app:latest
- name: Verify Manifest
run: |
docker manifest inspect ghcr.io/gitroomhq/postiz-app:latest
================================================
FILE: .github/workflows/build-extension.yaml
================================================
name: Build Extension
on:
workflow_dispatch:
jobs:
submit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Zip extensions
run: FRONTEND_URL=https://platform.postiz.com pnpm run build:extension
- name: Upload to Nextcloud
env:
NEXTCLOUD_URL: ${{ secrets.NEXTCLOUD_URL }}
NEXTCLOUD_USERNAME: ${{ secrets.NEXTCLOUD_USERNAME }}
NEXTCLOUD_PASSWORD: ${{ secrets.NEXTCLOUD_PASSWORD }}
run: |
curl -T apps/extension/extension.zip \
-u "$NEXTCLOUD_USERNAME:$NEXTCLOUD_PASSWORD" \
"$NEXTCLOUD_URL/extension.zip"
================================================
FILE: .github/workflows/build.yml
================================================
---
name: Build
on:
push:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['22.12.0']
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: |
${{ env.STORE_PATH }}
${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}-
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
================================================
FILE: .github/workflows/codeql.yml
================================================
---
name: "Code Quality Analysis"
on:
push:
branches:
- main
paths:
- apps/**
- '!apps/docs/**'
- libraries/**
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: 'ubuntu-latest'
permissions:
security-events: write
strategy:
fail-fast: false
matrix:
include:
- language: javascript-typescript
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
================================================
FILE: .github/workflows/eslint
================================================
---
name: ESLint
on:
push:
branches:
- main
paths:
- package.json
- apps/**
- '!apps/docs/**'
- libraries/**
pull_request:
paths:
- package.json
- apps/**
- '!apps/docs/**'
- libraries/**
jobs:
eslint:
name: Run eslint scanning
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
strategy:
matrix:
service: ["backend", "frontend"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: |
**/pnpm-lock.yaml
- name: Install ESLint
run: |
npm install eslint
npm install @microsoft/eslint-formatter-sarif@2.1.7
- name: Run ESLint
run: npx eslint apps/${{ matrix.service }}/
--config apps/${{ matrix.service }}/.eslintrc.json
--format @microsoft/eslint-formatter-sarif
--output-file apps/${{ matrix.service }}/eslint-results.sarif
continue-on-error: true
- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: apps/${{ matrix.service }}/eslint-results.sarif
wait-for-processing: true
================================================
FILE: .github/workflows/issue-label-triggers.yml
================================================
---
name: Issue Label Triggers
on:
issues:
types:
- labeled
jobs:
closed-public-website:
if: github.event.label.name == 'trigger-public-website'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Add comment
run: gh issue comment "$NUMBER" --body "$BODY" && gh issue close "$NUMBER"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
BODY: >
This issue concerns the public website, which is not open source and is not part of this repository.
If you have a question or concern about the content of the public website, please contact Nevo David.
If you are looking to contribute to the open source Postiz project code, this is the correct repository, and we welcome your contributions in a new GitHub issue.
================================================
FILE: .github/workflows/pr-docker-build.yml
================================================
name: Build and Publish PR Docker Image
on:
pull_request_target:
types: [opened, synchronize]
permissions: write-all
jobs:
build-and-publish:
runs-on: ubuntu-latest
environment:
name: build-pr
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Set image tag
id: vars
run: echo "IMAGE_TAG=ghcr.io/gitroomhq/postiz-app-pr:${{ github.event.pull_request.number }}" >> $GITHUB_ENV
- name: Build Docker image from Dockerfile.dev
run: docker build -f Dockerfile.dev -t $IMAGE_TAG .
- name: Push Docker image to GHCR
run: docker push $IMAGE_TAG
================================================
FILE: .github/workflows/pr-quality.yml
================================================
name: PR Quality
permissions:
contents: read
issues: read
pull-requests: write
on:
pull_request_target:
types: [opened, reopened]
jobs:
anti-slop:
runs-on: ubuntu-latest
steps:
- uses: peakoss/anti-slop@v0
with:
max-failures: 4
================================================
FILE: .github/workflows/publish-extension.yml
================================================
name: Publish Extension
on:
workflow_dispatch:
jobs:
submit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Zip extensions
run: FRONTEND_URL=https://platform.postiz.com pnpm run build:extension
- name: Publish to Chrome Web Store
uses: mnao305/chrome-extension-upload@v5.0.0
with:
extension-id: ${{ secrets.CHROME_EXTENSION_ID }}
client-id: ${{ secrets.CHROME_CLIENT_ID }}
client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
file-path: apps/extension/extension.zip
================================================
FILE: .github/workflows/stale.yml
================================================
name: Close inactive issues
on:
workflow_dispatch:
schedule:
- cron: "*/30 * * * *"
jobs:
close-issues:
if: github.repository == 'gitroomhq/postiz-app'
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
days-before-issue-stale: 90
days-before-issue-close: 7
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 90 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale."
exempt-issue-labels: "no-stale-bot"
days-before-pr-stale: 90
days-before-pr-close: 7
stale-pr-label: "stale"
stale-pr-message: "This PR is stale because it has been open for 90 days with no activity."
close-pr-message: "This PR was closed because it has been inactive for 7 days since being marked as stale."
exempt-pr-label: "no-stale-bot"
repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 180
================================================
FILE: .gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
/out-tsc
.env
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
.vscode/*
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db
.nx/cache
.nx/workspace-data
# Next.js
.next
# Vim files
**/*.swp
**/*.swo
# Temporary files
*.orig
*.~*~
*.tsbuildinfo
# ignore Secrets folder
.secrets/
libraries/plugins/src/plugins.ts
i18n.cache
================================================
FILE: .gitmodules
================================================
[submodule "libraries/plugins/src/list/public-api"]
path = libraries/plugins/src/list/public-api
url = git@github.com:gitroomhq/public-api.git
================================================
FILE: .npmrc
================================================
ignore-workspace-root-check=true
node-linker=hoisted
restrict-manifest-changes=true
sync-injected-deps-after-scripts[]=build
inject-workspace-packages=true
================================================
FILE: .prettierignore
================================================
# Add files here to ignore them from prettier formatting
/dist
/coverage
/.nx/cache
================================================
FILE: .prettierrc
================================================
{
"singleQuote": true
}
================================================
FILE: CLAUDE.md
================================================
This project is Postiz, a tool to schedule social media and chat posts to 28+ channels.
You can add posts to the calendar, they will be added into a workflow and posted at the right time.
You can find things like:
- Schedule posts
- Calendar view
- Analytics
- Team management
- Media library
This project is a monorepo with a root only package.json of dependencies.
Made with PNPM.
We have 3 important folders
- apps/backend - this is where the API code is (NESTJS)
- apps/orchestrator - this is temporal, it's for background jobs (NESTJS) it contains all the workflows and activities
- apps/frontend - this is the code of the frontend (Vite ReactJS)
- /libraries contains a lot of services shared between backend and orchestrator and frontend components.
We are using only pnpm, don't use any other dependency manager.
Never install frontend components from npmjs, focus on writing native components.
The project uses tailwind 3, before writing any component look at:
- /apps/frontend/src/app/colors.scss
- /apps/frontend/src/app/global.scss
- /apps/frontend/tailwind.config.js
All the --color-custom* are deprecated, don't use them.
And check other components in the system before to get the right design.
When working on the backend we need to pass the 3 layers:
Controller >> Service >> Repository (no shortcuts)
In some cases we will have
Controller >> Mananger >> Service >> Repository.
Most of the server logic should be inside of libs/server.
The backend repository is mostly used to write controller, and import files from libs.server.
For the frontend follow this:
- Many of the UI components lives in /apps/frontend/src/components/ui
- Routing is in /apps/frontend/src/app
- Components are in /apps/frontend/src/components
- always use SWR to fetch stuff, and use "useFetch" hook from /libraries/helpers/src/utils/custom.fetch.tsx
When using SWR, each one have to be in a seperate hook and must comply with react-hooks/rules-of-hooks, never put eslint-disable-next-line on it.
It means that this is valid:
const useCommunity = () => {
return useSWR....
}
This is not valid:
const useCommunity = () => {
return {
communities: () => useSWR<CommunitiesListResponse>("communities", getCommunities),
providers: () => useSWR<ProvidersListResponse>("providers", getProviders),
};
}
- Linting of the project can run only from the root.
- Use only pnpm.
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
nevo@gitroom.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Contributions are welcome - code, docs, whatever it might be! If this is your first contribution to an Open Source project or you're a core maintainer of multiple projects, your time and interest in contributing to this project is most welcome.
## Read the developers guide
The main documentation site has a [developer guide](https://docs.postiz.com/developer-guide) . That guide provides you a good understanding of the project structure, and how to setup your development environment. Read this document after you have read that guide. This document is intended to provide you a good understanding of how to submit your first contribution.
## Write code with others
This is an open source project, with an open and welcoming community that is always keen to welcome new contributors. We recommend the two best ways to interact with the community are:
- **GitHub issues**: To discuss more slowly, or longer-written messages.
- **[Discord chat](https://discord.postiz.com)**: To chat with people [Discord chat](https://discord.postiz.com/) and a quicker feedback.
As a general rule;
- **If a change is less than 3 lines**: You're probably safe just to submit the change without a discussion. This includes typos, dependency changes, and quick fixes, etc.
- **If a change is more than 3 lines**: It's probably best to discuss the change in an issue or on discord first. This is simply because you might not be aware of the roadmap for the project, or understand the impact this change might have. We're just trying to save you time here, and importantly, avoid you being disappointed if your change isn't accepted.
## Types of Contributions
Contributions can include:
- **Code improvements:** Fixing bugs or adding new features.
- **Documentation updates:** Enhancing clarity or adding missing information.
- **Feature requests:** Suggesting new capabilities or integrations.
- **Bug reports:** Identifying and reporting issues.
## How to contribute
This project follows a Fork/Feature Branch/Pull Request model. If you're not familiar with this, here's how it works:
1. **Fork the project:** Create a personal copy of the repository on your GitHub account.
2. **Clone your fork:** Bring a copy of your fork to your local machine.
```bash
git clone https://github.com/YOUR_USERNAME/postiz.git
```
3. **Create a new branch**: Start a new branch for your changes
```bash
git checkout -b feature/your-feature-name
```
4. **Make your changes**: Implement the changes you wish to contribute.
5. **Push your changes**: Upload your changes to your fork.
```bash
git push -u origin feature/your-feature-name
```
6. **Create a pull request**: Propose your changes **to the main branch**.
# Need Help?
Again, do check the [developer guide](https://docs.postiz.com/developer-guide). Much of what you probably need to know is in there.
If you encounter any issues, please visit our [support page](https://docs.postiz.com/support) or check the community forums. Your contributions help make Postiz better!
================================================
FILE: Dockerfile.dev
================================================
FROM node:22.20-bookworm-slim
ARG NEXT_PUBLIC_VERSION
ENV NEXT_PUBLIC_VERSION=$NEXT_PUBLIC_VERSION
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
make \
python3-pip \
bash \
nginx \
&& rm -rf /var/lib/apt/lists/*
RUN addgroup --system www \
&& adduser --system --ingroup www --home /www --shell /usr/sbin/nologin www \
&& mkdir -p /www \
&& chown -R www:www /www /var/lib/nginx
RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1 pm2
WORKDIR /app
COPY . /app
COPY var/docker/nginx.conf /etc/nginx/nginx.conf
RUN pnpm install
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm run build
CMD ["sh", "-c", "nginx && pnpm run pm2"]
================================================
FILE: Jenkins/Build.Jenkinsfile
================================================
// Declarative Pipeline for building Node.js application and running SonarQube analysis triggered by a push event.
pipeline {
// Defines the execution environment. Using 'agent any' to ensure an agent is available.
agent any
// Global environment block removed to prevent Groovy scoping issues with manual path calculation.
stages {
// Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins)
stage('Source Checkout') {
steps {
echo "Workspace already populated by the initial SCM checkout. Proceeding."
}
}
// Stage 2: Setup Node.js v20 and install pnpm
stage('Setup Environment and Tools') {
steps {
sh '''
echo "Ensuring required utilities and Node.js are installed..."
sudo apt-get update
sudo apt-get install -y curl unzip nodejs
# 1. Install Node.js v20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
echo "Node.js version: \$(node -v)"
# 2. Install pnpm globally (version 8)
npm install -g pnpm@8
echo "pnpm version: \$(pnpm -v)"
'''
}
}
// Stage 3: Install dependencies and build the application
stage('Install and Build') {
steps {
sh 'pnpm install'
sh 'pnpm run build'
}
}
// Stage 4: Run SonarQube analysis: Install scanner, get version, and execute.
stage('SonarQube Analysis') {
steps {
script {
// 1. Get the short 8-character commit SHA for project versioning
def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim()
echo "Commit SHA (short) is: ${commitShaShort}"
// --- 2. MANUALLY INSTALL THE SONAR SCANNER CLI LOCALLY IN THIS STAGE ---
sh """
echo "Manually downloading and installing Sonar Scanner CLI..."
# Download the stable scanner CLI package
curl -sS -o sonar-scanner.zip \
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip"
# Added -o flag to force overwrite and prevent interactive prompt failure
unzip -o -q sonar-scanner.zip -d .
"""
// 3. Find the extracted directory name and capture the full absolute bin path in Groovy
// This is defined locally and used directly, avoiding environment variable issues.
def scannerBinPath = sh(
returnStdout: true,
script: '''
SCANNER_DIR=$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1)
# Get the full absolute path to the executable file
echo \$(pwd)/\${SCANNER_DIR}/bin/sonar-scanner
'''
).trim()
echo "Scanner executable path captured: ${scannerBinPath}"
// 4. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN)
withSonarQubeEnv(installationName: 'SonarQube-Server') {
// 5. Execute the scanner using the Groovy variable directly.
sh """
echo "Starting SonarQube Analysis for project version: ${commitShaShort}"
# Execute the full, absolute path captured in the Groovy variable.
'${scannerBinPath}' \\
-Dsonar.projectVersion=${commitShaShort} \\
-Dsonar.sources=.
# SONAR_HOST_URL and SONAR_TOKEN are automatically passed as environment variables
# by the withSonarQubeEnv block.
"""
}
}
}
}
}
}
================================================
FILE: Jenkins/BuildPR.Jenkinsfile
================================================
// Declarative Pipeline for building Node.js application and running SonarQube analysis for a Pull Request.
pipeline {
// Defines the execution environment. Using 'agent any' to ensure an agent is available.
agent any
// Environment variables that hold PR details, provided by Jenkins Multibranch setup.
environment {
// FIX: Environment variables must be quoted or wrapped in a function call.
// We quote the 'env.CHANGE_ID' reference to fix the compilation error.
PR_KEY = "${env.CHANGE_ID}"
PR_BRANCH = "${env.CHANGE_BRANCH}"
PR_BASE = "${env.CHANGE_TARGET}"
}
stages {
// Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins)
stage('Source Checkout') {
steps {
echo "Workspace already populated by the initial SCM checkout. Proceeding."
}
}
// Stage 2: Setup Node.js v20, install pnpm, and install required tools (curl, unzip)
stage('Setup Environment and Tools') {
steps {
sh '''
echo "Ensuring required utilities and Node.js are installed..."
sudo apt-get update
sudo apt-get install -y curl unzip nodejs
# 1. Install Node.js v20 (closest matching the specified version '20.17.0')
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
echo "Node.js version: \$(node -v)"
# 2. Install pnpm globally (version 8)
npm install -g pnpm@8
echo "pnpm version: \$(pnpm -v)"
'''
}
}
// Stage 3: Install dependencies and build the application
stage('Install and Build') {
steps {
sh 'pnpm install'
sh 'pnpm run build'
}
}
// Stage 4: Run SonarQube PR analysis: Install scanner locally, get version, and execute.
stage('SonarQube Pull Request Analysis') {
steps {
script {
// 1. Get the short 8-character commit SHA for project versioning
def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim()
echo "Commit SHA (short) is: ${commitShaShort}"
// --- 2. MANUALLY INSTALL THE SONAR SCANNER CLI LOCALLY ---
sh """
echo "Manually downloading and installing Sonar Scanner CLI..."
curl -sS -o sonar-scanner.zip \
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip"
unzip -o -q sonar-scanner.zip -d .
"""
// 3. Find the extracted directory name and capture the full absolute executable path.
def scannerBinPath = sh(
returnStdout: true,
script: '''
SCANNER_DIR=$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1)
# Get the full absolute path to the executable file
echo \$(pwd)/\${SCANNER_DIR}/bin/sonar-scanner
'''
).trim()
echo "Scanner executable path captured: ${scannerBinPath}"
// 4. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN)
withSonarQubeEnv(installationName: 'SonarQube-Server') {
// 5. Execute the scanner using the Groovy variable directly with PR parameters.
sh """
echo "Starting SonarQube Pull Request Analysis for PR #${PR_KEY}"
'${scannerBinPath}' \\
-Dsonar.projectVersion=${commitShaShort} \\
-Dsonar.sources=. \\
-Dsonar.pullrequest.key=${PR_KEY} \\
-Dsonar.pullrequest.branch=${PR_BRANCH} \\
-Dsonar.pullrequest.base=${PR_BASE}
# SONAR_HOST_URL and SONAR_TOKEN are automatically passed as environment variables
# by the withSonarQubeEnv block.
"""
}
}
}
}
}
}
================================================
FILE: LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Postiz - Social media schedule tool
Copyright (C) 2025 Nevo David
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.
================================================
FILE: README.md
================================================
<p align="center">
<a href="https://postiz.com/" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/765e9d72-3ee7-4a56-9d59-a2c9befe2311">
<img alt="Postiz Logo" src="https://github.com/user-attachments/assets/f0d30d70-dddb-4142-8876-e9aa6ed1cb99" width="280"/>
</picture>
</a>
</p>
<p align="center">
<a href="https://opensource.org/license/agpl-v3">
<img src="https://img.shields.io/badge/License-AGPL%203.0-blue.svg" alt="License">
</a>
</p>
<h3 align="center"><strong><a href="https://github.com/gitroomhq/postiz-agent">NEW: check out Postiz agent CLI! perfect for OpenClaw and other agents</a></strong></h3>
<div align="center">
<strong>
<h2>Your ultimate AI social media scheduling tool</h2><br />
<a href="https://postiz.com">Postiz</a>: An alternative to: Buffer.com, Hypefury, Twitter Hunter, etc...<br /><br />
</strong>
Postiz offers everything you need to manage your social media posts,<br />build an audience, capture leads, and grow your business.
</div>
<div class="flex" align="center">
<br />
<img alt="Instagram" src="https://postiz.com/svgs/socials/Instagram.svg" width="32">
<img alt="Youtube" src="https://postiz.com/svgs/socials/Youtube.svg" width="32">
<img alt="Dribbble" src="https://postiz.com/svgs/socials/Dribbble.svg" width="32">
<img alt="Linkedin" src="https://postiz.com/svgs/socials/Linkedin.svg" width="32">
<img alt="Reddit" src="https://postiz.com/svgs/socials/Reddit.svg" width="32">
<img alt="TikTok" src="https://postiz.com/svgs/socials/TikTok.svg" width="32">
<img alt="Facebook" src="https://postiz.com/svgs/socials/Facebook.svg" width="32">
<img alt="Pinterest" src="https://postiz.com/svgs/socials/Pinterest.svg" width="32">
<img alt="Threads" src="https://postiz.com/svgs/socials/Threads.svg" width="32">
<img alt="X" src="https://postiz.com/svgs/socials/X.svg" width="32">
<img alt="Slack" src="https://postiz.com/svgs/socials/Slack.svg" width="32">
<img alt="Discord" src="https://postiz.com/svgs/socials/Discord.svg" width="32">
<img alt="Mastodon" src="https://postiz.com/svgs/socials/Mastodon.svg" width="32">
<img alt="Bluesky" src="https://postiz.com/svgs/socials/Bluesky.svg" width="32">
</div>
<p align="center">
<br />
<a href="https://docs.postiz.com" rel="dofollow"><strong>Explore the docs »</strong></a>
<br />
<br />
<a href="https://youtube.com/@postizofficial" rel="dofollow"><strong>Watch the YouTube Tutorials»</strong></a>
<br />
</p>
<p align="center">
<a href="https://platform.postiz.com">Register</a>
·
<a href="https://discord.postiz.com">Join Our Discord (devs only)</a>
·
<a href="https://docs.postiz.com/public-api">Public API</a><br />
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@postiz/node">NodeJS SDK</a>
·
<a href="https://www.npmjs.com/package/n8n-nodes-postiz">N8N custom node</a>
·
<a href="https://apps.make.com/postiz">Make.com integration</a>
</p>
<br />
## New - Postiz-as-a-service - Enterprise (Cloud)
Integrate powerful social media scheduling capabilities into your SaaS. <br />Multi-tenant architecture designed for SaaS companies who want to offer social media management to their users.
- **Skip App Approvals** - Use Postiz apps directly without going through lengthy social platform approval processes. Get the full power of Postiz instantly.
- **Multi-Tenant Architecture** - each of your customers gets their own isolated environment with separate accounts, channels, and team management.
- **Headless API** - Full REST API access to build your own frontend experience. Complete control over the user interface and branding.
- **Full OAuth Support** - Connect all major social platforms including Facebook, Instagram, Twitter, LinkedIn, TikTok, and more.
[Check it here](https://postiz.com/enterprise)
<br /><br />
## 🔌 See the leading Postiz features
<p align="center">
<a href="https://www.youtube.com/watch?v=BdsCVvEYgHU" target="_blank">
<img alt="Postiz" src="https://github.com/user-attachments/assets/8b9b7939-da1a-4be5-95be-42c6fce772de" />
</a>
</p>
## ✨ Features
|  |  |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|  |  |
### Our Sponsors
| Sponsor | Logo | Description |
|---------|:-----------------------------------------------------------------------:|-----------------|
| [Hostinger](https://www.hostinger.com/?ref=postiz) | <img src=".github/sponsors/hostinger.png" alt="Hostinger" width="500"/> | Hostinger is on a mission to make online success possible for anyone – from developers to aspiring bloggers and business owners |
| [Virlo](https://dev.virlo.ai/?ref=postiz) | <img src="https://github.com/user-attachments/assets/25182598-5344-45fc-b9cd-e4cfa16aabfd" alt="Virlo" width="500"/> | Virlo is the #1 social media trend spotting and all-in-one GTM tool for teams leveraging short-form video |
# Intro
- Schedule all your social media posts (many AI features)
- Measure your work with analytics.
- Collaborate with other team members to exchange or buy posts.
- Invite your team members to collaborate, comment, and schedule posts.
- At the moment there is no difference between the hosted version to the self-hosted version
- Perfect for automation (API) with platforms like N8N, Make.com, Zapier, etc.
## Tech Stack
- Pnpm workspaces (Monorepo)
- NextJS (React)
- NestJS
- Prisma (Default to PostgreSQL)
- Temporal
- Resend (email notifications)
## Quick Start
To have the project up and running, please follow the [Quick Start Guide](https://docs.postiz.com/quickstart)
## Sponsor Postiz
We now give a few options to Sponsor Postiz:
- Just a donation: You like what we are building, and want to buy us some coffees so we can build faster.
- Main Repository: Get your logo with a backlink from the main Postiz repository. Postiz has almost 3m downloads and 20k views per month.
- Main Repository + Website: Get your logo on the central repository and the main website. Here are some metrics: - Website has 20k hits per month + 65 DR (strong backlink) - Repository has 20k hits per month + Almost 3m docker downloads.
Link: https://opencollective.com/postiz
## Postiz Compliance
- Postiz is an open-source, self-hosted social media scheduling tool that supports platforms like X (formerly Twitter), Bluesky, Mastodon, Discord, and others.
- Postiz hosted service uses official, platform-approved OAuth flows.
- Postiz does not automate or scrape content from social media platforms.
- Postiz does not collect, store, or proxy API keys or access tokens from users.
- Postiz never ask users to paste API keys into our hosted product.
- Postiz Users always authenticate directly with the social platform (e.g., X, Discord, etc.), ensuring platform compliance and data privacy.
## Star History
[](https://www.star-history.com/#gitroomhq/postiz-app&type=date&legend=top-left)
## License
This repository's source code is available under the [AGPL-3.0 license](LICENSE).
<br /><br /><br />
<p align="center">
<a href="https://www.g2.com/products/postiz/take_survey" target="blank"><img alt="g2" src="https://github.com/user-attachments/assets/892cb74c-0b49-4589-b2f5-fbdbf7a98f66" /></a>
</p>
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Introduction
The Postiz app is committed to ensuring the security and integrity of our users' data. This security policy outlines our procedures for handling security vulnerabilities and our disclosure policy.
## Reporting Security Vulnerabilities
If you discover a security vulnerability in the Postiz app, please report it to us privately via email to one of the maintainers:
- @nevo-david
- @egelhaus ([E-Mail](mailto:egelhaus@ennogelhaus.de))
When reporting a security vulnerability, please provide as much detail as possible, including:
- A clear description of the vulnerability
- Steps to reproduce the vulnerability
- Any relevant code or configuration files
## Supported Versions
This project currently only supports the latest release. We recommend that users always use the latest version of the Postiz app to ensure they have the latest security patches.
## Disclosure Guidelines
We follow a private disclosure policy. If you discover a security vulnerability, please report it to us privately via email to one of the maintainers listed above. We will respond promptly to reports of vulnerabilities and work to resolve them as quickly as possible.
We will not publicly disclose security vulnerabilities until a patch or fix is available to prevent malicious actors from exploiting the vulnerability before a fix is released.
## Security Vulnerability Response Process
We take security vulnerabilities seriously and will respond promptly to reports of vulnerabilities. Our response process includes:
- Investigating the report and verifying the vulnerability.
- Developing a patch or fix for the vulnerability.
- Releasing the patch or fix as soon as possible.
- Notifying users of the vulnerability and the patch or fix.
## Template Attribution
This SECURITY.md file is based on the [GitHub Security Policy Template](https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository).
Thank you for helping to keep the `postiz-app` secure!
================================================
FILE: apps/backend/.gitignore
================================================
dist/
node_modules/
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
================================================
FILE: apps/backend/nest-cli.json
================================================
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"monorepo": false,
"sourceRoot": "src",
"entryFile": "../../dist/backend/apps/backend/src/main",
"language": "ts",
"generateOptions": {
"spec": false
},
"compilerOptions": {
"manualRestart": true,
"tsConfigPath": "./tsconfig.build.json",
"webpack": false,
"deleteOutDir": true,
"assets": [],
"watchAssets": false,
"plugins": []
}
}
================================================
FILE: apps/backend/package.json
================================================
{
"name": "postiz-backend",
"version": "1.0.0",
"description": "",
"scripts": {
"dev": "dotenv -e ../../.env -- nest start --watch --entryFile=./apps/backend/src/main",
"build": "cross-env NODE_ENV=production nest build",
"start": "dotenv -e ../../.env -- node --experimental-require-module ./dist/apps/backend/src/main.js",
"pm2": "pm2 start pnpm --name backend -- start"
},
"keywords": [],
"author": "",
"license": "ISC"
}
================================================
FILE: apps/backend/src/api/api.module.ts
================================================
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AuthController } from '@gitroom/backend/api/routes/auth.controller';
import { AuthService } from '@gitroom/backend/services/auth/auth.service';
import { UsersController } from '@gitroom/backend/api/routes/users.controller';
import { AuthMiddleware } from '@gitroom/backend/services/auth/auth.middleware';
import { StripeController } from '@gitroom/backend/api/routes/stripe.controller';
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
import { AnalyticsController } from '@gitroom/backend/api/routes/analytics.controller';
import { PoliciesGuard } from '@gitroom/backend/services/auth/permissions/permissions.guard';
import { PermissionsService } from '@gitroom/backend/services/auth/permissions/permissions.service';
import { IntegrationsController } from '@gitroom/backend/api/routes/integrations.controller';
import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager';
import { SettingsController } from '@gitroom/backend/api/routes/settings.controller';
import { PostsController } from '@gitroom/backend/api/routes/posts.controller';
import { MediaController } from '@gitroom/backend/api/routes/media.controller';
import { UploadModule } from '@gitroom/nestjs-libraries/upload/upload.module';
import { BillingController } from '@gitroom/backend/api/routes/billing.controller';
import { NotificationsController } from '@gitroom/backend/api/routes/notifications.controller';
import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.content.service';
import { CodesService } from '@gitroom/nestjs-libraries/services/codes.service';
import { CopilotController } from '@gitroom/backend/api/routes/copilot.controller';
import { PublicController } from '@gitroom/backend/api/routes/public.controller';
import { RootController } from '@gitroom/backend/api/routes/root.controller';
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
import { ShortLinkService } from '@gitroom/nestjs-libraries/short-linking/short.link.service';
import { Nowpayments } from '@gitroom/nestjs-libraries/crypto/nowpayments';
import { WebhookController } from '@gitroom/backend/api/routes/webhooks.controller';
import { SignatureController } from '@gitroom/backend/api/routes/signature.controller';
import { AutopostController } from '@gitroom/backend/api/routes/autopost.controller';
import { SetsController } from '@gitroom/backend/api/routes/sets.controller';
import { ThirdPartyController } from '@gitroom/backend/api/routes/third-party.controller';
import { MonitorController } from '@gitroom/backend/api/routes/monitor.controller';
import { NoAuthIntegrationsController } from '@gitroom/backend/api/routes/no.auth.integrations.controller';
import { EnterpriseController } from '@gitroom/backend/api/routes/enterprise.controller';
import { OAuthAppController } from '@gitroom/backend/api/routes/oauth-app.controller';
import { ApprovedAppsController } from '@gitroom/backend/api/routes/approved-apps.controller';
import { OAuthController, OAuthAuthorizedController } from '@gitroom/backend/api/routes/oauth.controller';
import { AuthProviderManager } from '@gitroom/backend/services/auth/providers/providers.manager';
import { GithubProvider } from '@gitroom/backend/services/auth/providers/github.provider';
import { GoogleProvider } from '@gitroom/backend/services/auth/providers/google.provider';
import { FarcasterProvider } from '@gitroom/backend/services/auth/providers/farcaster.provider';
import { WalletProvider } from '@gitroom/backend/services/auth/providers/wallet.provider';
import { OauthProvider } from '@gitroom/backend/services/auth/providers/oauth.provider';
const authenticatedController = [
UsersController,
AnalyticsController,
IntegrationsController,
SettingsController,
PostsController,
MediaController,
BillingController,
NotificationsController,
CopilotController,
WebhookController,
SignatureController,
AutopostController,
SetsController,
ThirdPartyController,
OAuthAppController,
ApprovedAppsController,
OAuthAuthorizedController,
];
@Module({
imports: [UploadModule],
controllers: [
RootController,
StripeController,
AuthController,
PublicController,
MonitorController,
EnterpriseController,
NoAuthIntegrationsController,
OAuthController,
...authenticatedController,
],
providers: [
AuthService,
StripeService,
OpenaiService,
ExtractContentService,
AuthMiddleware,
PoliciesGuard,
PermissionsService,
CodesService,
IntegrationManager,
TrackService,
ShortLinkService,
Nowpayments,
AuthProviderManager,
GithubProvider,
GoogleProvider,
FarcasterProvider,
WalletProvider,
OauthProvider,
],
get exports() {
return [...this.imports, ...this.providers];
},
})
export class ApiModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(AuthMiddleware).forRoutes(...authenticatedController);
}
}
================================================
FILE: apps/backend/src/api/routes/analytics.controller.ts
================================================
import { Controller, Get, Param, Query } from '@nestjs/common';
import { Organization } from '@prisma/client';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { ApiTags } from '@nestjs/swagger';
import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
@ApiTags('Analytics')
@Controller('/analytics')
export class AnalyticsController {
constructor(
private _integrationService: IntegrationService,
private _postsService: PostsService
) {}
@Get('/:integration')
async getIntegration(
@GetOrgFromRequest() org: Organization,
@Param('integration') integration: string,
@Query('date') date: string
) {
return this._integrationService.checkAnalytics(org, integration, date);
}
@Get('/post/:postId')
async getPostAnalytics(
@GetOrgFromRequest() org: Organization,
@Param('postId') postId: string,
@Query('date') date: string
) {
return this._postsService.checkPostAnalytics(org.id, postId, +date);
}
}
================================================
FILE: apps/backend/src/api/routes/approved-apps.controller.ts
================================================
import { Controller, Delete, Get, Param } from '@nestjs/common';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { User } from '@prisma/client';
import { ApiTags } from '@nestjs/swagger';
import { OAuthService } from '@gitroom/nestjs-libraries/database/prisma/oauth/oauth.service';
@ApiTags('Approved Apps')
@Controller('/user/approved-apps')
export class ApprovedAppsController {
constructor(private _oauthService: OAuthService) {}
@Get('/')
async list(@GetUserFromRequest() user: User) {
return this._oauthService.getApprovedApps(user.id);
}
@Delete('/:id')
async revoke(
@GetUserFromRequest() user: User,
@Param('id') id: string
) {
return this._oauthService.revokeApp(user.id, id);
}
}
================================================
FILE: apps/backend/src/api/routes/auth.controller.ts
================================================
import {
Body,
Controller,
Get,
Param,
Post,
Query,
Req,
Res,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { CreateOrgUserDto } from '@gitroom/nestjs-libraries/dtos/auth/create.org.user.dto';
import { LoginUserDto } from '@gitroom/nestjs-libraries/dtos/auth/login.user.dto';
import { AuthService } from '@gitroom/backend/services/auth/auth.service';
import { ForgotReturnPasswordDto } from '@gitroom/nestjs-libraries/dtos/auth/forgot-return.password.dto';
import { ForgotPasswordDto } from '@gitroom/nestjs-libraries/dtos/auth/forgot.password.dto';
import { ResendActivationDto } from '@gitroom/nestjs-libraries/dtos/auth/resend-activation.dto';
import { ApiTags } from '@nestjs/swagger';
import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management';
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
import { RealIP } from 'nestjs-real-ip';
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
import { Provider } from '@prisma/client';
import * as Sentry from '@sentry/nestjs';
@ApiTags('Auth')
@Controller('/auth')
export class AuthController {
constructor(
private _authService: AuthService,
private _emailService: EmailService
) {}
@Get('/can-register')
async canRegister() {
return {
register: await this._authService.canRegister(Provider.LOCAL as string),
};
}
@Post('/register')
async register(
@Req() req: Request,
@Body() body: CreateOrgUserDto,
@Res({ passthrough: false }) response: Response,
@RealIP() ip: string,
@UserAgent() userAgent: string
) {
try {
const getOrgFromCookie = this._authService.getOrgFromCookie(
req?.cookies?.org
);
const { jwt, addedOrg } = await this._authService.routeAuth(
body.provider,
body,
ip,
userAgent,
getOrgFromCookie
);
const activationRequired =
body.provider === 'LOCAL' && this._emailService.hasProvider();
if (activationRequired) {
response.header('activate', 'true');
response.status(200).json({ activate: true });
return;
}
response.cookie('auth', jwt, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
sameSite: 'none',
}
: {}),
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
if (process.env.NOT_SECURED) {
response.header('auth', jwt);
}
if (typeof addedOrg !== 'boolean' && addedOrg?.organizationId) {
response.cookie('showorg', addedOrg.organizationId, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
sameSite: 'none',
}
: {}),
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
if (process.env.NOT_SECURED) {
response.header('showorg', addedOrg.organizationId);
}
}
Sentry.metrics.count('new_user', 1);
response.header('onboarding', 'true');
response.status(200).json({
register: true,
});
} catch (e: any) {
response.status(400).send(e.message);
}
}
@Post('/login')
async login(
@Req() req: Request,
@Body() body: LoginUserDto,
@Res({ passthrough: false }) response: Response,
@RealIP() ip: string,
@UserAgent() userAgent: string
) {
try {
const getOrgFromCookie = this._authService.getOrgFromCookie(
req?.cookies?.org
);
const { jwt, addedOrg } = await this._authService.routeAuth(
body.provider,
body,
ip,
userAgent,
getOrgFromCookie
);
response.cookie('auth', jwt, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
sameSite: 'none',
}
: {}),
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
if (process.env.NOT_SECURED) {
response.header('auth', jwt);
}
if (typeof addedOrg !== 'boolean' && addedOrg?.organizationId) {
response.cookie('showorg', addedOrg.organizationId, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
sameSite: 'none',
}
: {}),
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
if (process.env.NOT_SECURED) {
response.header('showorg', addedOrg.organizationId);
}
}
response.header('reload', 'true');
response.status(200).json({
login: true,
});
} catch (e: any) {
response.status(400).send(e.message);
}
}
@Post('/forgot')
async forgot(@Body() body: ForgotPasswordDto) {
try {
await this._authService.forgot(body.email);
return {
forgot: true,
};
} catch (e) {
return {
forgot: false,
};
}
}
@Post('/forgot-return')
async forgotReturn(@Body() body: ForgotReturnPasswordDto) {
const reset = await this._authService.forgotReturn(body);
return {
reset: !!reset,
};
}
@Get('/oauth/:provider')
async oauthLink(@Param('provider') provider: string, @Query() query: any) {
return this._authService.oauthLink(provider, query);
}
@Post('/activate')
async activate(
@Body('code') code: string,
@Body('datafast_visitor_id') datafast_visitor_id: string,
@Res({ passthrough: false }) response: Response
) {
const activate = await this._authService.activate(code, datafast_visitor_id);
if (!activate) {
return response.status(200).json({ can: false });
}
response.cookie('auth', activate, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
sameSite: 'none',
}
: {}),
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
if (process.env.NOT_SECURED) {
response.header('auth', activate);
}
response.header('onboarding', 'true');
return response.status(200).json({ can: true });
}
@Post('/resend-activation')
async resendActivation(@Body() body: ResendActivationDto) {
try {
await this._authService.resendActivationEmail(body.email);
return {
success: true,
};
} catch (e: any) {
return {
success: false,
message: e.message,
};
}
}
@Post('/oauth/:provider/exists')
async oauthExists(
@Body('code') code: string,
@Param('provider') provider: string,
@Res({ passthrough: false }) response: Response
) {
const { jwt, token } = await this._authService.checkExists(provider, code);
if (token) {
return response.json({ token });
}
response.cookie('auth', jwt, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
sameSite: 'none',
}
: {}),
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
if (process.env.NOT_SECURED) {
response.header('auth', jwt);
}
response.header('reload', 'true');
response.status(200).json({
login: true,
});
}
}
================================================
FILE: apps/backend/src/api/routes/autopost.controller.ts
================================================
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
Query,
} from '@nestjs/common';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { ApiTags } from '@nestjs/swagger';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { AutopostService } from '@gitroom/nestjs-libraries/database/prisma/autopost/autopost.service';
import { AutopostDto } from '@gitroom/nestjs-libraries/dtos/autopost/autopost.dto';
import { AuthorizationActions, Sections } from '@gitroom/backend/services/auth/permissions/permission.exception.class';
@ApiTags('Autopost')
@Controller('/autopost')
export class AutopostController {
constructor(private _autopostsService: AutopostService) {}
@Get('/')
async getAutoposts(@GetOrgFromRequest() org: Organization) {
return this._autopostsService.getAutoposts(org.id);
}
@Post('/')
@CheckPolicies([AuthorizationActions.Create, Sections.WEBHOOKS])
async createAutopost(
@GetOrgFromRequest() org: Organization,
@Body() body: AutopostDto
) {
return this._autopostsService.createAutopost(org.id, body);
}
@Put('/:id')
async updateAutopost(
@GetOrgFromRequest() org: Organization,
@Body() body: AutopostDto,
@Param('id') id: string
) {
return this._autopostsService.createAutopost(org.id, body, id);
}
@Delete('/:id')
async deleteAutopost(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._autopostsService.deleteAutopost(org.id, id);
}
@Post('/:id/active')
async changeActive(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body('active') active: boolean
) {
return this._autopostsService.changeActive(org.id, id, active);
}
@Post('/send')
async sendWebhook(@Query('url') url: string) {
return this._autopostsService.loadXML(url);
}
}
================================================
FILE: apps/backend/src/api/routes/billing.controller.ts
================================================
import { Body, Controller, Get, HttpException, Param, Post, Req } from '@nestjs/common';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization, User } from '@prisma/client';
import { BillingSubscribeDto } from '@gitroom/nestjs-libraries/dtos/billing/billing.subscribe.dto';
import { ApiTags } from '@nestjs/swagger';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { NotificationService } from '@gitroom/nestjs-libraries/database/prisma/notifications/notification.service';
import { Request } from 'express';
import { Nowpayments } from '@gitroom/nestjs-libraries/crypto/nowpayments';
import { AuthService } from '@gitroom/helpers/auth/auth.service';
@ApiTags('Billing')
@Controller('/billing')
export class BillingController {
constructor(
private _subscriptionService: SubscriptionService,
private _stripeService: StripeService,
private _notificationService: NotificationService,
private _nowpayments: Nowpayments
) {}
@Get('/check/:id')
async checkId(
@GetOrgFromRequest() org: Organization,
@Param('id') body: string
) {
return {
status: await this._stripeService.checkSubscription(org.id, body),
};
}
@Get('/check-discount')
async checkDiscount(@GetOrgFromRequest() org: Organization) {
return {
offerCoupon: !(await this._stripeService.checkDiscount(org.paymentId))
? false
: AuthService.signJWT({ discount: true }),
};
}
@Post('/apply-discount')
async applyDiscount(@GetOrgFromRequest() org: Organization) {
await this._stripeService.applyDiscount(org.paymentId);
}
@Post('/finish-trial')
async finishTrial(@GetOrgFromRequest() org: Organization) {
try {
await this._stripeService.finishTrial(org.paymentId);
} catch (err) {}
return {
finish: true,
};
}
@Get('/is-trial-finished')
async isTrialFinished(@GetOrgFromRequest() org: Organization) {
return {
finished: !org.isTrailing,
};
}
@Post('/embedded')
embedded(
@GetOrgFromRequest() org: Organization,
@GetUserFromRequest() user: User,
@Body() body: BillingSubscribeDto,
@Req() req: Request
) {
const uniqueId = req?.cookies?.track;
return this._stripeService.embedded(
uniqueId,
org.id,
user.id,
body,
org.allowTrial
);
}
@Post('/subscribe')
subscribe(
@GetOrgFromRequest() org: Organization,
@GetUserFromRequest() user: User,
@Body() body: BillingSubscribeDto,
@Req() req: Request
) {
const uniqueId = req?.cookies?.track;
return this._stripeService.subscribe(
uniqueId,
org.id,
user.id,
body,
org.allowTrial
);
}
@Get('/portal')
async modifyPayment(@GetOrgFromRequest() org: Organization) {
const customer = await this._stripeService.getCustomerByOrganizationId(
org.id
);
const { url } = await this._stripeService.createBillingPortalLink(customer);
return {
portal: url,
};
}
@Get('/')
getCurrentBilling(@GetOrgFromRequest() org: Organization) {
return this._subscriptionService.getSubscriptionByOrganizationId(org.id);
}
@Post('/cancel')
async cancel(
@GetOrgFromRequest() org: Organization,
@GetUserFromRequest() user: User,
@Body() body: { feedback: string }
) {
await this._notificationService.sendEmail(
process.env.EMAIL_FROM_ADDRESS,
'Subscription Cancelled',
`Organization ${org.name} has cancelled their subscription because: ${body.feedback}`,
user.email
);
return this._stripeService.setToCancel(org.id);
}
@Post('/prorate')
prorate(
@GetOrgFromRequest() org: Organization,
@Body() body: BillingSubscribeDto
) {
return this._stripeService.prorate(org.id, body);
}
@Post('/lifetime')
async lifetime(
@GetOrgFromRequest() org: Organization,
@Body() body: { code: string }
) {
return this._stripeService.lifetimeDeal(org.id, body.code);
}
@Get('/charges')
async getCharges(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() org: Organization
) {
if (!user.isSuperAdmin) {
throw new HttpException('Unauthorized', 400);
}
return this._stripeService.getCharges(org.id);
}
@Post('/refund-charges')
async refundCharges(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() org: Organization,
@Body() body: { chargeIds: string[] }
) {
if (!user.isSuperAdmin) {
throw new HttpException('Unauthorized', 400);
}
return this._stripeService.refundCharges(org.id, body.chargeIds);
}
@Post('/cancel-subscription')
async cancelSubscription(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() org: Organization
) {
if (!user.isSuperAdmin) {
throw new HttpException('Unauthorized', 400);
}
return this._stripeService.cancelSubscription(org.id);
}
@Post('/add-subscription')
async addSubscription(
@Body() body: { subscription: string },
@GetUserFromRequest() user: User,
@GetOrgFromRequest() org: Organization
) {
if (!user.isSuperAdmin) {
throw new Error('Unauthorized');
}
await this._subscriptionService.addSubscription(
org.id,
user.id,
body.subscription
);
}
@Get('/crypto')
async crypto(@GetOrgFromRequest() org: Organization) {
return this._nowpayments.createPaymentPage(org.id);
}
}
================================================
FILE: apps/backend/src/api/routes/copilot.controller.ts
================================================
import {
Logger,
Controller,
Get,
Post,
Req,
Res,
Query,
Param,
} from '@nestjs/common';
import {
CopilotRuntime,
OpenAIAdapter,
copilotRuntimeNodeHttpEndpoint,
copilotRuntimeNextJSAppRouterEndpoint,
} from '@copilotkit/runtime';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { MastraAgent } from '@ag-ui/mastra';
import { MastraService } from '@gitroom/nestjs-libraries/chat/mastra.service';
import { Request, Response } from 'express';
import { RuntimeContext } from '@mastra/core/di';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { AuthorizationActions, Sections } from '@gitroom/backend/services/auth/permissions/permission.exception.class';
export type ChannelsContext = {
integrations: string;
organization: string;
ui: string;
};
@Controller('/copilot')
export class CopilotController {
constructor(
private _subscriptionService: SubscriptionService,
private _mastraService: MastraService
) {}
@Post('/chat')
chatAgent(@Req() req: Request, @Res() res: Response) {
if (
process.env.OPENAI_API_KEY === undefined ||
process.env.OPENAI_API_KEY === ''
) {
Logger.warn('OpenAI API key not set, chat functionality will not work');
return;
}
const copilotRuntimeHandler = copilotRuntimeNodeHttpEndpoint({
endpoint: '/copilot/chat',
runtime: new CopilotRuntime(),
serviceAdapter: new OpenAIAdapter({
model: 'gpt-4.1',
}),
});
return copilotRuntimeHandler(req, res);
}
@Post('/agent')
@CheckPolicies([AuthorizationActions.Create, Sections.AI])
async agent(
@Req() req: Request,
@Res() res: Response,
@GetOrgFromRequest() organization: Organization
) {
if (
process.env.OPENAI_API_KEY === undefined ||
process.env.OPENAI_API_KEY === ''
) {
Logger.warn('OpenAI API key not set, chat functionality will not work');
return;
}
const mastra = await this._mastraService.mastra();
const runtimeContext = new RuntimeContext<ChannelsContext>();
runtimeContext.set(
'integrations',
req?.body?.variables?.properties?.integrations || []
);
runtimeContext.set('organization', JSON.stringify(organization));
runtimeContext.set('ui', 'true');
const agents = MastraAgent.getLocalAgents({
resourceId: organization.id,
mastra,
// @ts-ignore
runtimeContext,
});
const runtime = new CopilotRuntime({
agents,
});
const copilotRuntimeHandler = copilotRuntimeNextJSAppRouterEndpoint({
endpoint: '/copilot/agent',
runtime,
// properties: req.body.variables.properties,
serviceAdapter: new OpenAIAdapter({
model: 'gpt-4.1',
}),
});
return copilotRuntimeHandler.handleRequest(req, res);
}
@Get('/credits')
calculateCredits(
@GetOrgFromRequest() organization: Organization,
@Query('type') type: 'ai_images' | 'ai_videos'
) {
return this._subscriptionService.checkCredits(
organization,
type || 'ai_images'
);
}
@Get('/:thread/list')
@CheckPolicies([AuthorizationActions.Create, Sections.AI])
async getMessagesList(
@GetOrgFromRequest() organization: Organization,
@Param('thread') threadId: string
): Promise<any> {
const mastra = await this._mastraService.mastra();
const memory = await mastra.getAgent('postiz').getMemory();
try {
return await memory.query({
resourceId: organization.id,
threadId,
});
} catch (err) {
return { messages: [] };
}
}
@Get('/list')
@CheckPolicies([AuthorizationActions.Create, Sections.AI])
async getList(@GetOrgFromRequest() organization: Organization) {
const mastra = await this._mastraService.mastra();
// @ts-ignore
const memory = await mastra.getAgent('postiz').getMemory();
const list = await memory.getThreadsByResourceIdPaginated({
resourceId: organization.id,
perPage: 100000,
page: 0,
orderBy: 'createdAt',
sortDirection: 'DESC',
});
return {
threads: list.threads.map((p) => ({
id: p.id,
title: p.title,
})),
};
}
}
================================================
FILE: apps/backend/src/api/routes/enterprise.controller.ts
================================================
import { Body, Controller, Param, Post, Res } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { AuthService } from '@gitroom/helpers/auth/auth.service';
import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service';
import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager';
import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.service';
import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
@ApiTags('Enterprise')
@Controller('/enterprise')
export class EnterpriseController {
constructor(
private _integrationManager: IntegrationManager,
private _organizationService: OrganizationService,
private _integrationService: IntegrationService,
private _postsService: PostsService
) {}
@Post('/create-user')
async createUser(@Body('params') params: string) {
try {
const { id, name, saasName, email } = AuthService.verifyJWT(params) as {
id: string;
name: string;
email: string;
saasName: string;
};
try {
return await this._organizationService.createMaxUser(
id,
name,
saasName,
email
);
} catch (err) {
return { create: false };
}
} catch (err) {
return { success: false };
}
}
@Post('/url')
async redirectParams(@Body('params') params: string) {
try {
const load = AuthService.verifyJWT(params) as {
redirectUrl: string;
apiKey: string;
refreshId?: string;
provider: string;
webhookUrl: string;
};
if (!load || !load.redirectUrl || !load.apiKey || !load.provider) {
return;
}
const org = await this._organizationService.getOrgByApiKey(load.apiKey);
if (!org) {
throw new Error('Organization not found');
}
if (
!this._integrationManager
.getAllowedSocialsIntegrations()
.includes(load.provider)
) {
throw new Error('Integration not allowed');
}
const integrationProvider = this._integrationManager.getSocialIntegration(
load.provider
);
const { codeVerifier, state, url } =
await integrationProvider.generateAuthUrl();
if (load.refreshId) {
await ioRedis.set(`refresh:${state}`, load.refreshId, 'EX', 3600);
}
await ioRedis.set(`webhookUrl:${state}`, load.webhookUrl, 'EX', 3600);
await ioRedis.set(`redirect:${state}`, load.redirectUrl, 'EX', 3600);
await ioRedis.set(`organization:${state}`, org.id, 'EX', 3600);
await ioRedis.set(`login:${state}`, codeVerifier, 'EX', 3600);
return url;
} catch (err) {}
}
@Post('/delete-channel')
async deleteChannel(@Body('params') params: string) {
try {
const load = AuthService.verifyJWT(params) as {
apiKey: string;
id: string;
};
if (!load || !load.apiKey || !load.id) {
return { success: false };
}
const org = await this._organizationService.getOrgByApiKey(load.apiKey);
if (!org) {
return { success: false };
}
const isTherePosts = await this._integrationService.getPostsForChannel(
org.id,
load.id
);
if (isTherePosts.length) {
for (const post of isTherePosts) {
this._postsService.deletePost(org.id, post.group).catch(() => {});
}
}
await this._integrationService.deleteChannel(org.id, load.id);
return { success: true };
} catch (err) {
return { success: false };
}
}
}
================================================
FILE: apps/backend/src/api/routes/integrations.controller.ts
================================================
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
Query,
} from '@nestjs/common';
import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service';
import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager';
import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization, User } from '@prisma/client';
import { IntegrationFunctionDto } from '@gitroom/nestjs-libraries/dtos/integrations/integration.function.dto';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing';
import { ApiTags } from '@nestjs/swagger';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
import { IntegrationTimeDto } from '@gitroom/nestjs-libraries/dtos/integrations/integration.time.dto';
import { PlugDto } from '@gitroom/nestjs-libraries/dtos/plugs/plug.dto';
import { RefreshToken } from '@gitroom/nestjs-libraries/integrations/social.abstract';
import { timer } from '@gitroom/helpers/utils/timer';
import { TelegramProvider } from '@gitroom/nestjs-libraries/integrations/social/telegram.provider';
import { MoltbookProvider } from '@gitroom/nestjs-libraries/integrations/social/moltbook.provider';
import {
AuthorizationActions,
Sections,
} from '@gitroom/backend/services/auth/permissions/permission.exception.class';
import { uniqBy } from 'lodash';
import { RefreshIntegrationService } from '@gitroom/nestjs-libraries/integrations/refresh.integration.service';
@ApiTags('Integrations')
@Controller('/integrations')
export class IntegrationsController {
constructor(
private _integrationManager: IntegrationManager,
private _integrationService: IntegrationService,
private _postService: PostsService,
private _refreshIntegrationService: RefreshIntegrationService
) {}
@Post('/provider/:id/connect')
@CheckPolicies([AuthorizationActions.Create, Sections.CHANNEL])
async saveProviderPage(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body() body: any
) {
return this._integrationService.saveProviderPage(org.id, id, body);
}
@Get('/:identifier/internal-plugs')
getInternalPlugs(@Param('identifier') identifier: string) {
return this._integrationManager.getInternalPlugs(identifier);
}
@Get('/customers')
getCustomers(@GetOrgFromRequest() org: Organization) {
return this._integrationService.customers(org.id);
}
@Put('/:id/group')
async updateIntegrationGroup(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body() body: { group: string }
) {
return this._integrationService.updateIntegrationGroup(
org.id,
id,
body.group
);
}
@Put('/:id/customer-name')
async updateOnCustomerName(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body() body: { name: string }
) {
return this._integrationService.updateOnCustomerName(org.id, id, body.name);
}
@Get('/list')
async getIntegrationList(@GetOrgFromRequest() org: Organization) {
return {
integrations: await Promise.all(
(
await this._integrationService.getIntegrationsList(org.id)
).map(async (p) => {
const findIntegration = this._integrationManager.getSocialIntegration(
p.providerIdentifier
);
return {
name: p.name,
id: p.id,
internalId: p.internalId,
disabled: p.disabled,
editor: findIntegration.editor,
picture: p.picture || '/no-picture.jpg',
identifier: p.providerIdentifier,
inBetweenSteps: p.inBetweenSteps,
refreshNeeded: p.refreshNeeded,
isCustomFields: !!findIntegration.customFields,
...(findIntegration.customFields
? { customFields: await findIntegration.customFields() }
: {}),
display: p.profile,
type: p.type,
time: JSON.parse(p.postingTimes),
changeProfilePicture: !!findIntegration?.changeProfilePicture,
changeNickName: !!findIntegration?.changeNickname,
customer: p.customer,
additionalSettings: p.additionalSettings || '[]',
};
})
),
};
}
@Post('/:id/settings')
async updateProviderSettings(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body('additionalSettings') body: string
) {
if (typeof body !== 'string') {
throw new Error('Invalid body');
}
await this._integrationService.updateProviderSettings(org.id, id, body);
}
@Post('/:id/nickname')
async setNickname(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body() body: { name: string; picture: string }
) {
const integration = await this._integrationService.getIntegrationById(
org.id,
id
);
if (!integration) {
throw new Error('Invalid integration');
}
const manager = this._integrationManager.getSocialIntegration(
integration.providerIdentifier
);
if (!manager.changeProfilePicture && !manager.changeNickname) {
throw new Error('Invalid integration');
}
const { url } = manager.changeProfilePicture
? await manager.changeProfilePicture(
integration.internalId,
integration.token,
body.picture
)
: { url: '' };
const { name } = manager.changeNickname
? await manager.changeNickname(
integration.internalId,
integration.token,
body.name
)
: { name: '' };
return this._integrationService.updateNameAndUrl(id, name, url);
}
@Get('/:id')
getSingleIntegration(
@Param('id') id: string,
@Query('order') order: string,
@GetUserFromRequest() user: User,
@GetOrgFromRequest() org: Organization
) {
return this._integrationService.getIntegrationForOrder(
id,
order,
user.id,
org.id
);
}
@Get('/social/:integration')
@CheckPolicies([AuthorizationActions.Create, Sections.CHANNEL])
async getIntegrationUrl(
@Param('integration') integration: string,
@Query('refresh') refresh: string,
@Query('externalUrl') externalUrl: string,
@Query('onboarding') onboarding: string,
@GetOrgFromRequest() org: Organization
) {
if (
!this._integrationManager
.getAllowedSocialsIntegrations()
.includes(integration)
) {
throw new Error('Integration not allowed');
}
const integrationProvider =
this._integrationManager.getSocialIntegration(integration);
if (integrationProvider.externalUrl && !externalUrl) {
throw new Error('Missing external url');
}
try {
const getExternalUrl = integrationProvider.externalUrl
? {
...(await integrationProvider.externalUrl(externalUrl)),
instanceUrl: externalUrl,
}
: undefined;
const { codeVerifier, state, url } =
await integrationProvider.generateAuthUrl(getExternalUrl);
if (refresh) {
await ioRedis.set(`refresh:${state}`, refresh, 'EX', 3600);
}
if (onboarding === 'true') {
await ioRedis.set(`onboarding:${state}`, 'true', 'EX', 3600);
}
await ioRedis.set(`organization:${state}`, org.id, 'EX', 3600);
await ioRedis.set(`login:${state}`, codeVerifier, 'EX', 3600);
await ioRedis.set(
`external:${state}`,
JSON.stringify(getExternalUrl),
'EX',
3600
);
return { url };
} catch (err) {
return { err: true };
}
}
@Post('/:id/time')
async setTime(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body() body: IntegrationTimeDto
) {
return this._integrationService.setTimes(org.id, id, body);
}
@Post('/mentions')
async mentions(
@GetOrgFromRequest() org: Organization,
@Body() body: IntegrationFunctionDto
) {
const getIntegration = await this._integrationService.getIntegrationById(
org.id,
body.id
);
if (!getIntegration) {
throw new Error('Invalid integration');
}
let newList: any[] | { none: true } = [];
try {
newList = (await this.functionIntegration(org, body)) || [];
} catch (err) {
console.log(err);
}
if (!Array.isArray(newList) && newList?.none) {
return newList;
}
const list = await this._integrationService.getMentions(
getIntegration.providerIdentifier,
body?.data?.query
);
if (Array.isArray(newList) && newList.length) {
await this._integrationService.insertMentions(
getIntegration.providerIdentifier,
newList
.map((p: any) => ({
name: p.label || '',
username: p.id || '',
image: p.image || '',
doNotCache: p.doNotCache || false,
}))
.filter((f: any) => f.name && !f.doNotCache)
);
}
return uniqBy(
[
...list.map((p) => ({
id: p.username,
image: p.image,
label: p.name,
})),
...(newList as any[]),
],
(p) => p.id
).filter((f) => f.label && f.id);
}
@Post('/function')
async functionIntegration(
@GetOrgFromRequest() org: Organization,
@Body() body: IntegrationFunctionDto
): Promise<any> {
const getIntegration = await this._integrationService.getIntegrationById(
org.id,
body.id
);
if (!getIntegration) {
throw new Error('Invalid integration');
}
const integrationProvider = this._integrationManager.getSocialIntegration(
getIntegration.providerIdentifier
);
if (!integrationProvider) {
throw new Error('Invalid provider');
}
// @ts-ignore
if (integrationProvider[body.name]) {
try {
// @ts-ignore
const load = await integrationProvider[body.name](
getIntegration.token,
body.data,
getIntegration.internalId,
getIntegration
);
return load;
} catch (err) {
if (err instanceof RefreshToken) {
const data = await this._refreshIntegrationService.refresh(
getIntegration
);
if (!data) {
return;
}
const { accessToken } = data;
if (accessToken) {
if (integrationProvider.refreshWait) {
await timer(10000);
}
return this.functionIntegration(org, body);
}
return false;
}
return false;
}
}
throw new Error('Function not found');
}
@Post('/disable')
disableChannel(
@GetOrgFromRequest() org: Organization,
@Body('id') id: string
) {
return this._integrationService.disableChannel(org.id, id);
}
@Post('/enable')
enableChannel(
@GetOrgFromRequest() org: Organization,
@Body('id') id: string
) {
return this._integrationService.enableChannel(
org.id,
// @ts-ignore
org?.subscription?.totalChannels || pricing.FREE.channel,
id
);
}
@Delete('/')
async deleteChannel(
@GetOrgFromRequest() org: Organization,
@Body('id') id: string
) {
const isTherePosts = await this._integrationService.getPostsForChannel(
org.id,
id
);
if (isTherePosts.length) {
for (const post of isTherePosts) {
this._postService.deletePost(org.id, post.group).catch((err) => {});
}
}
return this._integrationService.deleteChannel(org.id, id);
}
@Get('/plug/list')
async getPlugList() {
return { plugs: this._integrationManager.getAllPlugs() };
}
@Get('/:id/plugs')
async getPlugsByIntegrationId(
@Param('id') id: string,
@GetOrgFromRequest() org: Organization
) {
return this._integrationService.getPlugsByIntegrationId(org.id, id);
}
@Post('/:id/plugs')
async postPlugsByIntegrationId(
@Param('id') id: string,
@GetOrgFromRequest() org: Organization,
@Body() body: PlugDto
) {
return this._integrationService.createOrUpdatePlug(org.id, id, body);
}
@Put('/plugs/:id/activate')
async changePlugActivation(
@Param('id') id: string,
@GetOrgFromRequest() org: Organization,
@Body('status') status: boolean
) {
return this._integrationService.changePlugActivation(org.id, id, status);
}
@Get('/telegram/updates')
async getUpdates(@Query() query: { word: string; id?: number }) {
return new TelegramProvider().getBotId(query);
}
@Post('/moltbook/register')
async moltbookRegister(
@Body() body: { name: string; description: string }
) {
try {
const provider = new MoltbookProvider();
const result = await provider.registerAgent(body.name, body.description);
return {
apiKey: result.api_key,
claimUrl: result.claim_url,
verificationCode: result.verification_code,
};
} catch (err: any) {
return { error: err.message || 'Registration failed' };
}
}
@Get('/moltbook/status')
async moltbookStatus(@Query('apiKey') apiKey: string) {
try {
const provider = new MoltbookProvider();
const result = await provider.checkAgentStatus(apiKey);
return { claimed: result?.status === 'claimed' };
} catch (err) {
return { claimed: false };
}
}
}
================================================
FILE: apps/backend/src/api/routes/media.controller.ts
================================================
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Query,
Req,
Res,
UploadedFile,
UseInterceptors,
UsePipes,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { MediaService } from '@gitroom/nestjs-libraries/database/prisma/media/media.service';
import { ApiTags } from '@nestjs/swagger';
import handleR2Upload from '@gitroom/nestjs-libraries/upload/r2.uploader';
import { FileInterceptor } from '@nestjs/platform-express';
import { CustomFileValidationPipe } from '@gitroom/nestjs-libraries/upload/custom.upload.validation';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { UploadFactory } from '@gitroom/nestjs-libraries/upload/upload.factory';
import { SaveMediaInformationDto } from '@gitroom/nestjs-libraries/dtos/media/save.media.information.dto';
import { VideoDto } from '@gitroom/nestjs-libraries/dtos/videos/video.dto';
import { VideoFunctionDto } from '@gitroom/nestjs-libraries/dtos/videos/video.function.dto';
@ApiTags('Media')
@Controller('/media')
export class MediaController {
private storage = UploadFactory.createStorage();
constructor(
private _mediaService: MediaService,
private _subscriptionService: SubscriptionService
) {}
@Delete('/:id')
deleteMedia(@GetOrgFromRequest() org: Organization, @Param('id') id: string) {
return this._mediaService.deleteMedia(org.id, id);
}
@Post('/generate-video')
generateVideo(
@GetOrgFromRequest() org: Organization,
@Body() body: VideoDto
) {
console.log('hello');
return this._mediaService.generateVideo(org, body);
}
@Post('/generate-image')
async generateImage(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Body('prompt') prompt: string,
isPicturePrompt = false
) {
const total = await this._subscriptionService.checkCredits(org);
if (process.env.STRIPE_PUBLISHABLE_KEY && total.credits <= 0) {
return false;
}
return {
output:
(isPicturePrompt ? '' : 'data:image/png;base64,') +
(await this._mediaService.generateImage(prompt, org, isPicturePrompt)),
};
}
@Post('/generate-image-with-prompt')
async generateImageFromText(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Body('prompt') prompt: string
) {
const image = await this.generateImage(org, req, prompt, true);
if (!image) {
return false;
}
const file = await this.storage.uploadSimple(image.output);
return this._mediaService.saveFile(org.id, file.split('/').pop(), file);
}
@Post('/upload-server')
@UseInterceptors(FileInterceptor('file'))
@UsePipes(new CustomFileValidationPipe())
async uploadServer(
@GetOrgFromRequest() org: Organization,
@UploadedFile() file: Express.Multer.File
) {
const originalName = file?.originalname || '';
const uploadedFile = await this.storage.uploadFile(file);
return this._mediaService.saveFile(
org.id,
uploadedFile.originalname,
uploadedFile.path,
originalName
);
}
@Post('/save-media')
async saveMedia(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Body('name') name: string,
@Body('originalName') originalName: string
) {
if (!name) {
return false;
}
return this._mediaService.saveFile(
org.id,
name,
process.env.CLOUDFLARE_BUCKET_URL + '/' + name,
originalName || undefined
);
}
@Post('/information')
saveMediaInformation(
@GetOrgFromRequest() org: Organization,
@Body() body: SaveMediaInformationDto
) {
return this._mediaService.saveMediaInformation(org.id, body);
}
@Post('/upload-simple')
@UseInterceptors(FileInterceptor('file'))
async uploadSimple(
@GetOrgFromRequest() org: Organization,
@UploadedFile('file') file: Express.Multer.File,
@Body('preventSave') preventSave: string = 'false'
) {
const originalName = file.originalname;
const getFile = await this.storage.uploadFile(file);
if (preventSave === 'true') {
const { path } = getFile;
return { path };
}
return this._mediaService.saveFile(
org.id,
getFile.originalname,
getFile.path,
originalName
);
}
@Post('/:endpoint')
async uploadFile(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Res() res: Response,
@Param('endpoint') endpoint: string
) {
const upload = await handleR2Upload(endpoint, req, res);
if (endpoint !== 'complete-multipart-upload') {
return upload;
}
// @ts-ignore
const name = upload.Location.split('/').pop();
const originalName = req.body?.file?.name;
const saveFile = await this._mediaService.saveFile(
org.id,
name,
// @ts-ignore
upload.Location,
originalName || undefined
);
res.status(200).json({ ...upload, saved: saveFile });
}
@Get('/')
getMedia(
@GetOrgFromRequest() org: Organization,
@Query('page') page: number
) {
return this._mediaService.getMedia(org.id, page);
}
@Get('/video-options')
getVideos() {
return this._mediaService.getVideoOptions();
}
@Post('/video/function')
videoFunction(
@Body() body: VideoFunctionDto
) {
return this._mediaService.videoFunction(body.identifier, body.functionName, body.params);
}
@Get('/generate-video/:type/allowed')
generateVideoAllowed(
@GetOrgFromRequest() org: Organization,
@Param('type') type: string
) {
return this._mediaService.generateVideoAllowed(org, type);
}
}
================================================
FILE: apps/backend/src/api/routes/monitor.controller.ts
================================================
import { Controller, Get, Param } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Monitor')
@Controller('/monitor')
export class MonitorController {
@Get('/queue/:name')
async getMessagesGroup(@Param('name') name: string) {
return {
status: 'success',
message: `Queue ${name} is healthy.`,
};
}
}
================================================
FILE: apps/backend/src/api/routes/no.auth.integrations.controller.ts
================================================
import {
Body,
Controller,
Get,
HttpException,
Param,
Post,
UseFilters,
} from '@nestjs/common';
import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service';
import { ConnectIntegrationDto } from '@gitroom/nestjs-libraries/dtos/integrations/connect.integration.dto';
import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager';
import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { ApiTags } from '@nestjs/swagger';
import { NotEnoughScopesFilter } from '@gitroom/nestjs-libraries/integrations/integration.missing.scopes';
import { AuthService } from '@gitroom/helpers/auth/auth.service';
import { AuthTokenDetails } from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface';
import { NotEnoughScopes } from '@gitroom/nestjs-libraries/integrations/social.abstract';
import {
AuthorizationActions,
Sections,
} from '@gitroom/backend/services/auth/permissions/permission.exception.class';
import { RefreshIntegrationService } from '@gitroom/nestjs-libraries/integrations/refresh.integration.service';
import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.service';
@ApiTags('Integrations')
@Controller('/integrations')
export class NoAuthIntegrationsController {
constructor(
private _integrationManager: IntegrationManager,
private _integrationService: IntegrationService,
private _refreshIntegrationService: RefreshIntegrationService,
private _organizationService: OrganizationService
) {}
@Get('/')
getIntegrations() {
return this._integrationManager.getAllIntegrations();
}
@Post('/social-connect/:integration')
@CheckPolicies([AuthorizationActions.Create, Sections.CHANNEL])
@UseFilters(new NotEnoughScopesFilter())
async connectSocialMedia(
@Param('integration') integration: string,
@Body() body: ConnectIntegrationDto
) {
if (
!this._integrationManager
.getAllowedSocialsIntegrations()
.includes(integration)
) {
throw new Error('Integration not allowed');
}
const integrationProvider =
this._integrationManager.getSocialIntegration(integration);
const getCodeVerifier = integrationProvider.customFields
? 'none'
: await ioRedis.get(`login:${body.state}`);
if (!getCodeVerifier) {
throw new Error('Invalid state');
}
const organization = await ioRedis.get(`organization:${body.state}`);
if (!organization) {
throw new Error('Organization not found');
}
const org = await this._organizationService.getOrgById(organization);
if (!integrationProvider.customFields) {
await ioRedis.del(`login:${body.state}`);
}
const details = integrationProvider.externalUrl
? await ioRedis.get(`external:${body.state}`)
: undefined;
if (details) {
await ioRedis.del(`external:${body.state}`);
}
const refresh = await ioRedis.get(`refresh:${body.state}`);
if (refresh) {
await ioRedis.del(`refresh:${body.state}`);
}
const onboarding = await ioRedis.get(`onboarding:${body.state}`);
if (onboarding) {
await ioRedis.del(`onboarding:${body.state}`);
}
const {
error,
accessToken,
expiresIn,
refreshToken,
id,
name,
picture,
username,
additionalSettings,
// eslint-disable-next-line no-async-promise-executor
} = await new Promise<AuthTokenDetails>(async (res) => {
try {
const auth = await integrationProvider.authenticate(
{
code: body.code,
codeVerifier: getCodeVerifier,
refresh: body.refresh,
},
details ? JSON.parse(details) : undefined
);
if (typeof auth === 'string') {
return res({
error: auth,
accessToken: '',
id: '',
name: '',
picture: '',
username: '',
additionalSettings: [],
});
}
if (refresh && integrationProvider.reConnect) {
console.log('reconnect');
try {
const newAuth = await integrationProvider.reConnect(
auth.id,
refresh,
auth.accessToken
);
return res({ ...newAuth, refreshToken: body.refresh });
} catch (err: any) {
return res({
error: err.message,
accessToken: '',
id: '',
name: '',
picture: '',
username: '',
additionalSettings: [],
});
}
}
return res(auth);
} catch (err) {
if (err instanceof NotEnoughScopes) {
return res({
error: err.message,
accessToken: '',
id: '',
name: '',
picture: '',
username: '',
additionalSettings: [],
});
}
return res({
error: 'Authentication failed',
accessToken: '',
id: '',
name: '',
picture: '',
username: '',
additionalSettings: [],
});
}
});
if (error) {
throw new NotEnoughScopes(error);
}
if (!id) {
throw new NotEnoughScopes('Invalid API key');
}
if (refresh && String(id) !== String(refresh)) {
throw new NotEnoughScopes(
'Please refresh the channel that needs to be refreshed'
);
}
let validName = name;
if (!validName) {
if (username) {
validName = username.split('.')[0] ?? username;
} else {
validName = `Channel_${String(id).slice(0, 8)}`;
}
}
if (
process.env.STRIPE_PUBLISHABLE_KEY &&
org.isTrailing &&
(await this._integrationService.checkPreviousConnections(
org.id,
String(id)
))
) {
throw new HttpException('', 412);
}
const createUpdate =
await this._integrationService.createOrUpdateIntegration(
additionalSettings,
!!integrationProvider.oneTimeToken,
org.id,
validName.trim(),
picture,
'social',
String(id),
integration,
accessToken,
refreshToken,
expiresIn,
username,
refresh ? false : integrationProvider.isBetweenSteps,
body.refresh,
+body.timezone,
details
? AuthService.fixedEncryption(details)
: integrationProvider.customFields
? AuthService.fixedEncryption(
Buffer.from(body.code, 'base64').toString()
)
: integrationProvider.isChromeExtension
? AuthService.signJWT(
JSON.parse(Buffer.from(body.code, 'base64').toString())
)
: undefined
);
this._refreshIntegrationService
.startRefreshWorkflow(org.id, createUpdate.id, integrationProvider)
.catch((err) => {
console.log(err);
});
// Fetch pages if this is a two-step provider and not a refresh
let pages: any[] = [];
if (integrationProvider.isBetweenSteps && !refresh) {
try {
// Check which method the provider uses (pages or companies)
const fetchMethod =
'pages' in integrationProvider
? 'pages'
: 'companies' in integrationProvider
? 'companies'
: null;
if (fetchMethod) {
// @ts-ignore - dynamic method call
pages = await integrationProvider[fetchMethod](accessToken);
}
} catch (err) {
console.log('Failed to fetch pages:', err);
}
}
const webhookUrl = await ioRedis.get(`webhookUrl:${body.state}`);
if (webhookUrl) {
try {
await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
params: AuthService.signJWT({
apiKey: org.apiKey,
}),
}),
});
} catch (err) {}
await ioRedis.del(`webhookUrl:${body.state}`);
}
const returnURL = await ioRedis.get(`redirect:${body.state}`);
if (returnURL) {
await ioRedis.del(`redirect:${body.state}`);
}
const extensionToken = integrationProvider.isChromeExtension
? AuthService.signJWT({
integrationId: createUpdate.id,
organizationId: org.id,
internalId: String(id),
provider: integration,
})
: undefined;
return {
...createUpdate,
onboarding: onboarding === 'true',
pages,
...(returnURL ? { returnURL } : {}),
...(extensionToken ? { extensionToken } : {}),
};
}
@Post('/public/provider/:id/connect')
async saveProviderPage(@Param('id') id: string, @Body() body: any) {
if (!body.state) {
throw new Error('Invalid state');
}
const organization = await ioRedis.get(`organization:${body.state}`);
if (!organization) {
throw new Error('Organization not found');
}
const org = await this._organizationService.getOrgById(organization);
return this._integrationService.saveProviderPage(org.id, id, body);
}
@Post('/extension-refresh')
async extensionRefreshCookies(
@Body() body: { jwt: string; cookies: string }
) {
let payload: any;
try {
payload = AuthService.verifyJWT(body.jwt);
} catch {
throw new HttpException('Invalid token', 401);
}
const { integrationId, organizationId, internalId, provider } = payload;
if (!integrationId || !organizationId || !internalId || !provider) {
throw new HttpException('Invalid token payload', 400);
}
const integration = await this._integrationService.getIntegrationById(
organizationId,
integrationId
);
if (!integration || integration.internalId !== internalId) {
throw new HttpException('Integration not found', 404);
}
const integrationProvider =
this._integrationManager.getSocialIntegration(provider);
if (!integrationProvider?.isChromeExtension) {
throw new HttpException('Not a Chrome extension integration', 400);
}
const authResult = await integrationProvider.authenticate({
code: body.cookies,
codeVerifier: '',
});
if (typeof authResult === 'string') {
throw new HttpException(authResult, 400);
}
if (String(authResult.id) !== String(integration.internalId)) {
await this._integrationService.refreshNeeded(
organizationId,
integrationId
);
return { success: false, reason: 'account_mismatch' };
}
await this._integrationService.createOrUpdateIntegration(
undefined,
false,
organizationId,
integration.name,
undefined,
'social',
integration.internalId,
integration.providerIdentifier,
authResult.accessToken,
'',
authResult.expiresIn,
undefined,
false,
undefined,
undefined,
AuthService.signJWT(
JSON.parse(Buffer.from(body.cookies, 'base64').toString())
)
);
return { success: true };
}
}
================================================
FILE: apps/backend/src/api/routes/notifications.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { Organization, User } from '@prisma/client';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { NotificationService } from '@gitroom/nestjs-libraries/database/prisma/notifications/notification.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Notifications')
@Controller('/notifications')
export class NotificationsController {
constructor(private _notificationsService: NotificationService) {}
@Get('/')
async mainPageList(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() organization: Organization
) {
return this._notificationsService.getMainPageCount(
organization.id,
user.id
);
}
@Get('/list')
async notifications(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() organization: Organization
) {
return this._notificationsService.getNotifications(
organization.id,
user.id
);
}
}
================================================
FILE: apps/backend/src/api/routes/oauth-app.controller.ts
================================================
import { Body, Controller, Delete, Get, Post, Put } from '@nestjs/common';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { ApiTags } from '@nestjs/swagger';
import { OAuthService } from '@gitroom/nestjs-libraries/database/prisma/oauth/oauth.service';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import {
AuthorizationActions,
Sections,
} from '@gitroom/backend/services/auth/permissions/permission.exception.class';
import { CreateOAuthAppDto } from '@gitroom/nestjs-libraries/dtos/oauth/create-oauth-app.dto';
import { UpdateOAuthAppDto } from '@gitroom/nestjs-libraries/dtos/oauth/update-oauth-app.dto';
@ApiTags('OAuth App')
@Controller('/user/oauth-app')
export class OAuthAppController {
constructor(private _oauthService: OAuthService) {}
@Get('/')
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
async getApp(@GetOrgFromRequest() org: Organization) {
return this._oauthService.getApp(org.id);
}
@Post('/')
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
async createApp(
@GetOrgFromRequest() org: Organization,
@Body() body: CreateOAuthAppDto
) {
return this._oauthService.createApp(org.id, body);
}
@Put('/')
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
async updateApp(
@GetOrgFromRequest() org: Organization,
@Body() body: UpdateOAuthAppDto
) {
return this._oauthService.updateApp(org.id, body);
}
@Delete('/')
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
async deleteApp(@GetOrgFromRequest() org: Organization) {
return this._oauthService.deleteApp(org.id);
}
@Post('/rotate-secret')
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
async rotateSecret(@GetOrgFromRequest() org: Organization) {
return this._oauthService.rotateSecret(org.id);
}
}
================================================
FILE: apps/backend/src/api/routes/oauth.controller.ts
================================================
import {
Body,
Controller,
Get,
HttpException,
HttpStatus,
Post,
Query,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { OAuthService } from '@gitroom/nestjs-libraries/database/prisma/oauth/oauth.service';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { User, Organization } from '@prisma/client';
import { AuthorizeOAuthQueryDto, ApproveOAuthDto } from '@gitroom/nestjs-libraries/dtos/oauth/authorize-oauth.dto';
import { TokenExchangeDto } from '@gitroom/nestjs-libraries/dtos/oauth/token-exchange.dto';
@ApiTags('OAuth')
@Controller('/oauth')
export class OAuthController {
constructor(private _oauthService: OAuthService) {}
@Get('/authorize')
async authorize(@Query() query: AuthorizeOAuthQueryDto) {
const app = await this._oauthService.validateAuthorizationRequest(
query.client_id
);
return {
app: {
name: app.name,
description: app.description,
picture: app.picture,
clientId: app.clientId,
redirectUrl: app.redirectUrl,
},
state: query.state,
};
}
@Post('/token')
async token(@Body() body: TokenExchangeDto) {
if (body.grant_type !== 'authorization_code') {
throw new HttpException(
{ error: 'unsupported_grant_type' },
HttpStatus.BAD_REQUEST
);
}
return this._oauthService.exchangeCodeForToken(
body.code,
body.client_id,
body.client_secret
);
}
}
@ApiTags('OAuth')
@Controller('/oauth')
export class OAuthAuthorizedController {
constructor(private _oauthService: OAuthService) {}
@Post('/authorize')
async approveOrDeny(
@Body() body: ApproveOAuthDto,
@GetUserFromRequest() user: User,
@GetOrgFromRequest() org: Organization
) {
const app = await this._oauthService.validateAuthorizationRequest(
body.client_id
);
if (body.action === 'deny') {
const redirectUrl = new URL(app.redirectUrl);
redirectUrl.searchParams.set('error', 'access_denied');
if (body.state) {
redirectUrl.searchParams.set('state', body.state);
}
return { redirect: redirectUrl.toString() };
}
const code = await this._oauthService.createAuthorizationCode(
app.id,
user.id,
org.id
);
const redirectUrl = new URL(app.redirectUrl);
redirectUrl.searchParams.set('code', code);
if (body.state) {
redirectUrl.searchParams.set('state', body.state);
}
return { redirect: redirectUrl.toString() };
}
}
================================================
FILE: apps/backend/src/api/routes/posts.controller.ts
================================================
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
Query,
Res,
} from '@nestjs/common';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization, User } from '@prisma/client';
import { GetPostsDto } from '@gitroom/nestjs-libraries/dtos/posts/get.posts.dto';
import { GetPostsListDto } from '@gitroom/nestjs-libraries/dtos/posts/get.posts.list.dto';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { ApiTags } from '@nestjs/swagger';
import { GeneratorDto } from '@gitroom/nestjs-libraries/dtos/generator/generator.dto';
import { CreateGeneratedPostsDto } from '@gitroom/nestjs-libraries/dtos/generator/create.generated.posts.dto';
import { AgentGraphService } from '@gitroom/nestjs-libraries/agent/agent.graph.service';
import { Response } from 'express';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { ShortLinkService } from '@gitroom/nestjs-libraries/short-linking/short.link.service';
import { CreateTagDto } from '@gitroom/nestjs-libraries/dtos/posts/create.tag.dto';
import {
AuthorizationActions,
Sections,
} from '@gitroom/backend/services/auth/permissions/permission.exception.class';
@ApiTags('Posts')
@Controller('/posts')
export class PostsController {
constructor(
private _postsService: PostsService,
private _agentGraphService: AgentGraphService,
private _shortLinkService: ShortLinkService
) {}
@Get('/:id/statistics')
async getStatistics(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._postsService.getStatistics(org.id, id);
}
@Get('/:id/missing')
async getMissingContent(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._postsService.getMissingContent(org.id, id);
}
@Put('/:id/release-id')
async updateReleaseId(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body('releaseId') releaseId: string
) {
return this._postsService.updateReleaseId(org.id, id, releaseId);
}
@Post('/should-shortlink')
async shouldShortlink(@Body() body: { messages: string[] }) {
return { ask: this._shortLinkService.askShortLinkedin(body.messages) };
}
@Post('/:id/comments')
async createComment(
@GetOrgFromRequest() org: Organization,
@GetUserFromRequest() user: User,
@Param('id') id: string,
@Body() body: { comment: string }
) {
return this._postsService.createComment(org.id, user.id, id, body.comment);
}
@Get('/tags')
async getTags(@GetOrgFromRequest() org: Organization) {
return { tags: await this._postsService.getTags(org.id) };
}
@Post('/tags')
async createTag(
@GetOrgFromRequest() org: Organization,
@Body() body: CreateTagDto
) {
return this._postsService.createTag(org.id, body);
}
@Put('/tags/:id')
async editTag(
@GetOrgFromRequest() org: Organization,
@Body() body: CreateTagDto,
@Param('id') id: string
) {
return this._postsService.editTag(id, org.id, body);
}
@Delete('/tags/:id')
async deleteTag(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._postsService.deleteTag(id, org.id);
}
@Get('/')
async getPosts(
@GetOrgFromRequest() org: Organization,
@Query() query: GetPostsDto
) {
return this._postsService.getPostsMinified(org.id, query);
}
@Get('/find-slot')
async findSlot(@GetOrgFromRequest() org: Organization) {
return { date: await this._postsService.findFreeDateTime(org.id) };
}
@Get('/find-slot/:id')
async findSlotIntegration(
@GetOrgFromRequest() org: Organization,
@Param('id') id?: string
) {
return { date: await this._postsService.findFreeDateTime(org.id, id) };
}
@Get('/list')
async getPostsList(
@GetOrgFromRequest() org: Organization,
@Query() query: GetPostsListDto
) {
return this._postsService.getPostsList(org.id, query);
}
@Get('/old')
oldPosts(
@GetOrgFromRequest() org: Organization,
@Query('date') date: string
) {
return this._postsService.getOldPosts(org.id, date);
}
@Get('/group/:group')
getPostsByGroup(@GetOrgFromRequest() org: Organization, @Param('group') group: string) {
return this._postsService.getPostsByGroup(org.id, group);
}
@Get('/:id')
getPost(@GetOrgFromRequest() org: Organization, @Param('id') id: string) {
return this._postsService.getPost(org.id, id);
}
@Post('/')
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
async createPost(
@GetOrgFromRequest() org: Organization,
@Body() rawBody: any
) {
console.log(JSON.stringify(rawBody, null, 2));
const body = await this._postsService.mapTypeToPost(rawBody, org.id);
return this._postsService.createPost(org.id, body);
}
@Post('/generator/draft')
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
generatePostsDraft(
@GetOrgFromRequest() org: Organization,
@Body() body: CreateGeneratedPostsDto
) {
return this._postsService.generatePostsDraft(org.id, body);
}
@Post('/generator')
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
async generatePosts(
@GetOrgFromRequest() org: Organization,
@Body() body: GeneratorDto,
@Res({ passthrough: false }) res: Response
) {
res.setHeader('Content-Type', 'application/json; charset=utf-8');
for await (const event of this._agentGraphService.start(org.id, body)) {
res.write(JSON.stringify(event) + '\n');
}
res.end();
}
@Delete('/:group')
deletePost(
@GetOrgFromRequest() org: Organization,
@Param('group') group: string
) {
return this._postsService.deletePost(org.id, group);
}
@Put('/:id/date')
changeDate(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body('date') date: string,
@Body('action') action: 'schedule' | 'update' = 'schedule'
) {
return this._postsService.changeDate(org.id, id, date, action);
}
@Post('/separate-posts')
async separatePosts(
@GetOrgFromRequest() org: Organization,
@Body() body: { content: string; len: number }
) {
return this._postsService.separatePosts(body.content, body.len);
}
}
================================================
FILE: apps/backend/src/api/routes/public.controller.ts
================================================
import {
Body,
Controller,
Get,
Param,
Post,
Query,
Req,
Res,
StreamableFile,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { AgenciesService } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.service';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
import { RealIP } from 'nestjs-real-ip';
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
import { Request, Response } from 'express';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management';
import { AgentGraphInsertService } from '@gitroom/nestjs-libraries/agent/agent.graph.insert.service';
import { Nowpayments } from '@gitroom/nestjs-libraries/crypto/nowpayments';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { AuthService } from '@gitroom/helpers/auth/auth.service';
import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing';
import { Readable, pipeline } from 'stream';
import { promisify } from 'util';
const pump = promisify(pipeline);
@ApiTags('Public')
@Controller('/public')
export class PublicController {
constructor(
private _agenciesService: AgenciesService,
private _trackService: TrackService,
private _agentGraphInsertService: AgentGraphInsertService,
private _postsService: PostsService,
private _nowpayments: Nowpayments,
private _subscriptionService: SubscriptionService
) {}
@Post('/agent')
async createAgent(@Body() body: { text: string; apiKey: string }) {
if (
!body.apiKey ||
!process.env.AGENT_API_KEY ||
body.apiKey !== process.env.AGENT_API_KEY
) {
return;
}
return this._agentGraphInsertService.newPost(body.text);
}
@Get('/agencies-list')
async getAgencyByUser() {
return this._agenciesService.getAllAgencies();
}
@Get('/agencies-list-slug')
async getAgencySlug() {
return this._agenciesService.getAllAgenciesSlug();
}
@Get('/agencies-information/:agency')
async getAgencyInformation(@Param('agency') agency: string) {
return this._agenciesService.getAgencyInformation(agency);
}
@Get('/agencies-list-count')
async getAgenciesCount() {
return this._agenciesService.getCount();
}
@Get(`/posts/:id`)
async getPreview(@Param('id') id: string) {
return (await this._postsService.getPostsRecursively(id, true)).map(
({ childrenPost, ...p }) => ({
...p,
...(p.integration
? {
integration: {
id: p.integration.id,
name: p.integration.name,
picture: p.integration.picture,
providerIdentifier: p.integration.providerIdentifier,
profile: p.integration.profile,
},
}
: {}),
})
);
}
@Get(`/posts/:id/comments`)
async getComments(@Param('id') postId: string) {
return { comments: await this._postsService.getComments(postId) };
}
@Post('/t')
async trackEvent(
@Res() res: Response,
@Req() req: Request,
@RealIP() ip: string,
@UserAgent() userAgent: string,
@Body()
body: { fbclid?: string; tt: TrackEnum; additional: Record<string, any> }
) {
const uniqueId = req?.cookies?.track || makeId(10);
const fbclid = req?.cookies?.fbclid || body.fbclid;
await this._trackService.track(
uniqueId,
ip,
userAgent,
body.tt,
body.additional,
fbclid
);
if (!req.cookies.track) {
res.cookie('track', uniqueId, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
}
: {}),
sameSite: 'none',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
}
if (body.fbclid && !req.cookies.fbclid) {
res.cookie('fbclid', body.fbclid, {
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
...(!process.env.NOT_SECURED
? {
secure: true,
httpOnly: true,
}
: {}),
sameSite: 'none',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
}
res.status(200).json({
track: uniqueId,
});
}
@Post('/modify-subscription')
async modifySubscription(@Body('params') params: string) {
try {
const load = AuthService.verifyJWT(params) as {
orgId: string;
billing: 'FREE' | 'STANDARD' | 'TEAM' | 'PRO' | 'ULTIMATE';
};
if (!load || !load.orgId || !load.billing || !pricing[load.billing]) {
return { success: false };
}
const totalChannels = pricing[load.billing].channel || 0;
await this._subscriptionService.modifySubscriptionByOrg(
load.orgId,
totalChannels,
load.billing
);
return { success: true };
} catch (err) {
return { success: false };
}
}
@Post('/crypto/:path')
async cryptoPost(@Body() body: any, @Param('path') path: string) {
console.log('cryptoPost', body, path);
return this._nowpayments.processPayment(path, body);
}
@Get('/stream')
async streamFile(
@Query('url') url: string,
@Res() res: Response,
@Req() req: Request
) {
if (!url.endsWith('mp4')) {
return res.status(400).send('Invalid video URL');
}
const ac = new AbortController();
const onClose = () => ac.abort();
req.on('aborted', onClose);
res.on('close', onClose);
const r = await fetch(url, { signal: ac.signal });
if (!r.ok && r.status !== 206) {
res.status(r.status);
throw new Error(`Upstream error: ${r.statusText}`);
}
const type = r.headers.get('content-type') ?? 'application/octet-stream';
res.setHeader('Content-Type', type);
const contentRange = r.headers.get('content-range');
if (contentRange) res.setHeader('Content-Range', contentRange);
const len = r.headers.get('content-length');
if (len) res.setHeader('Content-Length', len);
const acceptRanges = r.headers.get('accept-ranges') ?? 'bytes';
res.setHeader('Accept-Ranges', acceptRanges);
if (r.status === 206) res.status(206); // Partial Content for range responses
try {
await pump(Readable.fromWeb(r.body as any), res);
} catch (err) {
}
}
}
================================================
FILE: apps/backend/src/api/routes/root.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/')
export class RootController {
@Get('/')
getRoot(): string {
return 'App is running!';
}
}
================================================
FILE: apps/backend/src/api/routes/sets.controller.ts
================================================
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { ApiTags } from '@nestjs/swagger';
import { SetsService } from '@gitroom/nestjs-libraries/database/prisma/sets/sets.service';
import {
UpdateSetsDto,
SetsDto,
} from '@gitroom/nestjs-libraries/dtos/sets/sets.dto';
@ApiTags('Sets')
@Controller('/sets')
export class SetsController {
constructor(private _setsService: SetsService) {}
@Get('/')
async getSets(@GetOrgFromRequest() org: Organization) {
return this._setsService.getSets(org.id);
}
@Post('/')
async createASet(
@GetOrgFromRequest() org: Organization,
@Body() body: SetsDto
) {
return this._setsService.createSet(org.id, body);
}
@Put('/')
async updateSet(
@GetOrgFromRequest() org: Organization,
@Body() body: UpdateSetsDto
) {
return this._setsService.createSet(org.id, body);
}
@Delete('/:id')
async deleteSet(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._setsService.deleteSet(org.id, id);
}
}
================================================
FILE: apps/backend/src/api/routes/settings.controller.ts
================================================
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.service';
import { AddTeamMemberDto } from '@gitroom/nestjs-libraries/dtos/settings/add.team.member.dto';
import { ShortlinkPreferenceDto } from '@gitroom/nestjs-libraries/dtos/settings/shortlink-preference.dto';
import { ApiTags } from '@nestjs/swagger';
import { AuthorizationActions, Sections } from '@gitroom/backend/services/auth/permissions/permission.exception.class';
@ApiTags('Settings')
@Controller('/settings')
export class SettingsController {
constructor(
private _organizationService: OrganizationService
) {}
@Get('/team')
@CheckPolicies(
[AuthorizationActions.Create, Sections.TEAM_MEMBERS],
[AuthorizationActions.Create, Sections.ADMIN]
)
async getTeam(@GetOrgFromRequest() org: Organization) {
return this._organizationService.getTeam(org.id);
}
@Post('/team')
@CheckPolicies(
[AuthorizationActions.Create, Sections.TEAM_MEMBERS],
[AuthorizationActions.Create, Sections.ADMIN]
)
async inviteTeamMember(
@GetOrgFromRequest() org: Organization,
@Body() body: AddTeamMemberDto
) {
return this._organizationService.inviteTeamMember(org.id, body);
}
@Delete('/team/:id')
@CheckPolicies(
[AuthorizationActions.Create, Sections.TEAM_MEMBERS],
[AuthorizationActions.Create, Sections.ADMIN]
)
deleteTeamMember(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._organizationService.deleteTeamMember(org, id);
}
@Get('/shortlink')
async getShortlinkPreference(@GetOrgFromRequest() org: Organization) {
return this._organizationService.getShortlinkPreference(org.id);
}
@Post('/shortlink')
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
async updateShortlinkPreference(
@GetOrgFromRequest() org: Organization,
@Body() body: ShortlinkPreferenceDto
) {
return this._organizationService.updateShortlinkPreference(
org.id,
body.shortlink
);
}
}
================================================
FILE: apps/backend/src/api/routes/signature.controller.ts
================================================
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { ApiTags } from '@nestjs/swagger';
import { SignatureService } from '@gitroom/nestjs-libraries/database/prisma/signatures/signature.service';
import { SignatureDto } from '@gitroom/nestjs-libraries/dtos/signature/signature.dto';
@ApiTags('Signatures')
@Controller('/signatures')
export class SignatureController {
constructor(private _signatureService: SignatureService) {}
@Get('/')
async getSignatures(@GetOrgFromRequest() org: Organization) {
return this._signatureService.getSignaturesByOrgId(org.id);
}
@Get('/default')
async getDefaultSignature(@GetOrgFromRequest() org: Organization) {
return (await this._signatureService.getDefaultSignature(org.id)) || {};
}
@Post('/')
async createSignature(
@GetOrgFromRequest() org: Organization,
@Body() body: SignatureDto
) {
return this._signatureService.createOrUpdateSignature(org.id, body);
}
@Delete('/:id')
async deleteSignature(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string
) {
return this._signatureService.deleteSignature(org.id, id);
}
@Put('/:id')
async updateSignature(
@Param('id') id: string,
@GetOrgFromRequest() org: Organization,
@Body() body: SignatureDto
) {
return this._signatureService.createOrUpdateSignature(org.id, body, id);
}
}
================================================
FILE: apps/backend/src/api/routes/stripe.controller.ts
================================================
import {
Controller,
HttpException,
Post,
RawBodyRequest,
Req,
} from '@nestjs/common';
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Stripe')
@Controller('/stripe')
export class StripeController {
constructor(
private readonly _stripeService: StripeService,
) {}
@Post('/')
stripe(@Req() req: RawBodyRequest<Request>) {
const event = this._stripeService.validateRequest(
req.rawBody,
// @ts-ignore
req.headers['stripe-signature'],
process.env.STRIPE_SIGNING_KEY
);
// Maybe it comes from another stripe webhook
if (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
event?.data?.object?.metadata?.service !== 'gitroom' &&
event.type !== 'invoice.payment_succeeded'
) {
return { ok: true };
}
try {
switch (event.type) {
case 'invoice.payment_succeeded':
return this._stripeService.paymentSucceeded(event);
case 'customer.subscription.created':
return this._stripeService.createSubscription(event);
case 'customer.subscription.updated':
return this._stripeService.updateSubscription(event);
case 'customer.subscription.deleted':
return this._stripeService.deleteSubscription(event);
default:
return { ok: true };
}
} catch (e) {
throw new HttpException(e, 500);
}
}
}
================================================
FILE: apps/backend/src/api/routes/third-party.controller.ts
================================================
import {
Body,
Controller,
Get,
HttpException,
Param,
Post,
Delete,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { ThirdPartyManager } from '@gitroom/nestjs-libraries/3rdparties/thirdparty.manager';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { AuthService } from '@gitroom/helpers/auth/auth.service';
import { UploadFactory } from '@gitroom/nestjs-libraries/upload/upload.factory';
import { MediaService } from '@gitroom/nestjs-libraries/database/prisma/media/media.service';
@ApiTags('Third Party')
@Controller('/third-party')
export class ThirdPartyController {
private storage = UploadFactory.createStorage();
constructor(
private _thirdPartyManager: ThirdPartyManager,
private _mediaService: MediaService,
) {}
@Get('/list')
async getThirdPartyList() {
return this._thirdPartyManager.getAllThirdParties();
}
@Get('/')
async getSavedThirdParty(@GetOrgFromRequest() organization: Organization) {
return Promise.all(
(
await this._thirdPartyManager.getAllThirdPartiesByOrganization(
organization.id
)
).map((thirdParty) => {
const { description, fields, position, title, identifier } =
this._thirdPartyManager.getThirdPartyByName(thirdParty.identifier);
return {
...thirdParty,
title,
position,
fields,
description,
};
})
);
}
@Delete('/:id')
deleteById(
@GetOrgFromRequest() organization: Organization,
@Param('id') id: string
) {
return this._thirdPartyManager.deleteIntegration(organization.id, id);
}
@Post('/:id/submit')
async generate(
@GetOrgFromRequest() organization: Organization,
@Param('id') id: string,
@Body() data: any
) {
const thirdParty = await this._thirdPartyManager.getIntegrationById(
organization.id,
id
);
if (!thirdParty) {
throw new HttpException('Integration not found', 404);
}
const thirdPartyInstance = this._thirdPartyManager.getThirdPartyByName(
thirdParty.identifier
);
if (!thirdPartyInstance) {
throw new HttpException('Invalid identifier', 400);
}
const loadedData = await thirdPartyInstance?.instance?.sendData(
AuthService.fixedDecryption(thirdParty.apiKey),
data
);
const file = await this.storage.uploadSimple(loadedData);
return this._mediaService.saveFile(organization.id, file.split('/').pop(), file);
}
@Post('/function/:id/:functionName')
async callFunction(
@GetOrgFromRequest() organization: Organization,
@Param('id') id: string,
@Param('functionName') functionName: string,
@Body() data: any
) {
const thirdParty = await this._thirdPartyManager.getIntegrationById(
organization.id,
id
);
if (!thirdParty) {
throw new HttpException('Integration not found', 404);
}
const thirdPartyInstance = this._thirdPartyManager.getThirdPartyByName(
thirdParty.identifier
);
if (!thirdPartyInstance) {
throw new HttpException('Invalid identifier', 400);
}
return thirdPartyInstance?.instance?.[functionName](
AuthService.fixedDecryption(thirdParty.apiKey),
data
);
}
@Post('/:identifier')
async addApiKey(
@GetOrgFromRequest() organization: Organization,
@Param('identifier') identifier: string,
@Body('api') api: string
) {
const thirdParty = this._thirdPartyManager.getThirdPartyByName(identifier);
if (!thirdParty) {
throw new HttpException('Invalid identifier', 400);
}
const connect = await thirdParty.instance.checkConnection(api);
if (!connect) {
throw new HttpException('Invalid API key', 400);
}
try {
const save = await this._thirdPartyManager.saveIntegration(
organization.id,
identifier,
api,
{
name: connect.name,
username: connect.username,
id: connect.id,
}
);
return {
id: save.id,
};
} catch (e) {
console.log(e);
throw new HttpException('Integration Already Exists', 400);
}
}
}
================================================
FILE: apps/backend/src/api/routes/users.controller.ts
================================================
import {
Body,
Controller,
Get,
HttpException,
Post,
Query,
Req,
Res,
} from '@nestjs/common';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { sign } from 'jsonwebtoken';
import { Organization, User } from '@prisma/client';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
import { Response, Request } from 'express';
import { AuthService } from '@gitroom/backend/services/auth/auth.service';
import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.service';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management';
import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing';
import { ApiTags } from '@nestjs/swagger';
import { UsersService } from '@gitroom/nestjs-libraries/database/prisma/users/users.service';
import { UserDetailDto } from '@gitroom/nestjs-libraries/dtos/users/user.details.dto';
import { EmailNotificationsDto } from '@gitroom/nestjs-libraries/dtos/users/email-notifications.dto';
import { HttpForbiddenException } from '@gitroom/nestjs-libraries/services/exception.filter';
import { RealIP } from 'nestjs-real-ip';
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
import { AuthorizationActions, Sections } from '@gitroom/backend/services/auth/permissions/permission.exception.class';
@ApiTags('User')
@Controller('/user')
export class UsersController {
constructor(
private _subscriptionService: SubscriptionService,
private _stripeService: StripeService,
private _authService: AuthService,
private _orgService: OrganizationService,
private _userService: UsersService,
private _trackService: TrackService
) {}
@Get('/agent-media-sso')
async getAgentMediaSsoUrl(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() organization: Organization
) {
if (!process.env.AGENT_MEDIA_SSO_KEY) {
throw new HttpException('Agent Media SSO is not configured', 400);
}
const token = sign(
{ id: organization.id, displayName: organization.name },
process.env.AGENT_MEDIA_SSO_KEY
);
return { url: `https://agent-media.ai/sso/${token}` };
}
@Get('/self')
async getSelf(
@GetUserFromRequest() user: User,
@GetOrgFromRequest() organization: Organization,
@Req() req: Request
) {
if (!organization) {
throw new HttpForbiddenException();
}
const impersonate = req.cookies.impersonate || req.headers.impersonate;
// @ts-ignore
return {
...user,
orgId: organization.id,
// @ts-ignore
totalChannels: !process.env.STRIPE_PUBLISHABLE_KEY ? 10000 : organization?.subscription?.totalChannels || pricing.FREE.channel,
// @ts-ignore
tier: organization?.subscription?.subscriptionTier || (!process.env.STRIPE_PUBLISHABLE_KEY ? 'ULTIMATE' : 'FREE'),
// @ts-ignore
role: organization?.users[0]?.role,
// @ts-ignore
isLifetime: !!organization?.subscription?.isLifetime,
admin: !!user.isSuperAdmin,
impersonate: !!impersonate,
isTrailing: !process.env.STRIPE_PUBLISHABLE_KEY ? false : organization?.isTrailing,
allowTrial: organization?.allowTrial,
streakSince: organization?.streakSince || null,
// @ts-ignore
publicApi: organization?.users[0]?.role === 'SUPERADMIN' || organization?.users[0]?.role === 'ADMIN' ? organization?.apiKey : '',
};
}
@Get('/personal')
async getPersonalInformation(@GetUserFromRequest() user: User) {
return this._userService.getPersonal(user.id);
}
@Get('/impersonate')
async getImpersonate(
@GetUserFromRequest() user: User,
@Query('name') name: string
) {
if (!user.isSuperAdmin) {
throw new HttpException('Unauthorized', 400);
}
return this._userService.getImpersonateUser(name);
}
@Post('/impersonate')
async setImpersonate(
@GetUserFromRequest() user: User,
@Body('id') id: string,
@Res({ passthrough: true }) response: Response
) {
if (!user.isSuperAd
gitextract_ft7oghrf/ ├── .coderabbit.yaml ├── .devcontainer/ │ └── devcontainer.json ├── .dockerignore ├── .eslintignore ├── .github/ │ ├── Dependabot.yml │ ├── FUNDING.yaml │ ├── ISSUE_TEMPLATE/ │ │ ├── 01_bug_report.yml │ │ ├── 02_feature_request.yml │ │ └── config.yml │ ├── PULL_REQUEST_TEMPLATE.md │ ├── copilot-instructions.md │ └── workflows/ │ ├── build-containers.yml │ ├── build-extension.yaml │ ├── build.yml │ ├── codeql.yml │ ├── eslint │ ├── issue-label-triggers.yml │ ├── pr-docker-build.yml │ ├── pr-quality.yml │ ├── publish-extension.yml │ └── stale.yml ├── .gitignore ├── .gitmodules ├── .npmrc ├── .prettierignore ├── .prettierrc ├── CLAUDE.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile.dev ├── Jenkins/ │ ├── Build.Jenkinsfile │ └── BuildPR.Jenkinsfile ├── LICENSE ├── README.md ├── SECURITY.md ├── apps/ │ ├── backend/ │ │ ├── .gitignore │ │ ├── nest-cli.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── api/ │ │ │ │ ├── api.module.ts │ │ │ │ └── routes/ │ │ │ │ ├── analytics.controller.ts │ │ │ │ ├── approved-apps.controller.ts │ │ │ │ ├── auth.controller.ts │ │ │ │ ├── autopost.controller.ts │ │ │ │ ├── billing.controller.ts │ │ │ │ ├── copilot.controller.ts │ │ │ │ ├── enterprise.controller.ts │ │ │ │ ├── integrations.controller.ts │ │ │ │ ├── media.controller.ts │ │ │ │ ├── monitor.controller.ts │ │ │ │ ├── no.auth.integrations.controller.ts │ │ │ │ ├── notifications.controller.ts │ │ │ │ ├── oauth-app.controller.ts │ │ │ │ ├── oauth.controller.ts │ │ │ │ ├── posts.controller.ts │ │ │ │ ├── public.controller.ts │ │ │ │ ├── root.controller.ts │ │ │ │ ├── sets.controller.ts │ │ │ │ ├── settings.controller.ts │ │ │ │ ├── signature.controller.ts │ │ │ │ ├── stripe.controller.ts │ │ │ │ ├── third-party.controller.ts │ │ │ │ ├── users.controller.ts │ │ │ │ └── webhooks.controller.ts │ │ │ ├── app.module.ts │ │ │ ├── assets/ │ │ │ │ └── .gitkeep │ │ │ ├── main.ts │ │ │ ├── public-api/ │ │ │ │ ├── public.api.module.ts │ │ │ │ └── routes/ │ │ │ │ └── v1/ │ │ │ │ └── public.integrations.controller.ts │ │ │ └── services/ │ │ │ └── auth/ │ │ │ ├── auth.middleware.ts │ │ │ ├── auth.service.ts │ │ │ ├── permissions/ │ │ │ │ ├── permission.exception.class.ts │ │ │ │ ├── permissions.ability.ts │ │ │ │ ├── permissions.guard.ts │ │ │ │ ├── permissions.service.ts │ │ │ │ └── subscription.exception.ts │ │ │ ├── providers/ │ │ │ │ ├── farcaster.provider.ts │ │ │ │ ├── github.provider.ts │ │ │ │ ├── google.provider.ts │ │ │ │ ├── oauth.provider.ts │ │ │ │ ├── providers.manager.ts │ │ │ │ └── wallet.provider.ts │ │ │ ├── providers.interface.ts │ │ │ └── public.auth.middleware.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── cli/ │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── FEATURES.md │ │ ├── HOW_TO_RUN.md │ │ ├── INTEGRATION_SETTINGS_DISCOVERY.md │ │ ├── INTEGRATION_TOOLS_WORKFLOW.md │ │ ├── PROJECT_STRUCTURE.md │ │ ├── PROVIDER_SETTINGS.md │ │ ├── PROVIDER_SETTINGS_SUMMARY.md │ │ ├── PUBLISHING.md │ │ ├── QUICK_START.md │ │ ├── README.md │ │ ├── SKILL.md │ │ ├── SUMMARY.md │ │ ├── SUPPORTED_FILE_TYPES.md │ │ ├── SYNTAX_UPGRADE.md │ │ ├── examples/ │ │ │ ├── COMMAND_LINE_GUIDE.md │ │ │ ├── EXAMPLES.md │ │ │ ├── ai-agent-example.js │ │ │ ├── basic-usage.sh │ │ │ ├── command-line-examples.sh │ │ │ ├── multi-platform-post.json │ │ │ ├── multi-platform-with-settings.json │ │ │ ├── post-with-comments.json │ │ │ ├── reddit-post.json │ │ │ ├── thread-post.json │ │ │ ├── tiktok-video.json │ │ │ └── youtube-video.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── api.ts │ │ │ ├── commands/ │ │ │ │ ├── integrations.ts │ │ │ │ ├── posts.ts │ │ │ │ └── upload.ts │ │ │ ├── config.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── commands/ │ │ ├── .gitignore │ │ ├── nest-cli.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── command.module.ts │ │ │ ├── main.ts │ │ │ └── tasks/ │ │ │ ├── agent.run.ts │ │ │ ├── configuration.ts │ │ │ └── refresh.tokens.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── extension/ │ │ ├── .gitignore │ │ ├── custom-vite-plugins.ts │ │ ├── manifest.dev.json │ │ ├── manifest.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── background.ts │ │ │ ├── providers/ │ │ │ │ ├── cookie-provider.interface.ts │ │ │ │ ├── list/ │ │ │ │ │ └── skool.provider.ts │ │ │ │ └── provider.registry.ts │ │ │ └── types/ │ │ │ └── messages.ts │ │ ├── tsconfig.json │ │ ├── vite.config.base.ts │ │ ├── vite.config.chrome.ts │ │ └── vite.config.ts │ ├── frontend/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── next.config.js │ │ ├── package.json │ │ ├── postcss.config.mjs │ │ ├── public/ │ │ │ ├── .gitkeep │ │ │ └── f.js │ │ ├── src/ │ │ │ ├── app/ │ │ │ │ ├── (app)/ │ │ │ │ │ ├── (preview)/ │ │ │ │ │ │ └── p/ │ │ │ │ │ │ └── [id]/ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── (site)/ │ │ │ │ │ │ ├── agents/ │ │ │ │ │ │ │ ├── [id]/ │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── analytics/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── billing/ │ │ │ │ │ │ │ ├── lifetime/ │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── err/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── launches/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── plugs/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── settings/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── third-party/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── api/ │ │ │ │ │ │ └── uploads/ │ │ │ │ │ │ └── [[...path]]/ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── auth/ │ │ │ │ │ │ ├── activate/ │ │ │ │ │ │ │ ├── [code]/ │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── forgot/ │ │ │ │ │ │ │ ├── [token]/ │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── login/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── login-required/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ └── return.url.component.tsx │ │ │ │ │ ├── integrations/ │ │ │ │ │ │ └── social/ │ │ │ │ │ │ ├── [provider]/ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── layout.tsx │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── oauth/ │ │ │ │ │ └── authorize/ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── page.tsx │ │ │ │ ├── (extension)/ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── modal/ │ │ │ │ │ ├── [style]/ │ │ │ │ │ │ └── [platform]/ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ └── layout.tsx │ │ │ │ ├── colors.scss │ │ │ │ ├── global-error.tsx │ │ │ │ ├── global.scss │ │ │ │ └── polonto.css │ │ │ ├── chrome.d.ts │ │ │ ├── components/ │ │ │ │ ├── agents/ │ │ │ │ │ ├── agent.chat.tsx │ │ │ │ │ ├── agent.input.tsx │ │ │ │ │ ├── agent.textarea.tsx │ │ │ │ │ └── agent.tsx │ │ │ │ ├── analytics/ │ │ │ │ │ ├── analytics.component.tsx │ │ │ │ │ ├── chart-social.tsx │ │ │ │ │ ├── chart.tsx │ │ │ │ │ ├── stars.and.forks.interface.ts │ │ │ │ │ ├── stars.and.forks.tsx │ │ │ │ │ └── stars.table.component.tsx │ │ │ │ ├── approved-apps/ │ │ │ │ │ └── approved-apps.component.tsx │ │ │ │ ├── auth/ │ │ │ │ │ ├── activate.tsx │ │ │ │ │ ├── after.activate.tsx │ │ │ │ │ ├── forgot-return.tsx │ │ │ │ │ ├── forgot.tsx │ │ │ │ │ ├── login.tsx │ │ │ │ │ ├── login.with.oidc.tsx │ │ │ │ │ ├── nayner.auth.button.tsx │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── farcaster.provider.tsx │ │ │ │ │ │ ├── github.provider.tsx │ │ │ │ │ │ ├── google.provider.tsx │ │ │ │ │ │ ├── oauth.provider.tsx │ │ │ │ │ │ ├── placeholder/ │ │ │ │ │ │ │ └── wallet.ui.provider.tsx │ │ │ │ │ │ └── wallet.provider.tsx │ │ │ │ │ ├── register.tsx │ │ │ │ │ ├── testimonial.component.tsx │ │ │ │ │ └── testimonial.tsx │ │ │ │ ├── autopost/ │ │ │ │ │ └── autopost.tsx │ │ │ │ ├── billing/ │ │ │ │ │ ├── billing.component.tsx │ │ │ │ │ ├── embedded.billing.tsx │ │ │ │ │ ├── faq.component.tsx │ │ │ │ │ ├── finish.trial.tsx │ │ │ │ │ ├── first.billing.component.tsx │ │ │ │ │ ├── lifetime.deal.tsx │ │ │ │ │ ├── main.billing.component.tsx │ │ │ │ │ └── purchase.crypto.tsx │ │ │ │ ├── developer/ │ │ │ │ │ └── developer.component.tsx │ │ │ │ ├── launches/ │ │ │ │ │ ├── add.provider.component.tsx │ │ │ │ │ ├── ai.image.tsx │ │ │ │ │ ├── ai.video.tsx │ │ │ │ │ ├── bot.picture.tsx │ │ │ │ │ ├── calendar.context.tsx │ │ │ │ │ ├── calendar.tsx │ │ │ │ │ ├── comments/ │ │ │ │ │ │ └── comment.component.tsx │ │ │ │ │ ├── continue.integration.tsx │ │ │ │ │ ├── customer.modal.tsx │ │ │ │ │ ├── filters.tsx │ │ │ │ │ ├── general.preview.component.tsx │ │ │ │ │ ├── generator/ │ │ │ │ │ │ └── generator.tsx │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ ├── date.picker.tsx │ │ │ │ │ │ ├── dnd.provider.tsx │ │ │ │ │ │ ├── isuscitizen.utils.tsx │ │ │ │ │ │ ├── linkedin.component.tsx │ │ │ │ │ │ ├── media.settings.component.tsx │ │ │ │ │ │ ├── pick.platform.component.tsx │ │ │ │ │ │ ├── top.title.component.tsx │ │ │ │ │ │ ├── use.custom.provider.function.ts │ │ │ │ │ │ ├── use.existing.data.tsx │ │ │ │ │ │ ├── use.expend.tsx │ │ │ │ │ │ ├── use.formatting.ts │ │ │ │ │ │ ├── use.hide.top.editor.tsx │ │ │ │ │ │ ├── use.integration.list.tsx │ │ │ │ │ │ ├── use.integration.ts │ │ │ │ │ │ ├── use.move.to.integration.tsx │ │ │ │ │ │ └── use.values.ts │ │ │ │ │ ├── information.component.tsx │ │ │ │ │ ├── integration.redirect.component.tsx │ │ │ │ │ ├── internal.channels.tsx │ │ │ │ │ ├── launches.component.tsx │ │ │ │ │ ├── layout.standalone.tsx │ │ │ │ │ ├── menu/ │ │ │ │ │ │ └── menu.tsx │ │ │ │ │ ├── merge.post.tsx │ │ │ │ │ ├── missing-release.modal.tsx │ │ │ │ │ ├── new.post.tsx │ │ │ │ │ ├── polonto/ │ │ │ │ │ │ └── polonto.picture.generation.tsx │ │ │ │ │ ├── polonto.tsx │ │ │ │ │ ├── repeat.component.tsx │ │ │ │ │ ├── select.customer.tsx │ │ │ │ │ ├── separate.post.tsx │ │ │ │ │ ├── settings.modal.tsx │ │ │ │ │ ├── statistics.tsx │ │ │ │ │ ├── tags.component.tsx │ │ │ │ │ ├── time.table.tsx │ │ │ │ │ ├── up.down.arrow.tsx │ │ │ │ │ └── web3/ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── moltbook.provider.tsx │ │ │ │ │ │ ├── telegram.provider.tsx │ │ │ │ │ │ └── wrapcaster.provider.tsx │ │ │ │ │ ├── web3.list.tsx │ │ │ │ │ └── web3.provider.interface.ts │ │ │ │ ├── layout/ │ │ │ │ │ ├── check.payment.tsx │ │ │ │ │ ├── chrome.extension.component.tsx │ │ │ │ │ ├── click.outside.tsx │ │ │ │ │ ├── continue.provider.tsx │ │ │ │ │ ├── drop.files.tsx │ │ │ │ │ ├── dubAnalytics.tsx │ │ │ │ │ ├── facebook.component.tsx │ │ │ │ │ ├── html.component.tsx │ │ │ │ │ ├── impersonate.tsx │ │ │ │ │ ├── language.component.tsx │ │ │ │ │ ├── layout.context.tsx │ │ │ │ │ ├── loading.tsx │ │ │ │ │ ├── logout.component.tsx │ │ │ │ │ ├── mode.component.tsx │ │ │ │ │ ├── new-modal.tsx │ │ │ │ │ ├── new.subscription.tsx │ │ │ │ │ ├── organization.selector.tsx │ │ │ │ │ ├── pre-condition.component.tsx │ │ │ │ │ ├── redirect.tsx │ │ │ │ │ ├── sentry.component.tsx │ │ │ │ │ ├── set.timezone.tsx │ │ │ │ │ ├── settings.component.tsx │ │ │ │ │ ├── streak.component.tsx │ │ │ │ │ ├── support.tsx │ │ │ │ │ ├── title.tsx │ │ │ │ │ ├── top.menu.tsx │ │ │ │ │ ├── top.tip.tsx │ │ │ │ │ └── user.context.tsx │ │ │ │ ├── media/ │ │ │ │ │ ├── media.component.tsx │ │ │ │ │ └── new.uploader.tsx │ │ │ │ ├── new-launch/ │ │ │ │ │ ├── a.component.tsx │ │ │ │ │ ├── add.edit.modal.tsx │ │ │ │ │ ├── add.post.button.tsx │ │ │ │ │ ├── bold.text.tsx │ │ │ │ │ ├── bullets.component.tsx │ │ │ │ │ ├── delay.component.tsx │ │ │ │ │ ├── dummy.code.component.tsx │ │ │ │ │ ├── editor.tsx │ │ │ │ │ ├── finisher/ │ │ │ │ │ │ └── thread.finisher.tsx │ │ │ │ │ ├── heading.component.tsx │ │ │ │ │ ├── manage.modal.tsx │ │ │ │ │ ├── mention.component.tsx │ │ │ │ │ ├── modal.wrapper.component.tsx │ │ │ │ │ ├── picks.socials.component.tsx │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── bluesky/ │ │ │ │ │ │ │ └── bluesky.provider.tsx │ │ │ │ │ │ ├── continue-provider/ │ │ │ │ │ │ │ ├── facebook/ │ │ │ │ │ │ │ │ └── facebook.continue.tsx │ │ │ │ │ │ │ ├── gmb/ │ │ │ │ │ │ │ │ └── gmb.continue.tsx │ │ │ │ │ │ │ ├── instagram/ │ │ │ │ │ │ │ │ └── instagram.continue.tsx │ │ │ │ │ │ │ ├── linkedin/ │ │ │ │ │ │ │ │ └── linkedin.continue.tsx │ │ │ │ │ │ │ ├── list.tsx │ │ │ │ │ │ │ ├── with-continue-provider.tsx │ │ │ │ │ │ │ └── youtube/ │ │ │ │ │ │ │ └── youtube.continue.tsx │ │ │ │ │ │ ├── devto/ │ │ │ │ │ │ │ ├── devto.provider.tsx │ │ │ │ │ │ │ ├── devto.tags.tsx │ │ │ │ │ │ │ └── select.organization.tsx │ │ │ │ │ │ ├── discord/ │ │ │ │ │ │ │ ├── discord.channel.select.tsx │ │ │ │ │ │ │ └── discord.provider.tsx │ │ │ │ │ │ ├── dribbble/ │ │ │ │ │ │ │ ├── dribbble.provider.tsx │ │ │ │ │ │ │ └── dribbble.teams.tsx │ │ │ │ │ │ ├── facebook/ │ │ │ │ │ │ │ ├── facebook.preview.tsx │ │ │ │ │ │ │ └── facebook.provider.tsx │ │ │ │ │ │ ├── gmb/ │ │ │ │ │ │ │ └── gmb.provider.tsx │ │ │ │ │ │ ├── hashnode/ │ │ │ │ │ │ │ ├── hashnode.provider.tsx │ │ │ │ │ │ │ ├── hashnode.publications.tsx │ │ │ │ │ │ │ └── hashnode.tags.tsx │ │ │ │ │ │ ├── high.order.provider.tsx │ │ │ │ │ │ ├── instagram/ │ │ │ │ │ │ │ ├── instagram.collaborators.tsx │ │ │ │ │ │ │ ├── instagram.preview.tsx │ │ │ │ │ │ │ └── instagram.tags.tsx │ │ │ │ │ │ ├── kick/ │ │ │ │ │ │ │ └── kick.provider.tsx │ │ │ │ │ │ ├── lemmy/ │ │ │ │ │ │ │ ├── lemmy.provider.tsx │ │ │ │ │ │ │ └── subreddit.tsx │ │ │ │ │ │ ├── linkedin/ │ │ │ │ │ │ │ ├── linkedin.preview.tsx │ │ │ │ │ │ │ └── linkedin.provider.tsx │ │ │ │ │ │ ├── listmonk/ │ │ │ │ │ │ │ ├── listmonk.provider.tsx │ │ │ │ │ │ │ ├── select.list.tsx │ │ │ │ │ │ │ └── select.templates.tsx │ │ │ │ │ │ ├── mastodon/ │ │ │ │ │ │ │ └── mastodon.provider.tsx │ │ │ │ │ │ ├── medium/ │ │ │ │ │ │ │ ├── fonts/ │ │ │ │ │ │ │ │ └── stylesheet.css │ │ │ │ │ │ │ ├── medium.provider.tsx │ │ │ │ │ │ │ ├── medium.publications.tsx │ │ │ │ │ │ │ └── medium.tags.tsx │ │ │ │ │ │ ├── mewe/ │ │ │ │ │ │ │ ├── mewe.group.select.tsx │ │ │ │ │ │ │ └── mewe.provider.tsx │ │ │ │ │ │ ├── moltbook/ │ │ │ │ │ │ │ └── moltbook.provider.tsx │ │ │ │ │ │ ├── nostr/ │ │ │ │ │ │ │ └── nostr.provider.tsx │ │ │ │ │ │ ├── pinterest/ │ │ │ │ │ │ │ ├── pinterest.board.tsx │ │ │ │ │ │ │ ├── pinterest.preview.tsx │ │ │ │ │ │ │ └── pinterest.provider.tsx │ │ │ │ │ │ ├── reddit/ │ │ │ │ │ │ │ ├── reddit.provider.tsx │ │ │ │ │ │ │ └── subreddit.tsx │ │ │ │ │ │ ├── show.all.providers.tsx │ │ │ │ │ │ ├── skool/ │ │ │ │ │ │ │ ├── skool.group.select.tsx │ │ │ │ │ │ │ ├── skool.label.select.tsx │ │ │ │ │ │ │ └── skool.provider.tsx │ │ │ │ │ │ ├── slack/ │ │ │ │ │ │ │ ├── slack.channel.select.tsx │ │ │ │ │ │ │ └── slack.provider.tsx │ │ │ │ │ │ ├── telegram/ │ │ │ │ │ │ │ └── telegram.provider.tsx │ │ │ │ │ │ ├── threads/ │ │ │ │ │ │ │ └── threads.provider.tsx │ │ │ │ │ │ ├── tiktok/ │ │ │ │ │ │ │ ├── tiktok.preview.tsx │ │ │ │ │ │ │ └── tiktok.provider.tsx │ │ │ │ │ │ ├── twitch/ │ │ │ │ │ │ │ └── twitch.provider.tsx │ │ │ │ │ │ ├── vk/ │ │ │ │ │ │ │ └── vk.provider.tsx │ │ │ │ │ │ ├── warpcast/ │ │ │ │ │ │ │ ├── subreddit.tsx │ │ │ │ │ │ │ └── warpcast.provider.tsx │ │ │ │ │ │ ├── whop/ │ │ │ │ │ │ │ ├── whop.company.select.tsx │ │ │ │ │ │ │ ├── whop.experience.select.tsx │ │ │ │ │ │ │ └── whop.provider.tsx │ │ │ │ │ │ ├── wordpress/ │ │ │ │ │ │ │ ├── wordpress.post.type.tsx │ │ │ │ │ │ │ └── wordpress.provider.tsx │ │ │ │ │ │ ├── x/ │ │ │ │ │ │ │ └── x.provider.tsx │ │ │ │ │ │ └── youtube/ │ │ │ │ │ │ ├── youtube.preview.tsx │ │ │ │ │ │ └── youtube.provider.tsx │ │ │ │ │ ├── select.current.tsx │ │ │ │ │ ├── store.ts │ │ │ │ │ └── u.text.tsx │ │ │ │ ├── new-layout/ │ │ │ │ │ ├── billing.after.tsx │ │ │ │ │ ├── layout.component.tsx │ │ │ │ │ ├── layout.media.component.tsx │ │ │ │ │ ├── logo.tsx │ │ │ │ │ ├── menu-item.tsx │ │ │ │ │ └── sentry.feedback.component.tsx │ │ │ │ ├── notifications/ │ │ │ │ │ └── notification.component.tsx │ │ │ │ ├── onboarding/ │ │ │ │ │ ├── github.onboarding.tsx │ │ │ │ │ ├── onboarding.modal.tsx │ │ │ │ │ └── onboarding.tsx │ │ │ │ ├── platform-analytics/ │ │ │ │ │ ├── platform.analytics.tsx │ │ │ │ │ └── render.analytics.tsx │ │ │ │ ├── plugs/ │ │ │ │ │ ├── plug.tsx │ │ │ │ │ ├── plugs.context.ts │ │ │ │ │ └── plugs.tsx │ │ │ │ ├── post-url-selector/ │ │ │ │ │ └── post.url.selector.tsx │ │ │ │ ├── preview/ │ │ │ │ │ ├── comments.components.tsx │ │ │ │ │ ├── copy.client.tsx │ │ │ │ │ ├── preview.wrapper.tsx │ │ │ │ │ └── render.preview.date.tsx │ │ │ │ ├── public-api/ │ │ │ │ │ └── public.component.tsx │ │ │ │ ├── sets/ │ │ │ │ │ └── sets.tsx │ │ │ │ ├── settings/ │ │ │ │ │ ├── email-notifications.component.tsx │ │ │ │ │ ├── github.component.tsx │ │ │ │ │ ├── global.settings.tsx │ │ │ │ │ ├── metric.component.tsx │ │ │ │ │ ├── shortlink-preference.component.tsx │ │ │ │ │ ├── signatures.component.tsx │ │ │ │ │ └── teams.component.tsx │ │ │ │ ├── signature.tsx │ │ │ │ ├── standalone-modal/ │ │ │ │ │ └── standalone.modal.tsx │ │ │ │ ├── third-parties/ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ └── heygen.provider.tsx │ │ │ │ │ ├── slider.component.tsx │ │ │ │ │ ├── third-party.component.tsx │ │ │ │ │ ├── third-party.function.tsx │ │ │ │ │ ├── third-party.list.component.tsx │ │ │ │ │ ├── third-party.media.tsx │ │ │ │ │ └── third-party.wrapper.tsx │ │ │ │ ├── ui/ │ │ │ │ │ ├── check.icon.component.tsx │ │ │ │ │ ├── icons/ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── is.scroll.hook.tsx │ │ │ │ │ ├── logo-text.component.tsx │ │ │ │ │ └── translated-label.tsx │ │ │ │ ├── videos/ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── image-text-slides.provider.tsx │ │ │ │ │ │ └── veo3.provider.tsx │ │ │ │ │ ├── video.context.wrapper.tsx │ │ │ │ │ ├── video.render.component.tsx │ │ │ │ │ └── video.wrapper.tsx │ │ │ │ └── webhooks/ │ │ │ │ └── webhooks.tsx │ │ │ ├── instrumentation.ts │ │ │ ├── middleware.ts │ │ │ ├── sentry.edge.config.ts │ │ │ └── sentry.server.config.ts │ │ ├── tailwind.config.js │ │ └── tsconfig.json │ ├── orchestrator/ │ │ ├── .gitignore │ │ ├── .swcrc │ │ ├── nest-cli.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── activities/ │ │ │ │ ├── autopost.activity.ts │ │ │ │ ├── email.activity.ts │ │ │ │ ├── integrations.activity.ts │ │ │ │ └── post.activity.ts │ │ │ ├── app.module.ts │ │ │ ├── main.ts │ │ │ ├── signals/ │ │ │ │ ├── email.signal.ts │ │ │ │ └── send.email.signal.ts │ │ │ └── workflows/ │ │ │ ├── autopost.workflow.ts │ │ │ ├── digest.email.workflow.ts │ │ │ ├── index.ts │ │ │ ├── missing.post.workflow.ts │ │ │ ├── post-workflows/ │ │ │ │ └── post.workflow.v1.0.1.ts │ │ │ ├── refresh.token.workflow.ts │ │ │ ├── send.email.workflow.ts │ │ │ └── streak.workflow.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ └── sdk/ │ ├── .babelrc │ ├── .npmignore │ ├── README.md │ ├── package.json │ ├── src/ │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── docker-compose.dev.yaml ├── docker-compose.yaml ├── dynamicconfig/ │ ├── development-cass.yaml │ └── development-sql.yaml ├── eslint.config.mjs ├── i18n.json ├── jest.config.ts ├── jest.preset.js ├── libraries/ │ ├── helpers/ │ │ └── src/ │ │ ├── auth/ │ │ │ └── auth.service.ts │ │ ├── configuration/ │ │ │ └── configuration.checker.ts │ │ ├── decorators/ │ │ │ ├── plug.decorator.ts │ │ │ └── post.plug.ts │ │ ├── subdomain/ │ │ │ ├── all.two.level.subdomain.ts │ │ │ └── subdomain.management.ts │ │ ├── swagger/ │ │ │ └── load.swagger.ts │ │ └── utils/ │ │ ├── count.length.ts │ │ ├── custom.fetch.func.ts │ │ ├── custom.fetch.tsx │ │ ├── internal.fetch.ts │ │ ├── is.dev.ts │ │ ├── is.general.server.side.ts │ │ ├── linkedin.company.prevent.remove.ts │ │ ├── posts.list.minify.ts │ │ ├── read.or.fetch.ts │ │ ├── remove.markdown.ts │ │ ├── strip.html.validation.ts │ │ ├── timer.ts │ │ ├── use.fire.events.ts │ │ ├── use.wait.for.class.tsx │ │ ├── utm.saver.tsx │ │ ├── valid.images.ts │ │ └── valid.url.path.ts │ ├── nestjs-libraries/ │ │ ├── .eslintrc.json │ │ ├── README.md │ │ ├── src/ │ │ │ ├── 3rdparties/ │ │ │ │ ├── heygen/ │ │ │ │ │ └── heygen.provider.ts │ │ │ │ ├── thirdparty.interface.ts │ │ │ │ ├── thirdparty.manager.ts │ │ │ │ └── thirdparty.module.ts │ │ │ ├── agent/ │ │ │ │ ├── agent.categories.ts │ │ │ │ ├── agent.graph.insert.service.ts │ │ │ │ ├── agent.graph.service.ts │ │ │ │ ├── agent.module.ts │ │ │ │ └── agent.topics.ts │ │ │ ├── chat/ │ │ │ │ ├── agent.tool.interface.ts │ │ │ │ ├── async.storage.ts │ │ │ │ ├── auth.context.ts │ │ │ │ ├── chat.module.ts │ │ │ │ ├── load.tools.service.ts │ │ │ │ ├── mastra.service.ts │ │ │ │ ├── mastra.store.ts │ │ │ │ ├── rules.description.decorator.ts │ │ │ │ ├── start.mcp.ts │ │ │ │ ├── tools/ │ │ │ │ │ ├── generate.image.tool.ts │ │ │ │ │ ├── generate.video.options.tool.ts │ │ │ │ │ ├── generate.video.tool.ts │ │ │ │ │ ├── integration.list.tool.ts │ │ │ │ │ ├── integration.schedule.post.ts │ │ │ │ │ ├── integration.trigger.tool.ts │ │ │ │ │ ├── integration.validation.tool.ts │ │ │ │ │ ├── tool.list.ts │ │ │ │ │ └── video.function.tool.ts │ │ │ │ └── validation.schemas.helper.ts │ │ │ ├── crypto/ │ │ │ │ └── nowpayments.ts │ │ │ ├── database/ │ │ │ │ └── prisma/ │ │ │ │ ├── agencies/ │ │ │ │ │ ├── agencies.repository.ts │ │ │ │ │ └── agencies.service.ts │ │ │ │ ├── autopost/ │ │ │ │ │ ├── autopost.repository.ts │ │ │ │ │ └── autopost.service.ts │ │ │ │ ├── database.module.ts │ │ │ │ ├── integrations/ │ │ │ │ │ ├── integration.repository.ts │ │ │ │ │ └── integration.service.ts │ │ │ │ ├── media/ │ │ │ │ │ ├── media.repository.ts │ │ │ │ │ └── media.service.ts │ │ │ │ ├── notifications/ │ │ │ │ │ ├── notification.service.ts │ │ │ │ │ └── notifications.repository.ts │ │ │ │ ├── oauth/ │ │ │ │ │ ├── oauth.repository.ts │ │ │ │ │ └── oauth.service.ts │ │ │ │ ├── organizations/ │ │ │ │ │ ├── organization.repository.ts │ │ │ │ │ └── organization.service.ts │ │ │ │ ├── posts/ │ │ │ │ │ ├── posts.repository.ts │ │ │ │ │ └── posts.service.ts │ │ │ │ ├── prisma.service.ts │ │ │ │ ├── schema.prisma │ │ │ │ ├── sets/ │ │ │ │ │ ├── sets.repository.ts │ │ │ │ │ └── sets.service.ts │ │ │ │ ├── signatures/ │ │ │ │ │ ├── signature.repository.ts │ │ │ │ │ └── signature.service.ts │ │ │ │ ├── subscriptions/ │ │ │ │ │ ├── pricing.ts │ │ │ │ │ ├── subscription.repository.ts │ │ │ │ │ └── subscription.service.ts │ │ │ │ ├── third-party/ │ │ │ │ │ ├── third-party.repository.ts │ │ │ │ │ └── third-party.service.ts │ │ │ │ ├── users/ │ │ │ │ │ ├── users.repository.ts │ │ │ │ │ └── users.service.ts │ │ │ │ └── webhooks/ │ │ │ │ ├── webhooks.repository.ts │ │ │ │ └── webhooks.service.ts │ │ │ ├── dtos/ │ │ │ │ ├── agencies/ │ │ │ │ │ └── create.agency.dto.ts │ │ │ │ ├── analytics/ │ │ │ │ │ └── stars.list.dto.ts │ │ │ │ ├── auth/ │ │ │ │ │ ├── create.org.user.dto.ts │ │ │ │ │ ├── forgot-return.password.dto.ts │ │ │ │ │ ├── forgot.password.dto.ts │ │ │ │ │ ├── login.user.dto.ts │ │ │ │ │ └── resend-activation.dto.ts │ │ │ │ ├── autopost/ │ │ │ │ │ └── autopost.dto.ts │ │ │ │ ├── billing/ │ │ │ │ │ └── billing.subscribe.dto.ts │ │ │ │ ├── comments/ │ │ │ │ │ └── add.comment.dto.ts │ │ │ │ ├── generator/ │ │ │ │ │ ├── create.generated.posts.dto.ts │ │ │ │ │ └── generator.dto.ts │ │ │ │ ├── integrations/ │ │ │ │ │ ├── api.key.dto.ts │ │ │ │ │ ├── connect.integration.dto.ts │ │ │ │ │ ├── integration.function.dto.ts │ │ │ │ │ └── integration.time.dto.ts │ │ │ │ ├── media/ │ │ │ │ │ ├── media.dto.ts │ │ │ │ │ ├── save.media.information.dto.ts │ │ │ │ │ └── upload.dto.ts │ │ │ │ ├── notifications/ │ │ │ │ │ └── get.notifications.dto.ts │ │ │ │ ├── oauth/ │ │ │ │ │ ├── authorize-oauth.dto.ts │ │ │ │ │ ├── create-oauth-app.dto.ts │ │ │ │ │ ├── token-exchange.dto.ts │ │ │ │ │ └── update-oauth-app.dto.ts │ │ │ │ ├── plugs/ │ │ │ │ │ └── plug.dto.ts │ │ │ │ ├── posts/ │ │ │ │ │ ├── create.post.dto.ts │ │ │ │ │ ├── create.tag.dto.ts │ │ │ │ │ ├── get.posts.dto.ts │ │ │ │ │ ├── get.posts.list.dto.ts │ │ │ │ │ ├── providers-settings/ │ │ │ │ │ │ ├── all.providers.settings.ts │ │ │ │ │ │ ├── dev.to.settings.dto.ts │ │ │ │ │ │ ├── dev.to.tags.settings.dto.ts │ │ │ │ │ │ ├── discord.dto.ts │ │ │ │ │ │ ├── dribbble.dto.ts │ │ │ │ │ │ ├── facebook.dto.ts │ │ │ │ │ │ ├── farcaster.dto.ts │ │ │ │ │ │ ├── gmb.settings.dto.ts │ │ │ │ │ │ ├── hashnode.settings.dto.ts │ │ │ │ │ │ ├── instagram.dto.ts │ │ │ │ │ │ ├── kick.dto.ts │ │ │ │ │ │ ├── lemmy.dto.ts │ │ │ │ │ │ ├── linkedin.dto.ts │ │ │ │ │ │ ├── listmonk.dto.ts │ │ │ │ │ │ ├── medium.settings.dto.ts │ │ │ │ │ │ ├── mewe.dto.ts │ │ │ │ │ │ ├── moltbook.dto.ts │ │ │ │ │ │ ├── pinterest.dto.ts │ │ │ │ │ │ ├── reddit.dto.ts │ │ │ │ │ │ ├── skool.dto.ts │ │ │ │ │ │ ├── slack.dto.ts │ │ │ │ │ │ ├── tiktok.dto.ts │ │ │ │ │ │ ├── twitch.dto.ts │ │ │ │ │ │ ├── whop.dto.ts │ │ │ │ │ │ ├── wordpress.dto.ts │ │ │ │ │ │ ├── x.dto.ts │ │ │ │ │ │ └── youtube.settings.dto.ts │ │ │ │ │ └── transformers/ │ │ │ │ │ └── integration.settings.transformer.ts │ │ │ │ ├── sets/ │ │ │ │ │ └── sets.dto.ts │ │ │ │ ├── settings/ │ │ │ │ │ ├── add.team.member.dto.ts │ │ │ │ │ └── shortlink-preference.dto.ts │ │ │ │ ├── signature/ │ │ │ │ │ └── signature.dto.ts │ │ │ │ ├── users/ │ │ │ │ │ ├── email-notifications.dto.ts │ │ │ │ │ └── user.details.dto.ts │ │ │ │ ├── videos/ │ │ │ │ │ ├── video.dto.ts │ │ │ │ │ └── video.function.dto.ts │ │ │ │ └── webhooks/ │ │ │ │ └── webhooks.dto.ts │ │ │ ├── emails/ │ │ │ │ ├── email.interface.ts │ │ │ │ ├── empty.provider.ts │ │ │ │ ├── node.mailer.provider.ts │ │ │ │ └── resend.provider.ts │ │ │ ├── integrations/ │ │ │ │ ├── integration.manager.ts │ │ │ │ ├── integration.missing.scopes.ts │ │ │ │ ├── refresh.integration.service.ts │ │ │ │ ├── social/ │ │ │ │ │ ├── bluesky.provider.ts │ │ │ │ │ ├── dev.to.provider.ts │ │ │ │ │ ├── discord.provider.ts │ │ │ │ │ ├── dribbble.provider.ts │ │ │ │ │ ├── facebook.provider.ts │ │ │ │ │ ├── farcaster.provider.ts │ │ │ │ │ ├── gmb.provider.ts │ │ │ │ │ ├── hashnode.provider.ts │ │ │ │ │ ├── hashnode.tags.ts │ │ │ │ │ ├── instagram.provider.ts │ │ │ │ │ ├── instagram.standalone.provider.ts │ │ │ │ │ ├── kick.provider.ts │ │ │ │ │ ├── lemmy.provider.ts │ │ │ │ │ ├── linkedin.page.provider.ts │ │ │ │ │ ├── linkedin.provider.ts │ │ │ │ │ ├── listmonk.provider.ts │ │ │ │ │ ├── mastodon.custom.provider.ts │ │ │ │ │ ├── mastodon.provider.ts │ │ │ │ │ ├── medium.provider.ts │ │ │ │ │ ├── mewe.provider.ts │ │ │ │ │ ├── moltbook.provider.ts │ │ │ │ │ ├── nostr.provider.ts │ │ │ │ │ ├── pinterest.provider.ts │ │ │ │ │ ├── reddit.provider.ts │ │ │ │ │ ├── skool.provider.ts │ │ │ │ │ ├── slack.provider.ts │ │ │ │ │ ├── social.integrations.interface.ts │ │ │ │ │ ├── telegram.provider.ts │ │ │ │ │ ├── threads.provider.ts │ │ │ │ │ ├── tiktok.provider.ts │ │ │ │ │ ├── twitch.provider.ts │ │ │ │ │ ├── vk.provider.ts │ │ │ │ │ ├── whop.provider.ts │ │ │ │ │ ├── wordpress.provider.ts │ │ │ │ │ ├── x.provider.ts │ │ │ │ │ └── youtube.provider.ts │ │ │ │ ├── social.abstract.ts │ │ │ │ └── tool.decorator.ts │ │ │ ├── newsletter/ │ │ │ │ ├── newsletter.interface.ts │ │ │ │ ├── newsletter.service.ts │ │ │ │ ├── providers/ │ │ │ │ │ ├── beehiiv.provider.ts │ │ │ │ │ ├── email-empty.provider.ts │ │ │ │ │ └── listmonk.provider.ts │ │ │ │ └── providers.ts │ │ │ ├── openai/ │ │ │ │ ├── extract.content.service.ts │ │ │ │ ├── fal.service.ts │ │ │ │ └── openai.service.ts │ │ │ ├── redis/ │ │ │ │ └── redis.service.ts │ │ │ ├── sentry/ │ │ │ │ ├── initialize.sentry.ts │ │ │ │ └── sentry.exception.ts │ │ │ ├── services/ │ │ │ │ ├── codes.service.ts │ │ │ │ ├── email.service.ts │ │ │ │ ├── exception.filter.ts │ │ │ │ ├── make.is.ts │ │ │ │ ├── stripe.country.list.ts │ │ │ │ └── stripe.service.ts │ │ │ ├── short-linking/ │ │ │ │ ├── providers/ │ │ │ │ │ ├── dub.ts │ │ │ │ │ ├── empty.ts │ │ │ │ │ ├── kutt.ts │ │ │ │ │ ├── linkdrip.ts │ │ │ │ │ └── short.io.ts │ │ │ │ ├── short-linking.interface.ts │ │ │ │ └── short.link.service.ts │ │ │ ├── temporal/ │ │ │ │ ├── infinite.workflow.register.ts │ │ │ │ ├── temporal.module.ts │ │ │ │ ├── temporal.register.ts │ │ │ │ └── temporal.search.attribute.ts │ │ │ ├── throttler/ │ │ │ │ └── throttler.provider.ts │ │ │ ├── track/ │ │ │ │ └── track.service.ts │ │ │ ├── upload/ │ │ │ │ ├── cloudflare.storage.ts │ │ │ │ ├── custom.upload.validation.ts │ │ │ │ ├── local.storage.ts │ │ │ │ ├── r2.uploader.ts │ │ │ │ ├── upload.factory.ts │ │ │ │ ├── upload.interface.ts │ │ │ │ └── upload.module.ts │ │ │ ├── user/ │ │ │ │ ├── org.from.request.ts │ │ │ │ ├── track.enum.ts │ │ │ │ ├── user.agent.ts │ │ │ │ └── user.from.request.ts │ │ │ └── videos/ │ │ │ ├── images-slides/ │ │ │ │ └── images.slides.ts │ │ │ ├── veo3/ │ │ │ │ └── veo3.ts │ │ │ ├── video.interface.ts │ │ │ ├── video.manager.ts │ │ │ └── video.module.ts │ │ ├── tsconfig.json │ │ └── tsconfig.lib.json │ └── react-shared-libraries/ │ ├── .eslintrc.json │ ├── README.md │ ├── src/ │ │ ├── form/ │ │ │ ├── button.tsx │ │ │ ├── canonical.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── color.picker.tsx │ │ │ ├── custom.select.tsx │ │ │ ├── input.tsx │ │ │ ├── select.tsx │ │ │ ├── slider.tsx │ │ │ ├── textarea.tsx │ │ │ └── total.tsx │ │ ├── helpers/ │ │ │ ├── delete.dialog.tsx │ │ │ ├── image.with.fallback.tsx │ │ │ ├── is.general.tsx │ │ │ ├── mantine.wrapper.tsx │ │ │ ├── posthog.tsx │ │ │ ├── testomonials.tsx │ │ │ ├── uppy.upload.ts │ │ │ ├── use.is.visible.tsx │ │ │ ├── use.media.directory.ts │ │ │ ├── use.prevent.window.unload.tsx │ │ │ ├── use.state.callback.ts │ │ │ ├── use.track.tsx │ │ │ ├── utc.date.render.tsx │ │ │ ├── variable.context.tsx │ │ │ ├── video.frame.tsx │ │ │ └── video.or.image.tsx │ │ ├── sentry/ │ │ │ ├── initialize.sentry.client.ts │ │ │ ├── initialize.sentry.next.basic.ts │ │ │ └── initialize.sentry.server.ts │ │ ├── toaster/ │ │ │ └── toaster.tsx │ │ └── translation/ │ │ ├── get.transation.service.client.ts │ │ ├── get.translation.service.backend.ts │ │ ├── i18n.config.ts │ │ ├── i18next.ts │ │ ├── locales/ │ │ │ ├── ar/ │ │ │ │ └── translation.json │ │ │ ├── bn/ │ │ │ │ └── translation.json │ │ │ ├── de/ │ │ │ │ └── translation.json │ │ │ ├── en/ │ │ │ │ └── translation.json │ │ │ ├── es/ │ │ │ │ └── translation.json │ │ │ ├── fr/ │ │ │ │ └── translation.json │ │ │ ├── he/ │ │ │ │ └── translation.json │ │ │ ├── it/ │ │ │ │ └── translation.json │ │ │ ├── ja/ │ │ │ │ └── translation.json │ │ │ ├── ka_ge/ │ │ │ │ └── translation.json │ │ │ ├── ko/ │ │ │ │ └── translation.json │ │ │ ├── pt/ │ │ │ │ └── translation.json │ │ │ ├── ru/ │ │ │ │ └── translation.json │ │ │ ├── tr/ │ │ │ │ └── translation.json │ │ │ ├── vi/ │ │ │ │ └── translation.json │ │ │ └── zh/ │ │ │ └── translation.json │ │ └── translated-label.tsx │ ├── tsconfig.json │ └── tsconfig.lib.json ├── package.json ├── pnpm-workspace.yaml ├── railway.toml ├── reports/ │ └── junit.xml ├── sonar-project.properties ├── tsconfig.base.json ├── tsconfig.json ├── var/ │ └── docker/ │ ├── create-namespace-default.sh │ ├── docker-build.sh │ ├── docker-create.sh │ └── nginx.conf └── version.txt
SYMBOL INDEX (2266 symbols across 383 files)
FILE: apps/backend/src/api/api.module.ts
method exports (line 98) | get exports() {
class ApiModule (line 102) | class ApiModule implements NestModule {
method configure (line 103) | configure(consumer: MiddlewareConsumer) {
FILE: apps/backend/src/api/routes/analytics.controller.ts
class AnalyticsController (line 10) | class AnalyticsController {
method constructor (line 11) | constructor(
method getIntegration (line 17) | async getIntegration(
method getPostAnalytics (line 26) | async getPostAnalytics(
FILE: apps/backend/src/api/routes/approved-apps.controller.ts
class ApprovedAppsController (line 9) | class ApprovedAppsController {
method constructor (line 10) | constructor(private _oauthService: OAuthService) {}
method list (line 13) | async list(@GetUserFromRequest() user: User) {
method revoke (line 18) | async revoke(
FILE: apps/backend/src/api/routes/auth.controller.ts
class AuthController (line 29) | class AuthController {
method constructor (line 30) | constructor(
method canRegister (line 36) | async canRegister() {
method register (line 43) | async register(
method login (line 117) | async login(
method forgot (line 181) | async forgot(@Body() body: ForgotPasswordDto) {
method forgotReturn (line 195) | async forgotReturn(@Body() body: ForgotReturnPasswordDto) {
method oauthLink (line 203) | async oauthLink(@Param('provider') provider: string, @Query() query: a...
method activate (line 208) | async activate(
method resendActivation (line 240) | async resendActivation(@Body() body: ResendActivationDto) {
method oauthExists (line 255) | async oauthExists(
FILE: apps/backend/src/api/routes/autopost.controller.ts
class AutopostController (line 21) | class AutopostController {
method constructor (line 22) | constructor(private _autopostsService: AutopostService) {}
method getAutoposts (line 25) | async getAutoposts(@GetOrgFromRequest() org: Organization) {
method createAutopost (line 31) | async createAutopost(
method updateAutopost (line 39) | async updateAutopost(
method deleteAutopost (line 48) | async deleteAutopost(
method changeActive (line 56) | async changeActive(
method sendWebhook (line 65) | async sendWebhook(@Query('url') url: string) {
FILE: apps/backend/src/api/routes/billing.controller.ts
class BillingController (line 16) | class BillingController {
method constructor (line 17) | constructor(
method checkId (line 25) | async checkId(
method checkDiscount (line 35) | async checkDiscount(@GetOrgFromRequest() org: Organization) {
method applyDiscount (line 44) | async applyDiscount(@GetOrgFromRequest() org: Organization) {
method finishTrial (line 49) | async finishTrial(@GetOrgFromRequest() org: Organization) {
method isTrialFinished (line 59) | async isTrialFinished(@GetOrgFromRequest() org: Organization) {
method embedded (line 66) | embedded(
method subscribe (line 83) | subscribe(
method modifyPayment (line 100) | async modifyPayment(@GetOrgFromRequest() org: Organization) {
method getCurrentBilling (line 111) | getCurrentBilling(@GetOrgFromRequest() org: Organization) {
method cancel (line 116) | async cancel(
method prorate (line 132) | prorate(
method lifetime (line 140) | async lifetime(
method getCharges (line 148) | async getCharges(
method refundCharges (line 160) | async refundCharges(
method cancelSubscription (line 173) | async cancelSubscription(
method addSubscription (line 185) | async addSubscription(
method crypto (line 202) | async crypto(@GetOrgFromRequest() org: Organization) {
FILE: apps/backend/src/api/routes/copilot.controller.ts
type ChannelsContext (line 27) | type ChannelsContext = {
class CopilotController (line 34) | class CopilotController {
method constructor (line 35) | constructor(
method chatAgent (line 40) | chatAgent(@Req() req: Request, @Res() res: Response) {
method agent (line 62) | async agent(
method calculateCredits (line 108) | calculateCredits(
method getMessagesList (line 120) | async getMessagesList(
method getList (line 138) | async getList(@GetOrgFromRequest() organization: Organization) {
FILE: apps/backend/src/api/routes/enterprise.controller.ts
class EnterpriseController (line 12) | class EnterpriseController {
method constructor (line 13) | constructor(
method createUser (line 21) | async createUser(@Body('params') params: string) {
method redirectParams (line 46) | async redirectParams(@Body('params') params: string) {
method deleteChannel (line 95) | async deleteChannel(@Body('params') params: string) {
FILE: apps/backend/src/api/routes/integrations.controller.ts
class IntegrationsController (line 38) | class IntegrationsController {
method constructor (line 39) | constructor(
method saveProviderPage (line 48) | async saveProviderPage(
method getInternalPlugs (line 57) | getInternalPlugs(@Param('identifier') identifier: string) {
method getCustomers (line 62) | getCustomers(@GetOrgFromRequest() org: Organization) {
method updateIntegrationGroup (line 67) | async updateIntegrationGroup(
method updateOnCustomerName (line 80) | async updateOnCustomerName(
method getIntegrationList (line 89) | async getIntegrationList(@GetOrgFromRequest() org: Organization) {
method updateProviderSettings (line 126) | async updateProviderSettings(
method setNickname (line 138) | async setNickname(
method getSingleIntegration (line 178) | getSingleIntegration(
method getIntegrationUrl (line 194) | async getIntegrationUrl(
method setTime (line 251) | async setTime(
method mentions (line 260) | async mentions(
method functionIntegration (line 316) | async functionIntegration(
method disableChannel (line 376) | disableChannel(
method enableChannel (line 384) | enableChannel(
method deleteChannel (line 397) | async deleteChannel(
method getPlugList (line 415) | async getPlugList() {
method getPlugsByIntegrationId (line 420) | async getPlugsByIntegrationId(
method postPlugsByIntegrationId (line 428) | async postPlugsByIntegrationId(
method changePlugActivation (line 437) | async changePlugActivation(
method getUpdates (line 446) | async getUpdates(@Query() query: { word: string; id?: number }) {
method moltbookRegister (line 451) | async moltbookRegister(
method moltbookStatus (line 468) | async moltbookStatus(@Query('apiKey') apiKey: string) {
FILE: apps/backend/src/api/routes/media.controller.ts
class MediaController (line 31) | class MediaController {
method constructor (line 33) | constructor(
method deleteMedia (line 39) | deleteMedia(@GetOrgFromRequest() org: Organization, @Param('id') id: s...
method generateVideo (line 44) | generateVideo(
method generateImage (line 53) | async generateImage(
method generateImageFromText (line 72) | async generateImageFromText(
method uploadServer (line 90) | async uploadServer(
method saveMedia (line 105) | async saveMedia(
method saveMediaInformation (line 123) | saveMediaInformation(
method uploadSimple (line 132) | async uploadSimple(
method uploadFile (line 154) | async uploadFile(
method getMedia (line 181) | getMedia(
method getVideos (line 189) | getVideos() {
method videoFunction (line 194) | videoFunction(
method generateVideoAllowed (line 201) | generateVideoAllowed(
FILE: apps/backend/src/api/routes/monitor.controller.ts
class MonitorController (line 6) | class MonitorController {
method getMessagesGroup (line 8) | async getMessagesGroup(@Param('name') name: string) {
FILE: apps/backend/src/api/routes/no.auth.integrations.controller.ts
class NoAuthIntegrationsController (line 29) | class NoAuthIntegrationsController {
method constructor (line 30) | constructor(
method getIntegrations (line 38) | getIntegrations() {
method connectSocialMedia (line 45) | async connectSocialMedia(
method saveProviderPage (line 310) | async saveProviderPage(@Param('id') id: string, @Body() body: any) {
method extensionRefreshCookies (line 326) | async extensionRefreshCookies(
FILE: apps/backend/src/api/routes/notifications.controller.ts
class NotificationsController (line 10) | class NotificationsController {
method constructor (line 11) | constructor(private _notificationsService: NotificationService) {}
method mainPageList (line 13) | async mainPageList(
method notifications (line 24) | async notifications(
FILE: apps/backend/src/api/routes/oauth-app.controller.ts
class OAuthAppController (line 16) | class OAuthAppController {
method constructor (line 17) | constructor(private _oauthService: OAuthService) {}
method getApp (line 21) | async getApp(@GetOrgFromRequest() org: Organization) {
method createApp (line 27) | async createApp(
method updateApp (line 36) | async updateApp(
method deleteApp (line 45) | async deleteApp(@GetOrgFromRequest() org: Organization) {
method rotateSecret (line 51) | async rotateSecret(@GetOrgFromRequest() org: Organization) {
FILE: apps/backend/src/api/routes/oauth.controller.ts
class OAuthController (line 20) | class OAuthController {
method constructor (line 21) | constructor(private _oauthService: OAuthService) {}
method authorize (line 24) | async authorize(@Query() query: AuthorizeOAuthQueryDto) {
method token (line 42) | async token(@Body() body: TokenExchangeDto) {
class OAuthAuthorizedController (line 60) | class OAuthAuthorizedController {
method constructor (line 61) | constructor(private _oauthService: OAuthService) {}
method approveOrDeny (line 64) | async approveOrDeny(
FILE: apps/backend/src/api/routes/posts.controller.ts
class PostsController (line 33) | class PostsController {
method constructor (line 34) | constructor(
method getStatistics (line 41) | async getStatistics(
method getMissingContent (line 49) | async getMissingContent(
method updateReleaseId (line 57) | async updateReleaseId(
method shouldShortlink (line 66) | async shouldShortlink(@Body() body: { messages: string[] }) {
method createComment (line 71) | async createComment(
method getTags (line 81) | async getTags(@GetOrgFromRequest() org: Organization) {
method createTag (line 86) | async createTag(
method editTag (line 94) | async editTag(
method deleteTag (line 103) | async deleteTag(
method getPosts (line 111) | async getPosts(
method findSlot (line 119) | async findSlot(@GetOrgFromRequest() org: Organization) {
method findSlotIntegration (line 124) | async findSlotIntegration(
method getPostsList (line 132) | async getPostsList(
method oldPosts (line 140) | oldPosts(
method getPostsByGroup (line 148) | getPostsByGroup(@GetOrgFromRequest() org: Organization, @Param('group'...
method getPost (line 153) | getPost(@GetOrgFromRequest() org: Organization, @Param('id') id: strin...
method createPost (line 159) | async createPost(
method generatePostsDraft (line 170) | generatePostsDraft(
method generatePosts (line 179) | async generatePosts(
method deletePost (line 193) | deletePost(
method changeDate (line 201) | changeDate(
method separatePosts (line 211) | async separatePosts(
FILE: apps/backend/src/api/routes/public.controller.ts
class PublicController (line 34) | class PublicController {
method constructor (line 35) | constructor(
method createAgent (line 44) | async createAgent(@Body() body: { text: string; apiKey: string }) {
method getAgencyByUser (line 56) | async getAgencyByUser() {
method getAgencySlug (line 61) | async getAgencySlug() {
method getAgencyInformation (line 66) | async getAgencyInformation(@Param('agency') agency: string) {
method getAgenciesCount (line 71) | async getAgenciesCount() {
method getPreview (line 76) | async getPreview(@Param('id') id: string) {
method getComments (line 96) | async getComments(@Param('id') postId: string) {
method trackEvent (line 101) | async trackEvent(
method modifySubscription (line 153) | async modifySubscription(@Body('params') params: string) {
method cryptoPost (line 179) | async cryptoPost(@Body() body: any, @Param('path') path: string) {
method streamFile (line 185) | async streamFile(
FILE: apps/backend/src/api/routes/root.controller.ts
class RootController (line 3) | class RootController {
method getRoot (line 5) | getRoot(): string {
FILE: apps/backend/src/api/routes/sets.controller.ts
class SetsController (line 21) | class SetsController {
method constructor (line 22) | constructor(private _setsService: SetsService) {}
method getSets (line 25) | async getSets(@GetOrgFromRequest() org: Organization) {
method createASet (line 30) | async createASet(
method updateSet (line 38) | async updateSet(
method deleteSet (line 46) | async deleteSet(
FILE: apps/backend/src/api/routes/settings.controller.ts
class SettingsController (line 13) | class SettingsController {
method constructor (line 14) | constructor(
method getTeam (line 23) | async getTeam(@GetOrgFromRequest() org: Organization) {
method inviteTeamMember (line 32) | async inviteTeamMember(
method deleteTeamMember (line 44) | deleteTeamMember(
method getShortlinkPreference (line 52) | async getShortlinkPreference(@GetOrgFromRequest() org: Organization) {
method updateShortlinkPreference (line 58) | async updateShortlinkPreference(
FILE: apps/backend/src/api/routes/signature.controller.ts
class SignatureController (line 10) | class SignatureController {
method constructor (line 11) | constructor(private _signatureService: SignatureService) {}
method getSignatures (line 14) | async getSignatures(@GetOrgFromRequest() org: Organization) {
method getDefaultSignature (line 19) | async getDefaultSignature(@GetOrgFromRequest() org: Organization) {
method createSignature (line 24) | async createSignature(
method deleteSignature (line 32) | async deleteSignature(
method updateSignature (line 40) | async updateSignature(
FILE: apps/backend/src/api/routes/stripe.controller.ts
class StripeController (line 13) | class StripeController {
method constructor (line 14) | constructor(
method stripe (line 19) | stripe(@Req() req: RawBodyRequest<Request>) {
FILE: apps/backend/src/api/routes/third-party.controller.ts
class ThirdPartyController (line 20) | class ThirdPartyController {
method constructor (line 23) | constructor(
method getThirdPartyList (line 29) | async getThirdPartyList() {
method getSavedThirdParty (line 34) | async getSavedThirdParty(@GetOrgFromRequest() organization: Organizati...
method deleteById (line 55) | deleteById(
method generate (line 63) | async generate(
method callFunction (line 95) | async callFunction(
method addApiKey (line 125) | async addApiKey(
FILE: apps/backend/src/api/routes/users.controller.ts
class UsersController (line 37) | class UsersController {
method constructor (line 38) | constructor(
method getAgentMediaSsoUrl (line 47) | async getAgentMediaSsoUrl(
method getSelf (line 64) | async getSelf(
method getPersonalInformation (line 97) | async getPersonalInformation(@GetUserFromRequest() user: User) {
method getImpersonate (line 102) | async getImpersonate(
method setImpersonate (line 114) | async setImpersonate(
method changePersonal (line 141) | async changePersonal(
method getEmailNotifications (line 149) | async getEmailNotifications(@GetUserFromRequest() user: User) {
method updateEmailNotifications (line 154) | async updateEmailNotifications(
method rotateApiKey (line 163) | async rotateApiKey(@GetOrgFromRequest() organization: Organization) {
method getSubscription (line 169) | async getSubscription(@GetOrgFromRequest() organization: Organization) {
method tiers (line 180) | async tiers() {
method joinOrg (line 185) | async joinOrg(
method getOrgs (line 209) | async getOrgs(@GetUserFromRequest() user: User) {
method changeOrg (line 216) | changeOrg(
method logout (line 240) | logout(@Res({ passthrough: true }) response: Response) {
method trackEvent (line 285) | async trackEvent(
FILE: apps/backend/src/api/routes/webhooks.controller.ts
class WebhookController (line 24) | class WebhookController {
method constructor (line 25) | constructor(private _webhooksService: WebhooksService) {}
method getStatistics (line 28) | async getStatistics(@GetOrgFromRequest() org: Organization) {
method createAWebhook (line 34) | async createAWebhook(
method updateWebhook (line 42) | async updateWebhook(
method deleteWebhook (line 50) | async deleteWebhook(
method sendWebhook (line 58) | async sendWebhook(@Body() body: any, @Query('url') url: string) {
FILE: apps/backend/src/app.module.ts
class AppModule (line 66) | class AppModule {}
FILE: apps/backend/src/main.ts
function start (line 22) | async function start() {
function checkConfiguration (line 79) | function checkConfiguration() {
FILE: apps/backend/src/public-api/public.api.module.ts
method exports (line 28) | get exports() {
class PublicApiModule (line 32) | class PublicApiModule implements NestModule {
method configure (line 33) | configure(consumer: MiddlewareConsumer) {
FILE: apps/backend/src/public-api/routes/v1/public.integrations.controller.ts
class PublicIntegrationsController (line 46) | class PublicIntegrationsController {
method constructor (line 49) | constructor(
method uploadSimple (line 60) | async uploadSimple(
method uploadsFromUrl (line 78) | async uploadsFromUrl(
method findSlotIntegration (line 114) | async findSlotIntegration(
method getPosts (line 123) | async getPosts(
method createPost (line 137) | async createPost(
method deletePost (line 154) | async deletePost(
method deletePostByGroup (line 164) | deletePostByGroup(
method getActiveIntegrations (line 173) | async getActiveIntegrations(@GetOrgFromRequest() org: Organization) {
method listIntegration (line 179) | async listIntegration(@GetOrgFromRequest() org: Organization) {
method getIntegrationUrl (line 201) | async getIntegrationUrl(
method getNotifications (line 243) | async getNotifications(
method generateVideo (line 255) | generateVideo(
method videoFunction (line 264) | videoFunction(@Body() body: VideoFunctionDto) {
method deleteChannel (line 274) | async deleteChannel(
method getIntegrationSettings (line 293) | async getIntegrationSettings(
method getMissingContent (line 336) | async getMissingContent(
method updateReleaseId (line 345) | async updateReleaseId(
method getAnalytics (line 355) | async getAnalytics(
method getPostAnalytics (line 365) | async getPostAnalytics(
method triggerIntegrationTool (line 375) | async triggerIntegrationTool(
FILE: apps/backend/src/services/auth/auth.middleware.ts
class AuthMiddleware (line 28) | class AuthMiddleware implements NestMiddleware {
method constructor (line 29) | constructor(
method use (line 33) | async use(req: Request, res: Response, next: NextFunction) {
FILE: apps/backend/src/services/auth/auth.service.ts
class AuthService (line 16) | class AuthService {
method constructor (line 17) | constructor(
method canRegister (line 24) | async canRegister(provider: string) {
method routeAuth (line 35) | async routeAuth(
method getOrgFromCookie (line 112) | public getOrgFromCookie(cookie?: string) {
method loginOrRegisterProvider (line 134) | private async loginOrRegisterProvider(
method _track (line 189) | private async _track(
method forgot (line 214) | async forgot(email: string) {
method forgotReturn (line 232) | forgotReturn(body: ForgotReturnPasswordDto) {
method activate (line 244) | async activate(code: string, tracking: string) {
method resendActivationEmail (line 265) | async resendActivationEmail(email: string) {
method oauthLink (line 288) | oauthLink(provider: string, query?: any) {
method checkExists (line 293) | async checkExists(provider: string, code: string) {
method jwt (line 311) | private async jwt(user: User) {
FILE: apps/backend/src/services/auth/permissions/permission.exception.class.ts
type Sections (line 3) | enum Sections {
type AuthorizationActions (line 16) | enum AuthorizationActions {
class SubscriptionException (line 23) | class SubscriptionException extends HttpException {
method constructor (line 24) | constructor(message: { section: Sections; action: AuthorizationActions...
FILE: apps/backend/src/services/auth/permissions/permissions.ability.ts
constant CHECK_POLICIES_KEY (line 4) | const CHECK_POLICIES_KEY = 'check_policy';
type AbilityPolicy (line 5) | type AbilityPolicy = [AuthorizationActions, Sections];
FILE: apps/backend/src/services/auth/permissions/permissions.guard.ts
class PoliciesGuard (line 16) | class PoliciesGuard implements CanActivate {
method constructor (line 17) | constructor(
method canActivate (line 22) | async canActivate(context: ExecutionContext): Promise<boolean> {
method execPolicyHandler (line 64) | private execPolicyHandler(handler: AbilityPolicy, ability: AppAbility) {
FILE: apps/backend/src/services/auth/permissions/permissions.service.ts
type AppAbility (line 11) | type AppAbility = Ability<[AuthorizationActions, Sections]>;
class PermissionsService (line 14) | class PermissionsService {
method constructor (line 15) | constructor(
method getPackageOptions (line 21) | async getPackageOptions(orgId: string) {
method check (line 39) | async check(
FILE: apps/backend/src/services/auth/permissions/subscription.exception.ts
class SubscriptionExceptionFilter (line 10) | class SubscriptionExceptionFilter implements ExceptionFilter {
method catch (line 11) | catch(exception: HttpException, host: ArgumentsHost) {
FILE: apps/backend/src/services/auth/providers.interface.ts
method postRegistration (line 9) | async postRegistration(
type AuthProviderParams (line 15) | interface AuthProviderParams {
function AuthProvider (line 19) | function AuthProvider(params: AuthProviderParams) {
FILE: apps/backend/src/services/auth/providers/farcaster.provider.ts
class FarcasterProvider (line 12) | class FarcasterProvider extends AuthProviderAbstract {
method generateLink (line 13) | generateLink() {
method getToken (line 17) | async getToken(code: string) {
method getUser (line 27) | async getUser(providerToken: string) {
FILE: apps/backend/src/services/auth/providers/github.provider.ts
class GithubProvider (line 7) | class GithubProvider extends AuthProviderAbstract {
method generateLink (line 8) | generateLink(): string {
method getToken (line 16) | async getToken(code: string): Promise<string> {
method getUser (line 36) | async getUser(access_token: string): Promise<{ email: string; id: stri...
FILE: apps/backend/src/services/auth/providers/google.provider.ts
class GoogleProvider (line 37) | class GoogleProvider extends AuthProviderAbstract {
method generateLink (line 38) | generateLink() {
method getToken (line 53) | async getToken(code: string) {
method getUser (line 59) | async getUser(providerToken: string) {
FILE: apps/backend/src/services/auth/providers/oauth.provider.ts
class OauthProvider (line 7) | class OauthProvider extends AuthProviderAbstract {
method getConfig (line 8) | private getConfig() {
method generateLink (line 39) | generateLink(): string {
method getToken (line 51) | async getToken(code: string): Promise<string> {
method getUser (line 77) | async getUser(access_token: string): Promise<{ email: string; id: stri...
FILE: apps/backend/src/services/auth/providers/providers.manager.ts
class AuthProviderManager (line 6) | class AuthProviderManager {
method constructor (line 7) | constructor(private _moduleRef: ModuleRef) {}
method getProvider (line 9) | getProvider(provider: string): AuthProviderAbstract {
FILE: apps/backend/src/services/auth/providers/wallet.provider.ts
function hexToUint8Array (line 10) | function hexToUint8Array(hex) {
class WalletProvider (line 31) | class WalletProvider extends AuthProviderAbstract {
method generateLink (line 32) | async generateLink(params: { publicKey: string }) {
method getToken (line 43) | async getToken(code: string) {
method getUser (line 73) | async getUser(providerToken: string) {
FILE: apps/backend/src/services/auth/public.auth.middleware.ts
class PublicAuthMiddleware (line 8) | class PublicAuthMiddleware implements NestMiddleware {
method constructor (line 9) | constructor(
method use (line 13) | async use(req: Request, res: Response, next: NextFunction) {
FILE: apps/cli/examples/ai-agent-example.js
constant POSTIZ_API_KEY (line 13) | const POSTIZ_API_KEY = process.env.POSTIZ_API_KEY;
function runPostizCommand (line 23) | function runPostizCommand(command) {
function main (line 40) | async function main() {
function getScheduledTime (line 90) | function getScheduledTime(hours, minutes) {
FILE: apps/cli/src/api.ts
type PostizConfig (line 3) | interface PostizConfig {
class PostizAPI (line 8) | class PostizAPI {
method constructor (line 12) | constructor(config: PostizConfig) {
method request (line 17) | private async request(endpoint: string, options: any = {}) {
method createPost (line 42) | async createPost(data: any) {
method listPosts (line 49) | async listPosts(filters: any = {}) {
method deletePost (line 68) | async deletePost(id: string) {
method upload (line 74) | async upload(file: Buffer, filename: string) {
method listIntegrations (line 140) | async listIntegrations() {
method getIntegrationSettings (line 146) | async getIntegrationSettings(integrationId: string) {
method triggerIntegrationTool (line 152) | async triggerIntegrationTool(
FILE: apps/cli/src/commands/integrations.ts
function listIntegrations (line 4) | async function listIntegrations() {
function getIntegrationSettings (line 19) | async function getIntegrationSettings(args: any) {
function triggerIntegrationTool (line 39) | async function triggerIntegrationTool(args: any) {
FILE: apps/cli/src/commands/posts.ts
function createPost (line 5) | async function createPost(args: any) {
function listPosts (line 106) | async function listPosts(args: any) {
function deletePost (line 139) | async function deletePost(args: any) {
FILE: apps/cli/src/commands/upload.ts
function uploadFile (line 5) | async function uploadFile(args: any) {
FILE: apps/cli/src/config.ts
function getConfig (line 3) | function getConfig(): PostizConfig {
FILE: apps/commands/src/command.module.ts
method exports (line 13) | get exports() {
class CommandModule (line 17) | class CommandModule {}
FILE: apps/commands/src/main.ts
function bootstrap (line 5) | async function bootstrap() {
FILE: apps/commands/src/tasks/agent.run.ts
class AgentRun (line 6) | class AgentRun {
method constructor (line 7) | constructor(private _agentGraphService: AgentGraphService) {}
method agentRun (line 12) | async agentRun() {
FILE: apps/commands/src/tasks/configuration.ts
class ConfigurationTask (line 6) | class ConfigurationTask {
method create (line 11) | create() {
FILE: apps/commands/src/tasks/refresh.tokens.ts
class RefreshTokens (line 6) | class RefreshTokens {
method constructor (line 7) | constructor(private _integrationService: IntegrationService) {}
method refresh (line 12) | async refresh() {
FILE: apps/extension/custom-vite-plugins.ts
function stripDevIcons (line 6) | function stripDevIcons(isDev: boolean) {
function crxI18n (line 27) | function crxI18n(options: {
FILE: apps/extension/src/background.ts
constant EXTENSION_VERSION (line 5) | const EXTENSION_VERSION = '2.0.0';
constant REFRESH_ALARM_NAME (line 6) | const REFRESH_ALARM_NAME = 'cookie-refresh';
constant STORAGE_KEY (line 7) | const STORAGE_KEY = 'refreshEntries';
constant ALLOWED_ORIGIN_PATTERNS (line 9) | const ALLOWED_ORIGIN_PATTERNS = [
function isOriginAllowed (line 14) | function isOriginAllowed(origin: string | undefined): boolean {
function extractCookies (line 19) | async function extractCookies(provider: CookieProvider): Promise<GetCook...
function getStoredEntries (line 52) | async function getStoredEntries(): Promise<Record<string, StoredRefreshE...
function setStoredEntries (line 57) | async function setStoredEntries(entries: Record<string, StoredRefreshEnt...
function ensureAlarm (line 61) | async function ensureAlarm(): Promise<void> {
function clearAlarmIfEmpty (line 68) | async function clearAlarmIfEmpty(): Promise<void> {
function refreshAllCookies (line 77) | async function refreshAllCookies(): Promise<void> {
FILE: apps/extension/src/providers/cookie-provider.interface.ts
type CookieDefinition (line 1) | interface CookieDefinition {
type CookieProvider (line 8) | interface CookieProvider {
FILE: apps/extension/src/providers/provider.registry.ts
function getAllProviders (line 12) | function getAllProviders(): CookieProvider[] {
function getProvider (line 16) | function getProvider(identifier: string): CookieProvider | undefined {
FILE: apps/extension/src/types/messages.ts
type PingRequest (line 3) | interface PingRequest {
type GetProvidersRequest (line 7) | interface GetProvidersRequest {
type GetCookiesRequest (line 11) | interface GetCookiesRequest {
type StoreRefreshTokenRequest (line 16) | interface StoreRefreshTokenRequest {
type RemoveRefreshTokenRequest (line 24) | interface RemoveRefreshTokenRequest {
type ExtensionRequest (line 29) | type ExtensionRequest =
type PingResponse (line 38) | interface PingResponse {
type ProviderInfo (line 43) | interface ProviderInfo {
type GetProvidersResponse (line 50) | interface GetProvidersResponse {
type GetCookiesSuccessResponse (line 54) | interface GetCookiesSuccessResponse {
type GetCookiesErrorResponse (line 60) | interface GetCookiesErrorResponse {
type GetCookiesResponse (line 67) | type GetCookiesResponse =
type StoredRefreshEntry (line 71) | interface StoredRefreshEntry {
type ErrorResponse (line 77) | interface ErrorResponse {
type ExtensionResponse (line 81) | type ExtensionResponse =
FILE: apps/frontend/next.config.js
method headers (line 10) | async headers() {
method redirects (line 46) | async redirects() {
method rewrites (line 56) | async rewrites() {
FILE: apps/frontend/public/f.js
function a (line 55) | function a(a, b) {
function a (line 100) | function a(a, b) {
function j (line 134) | function j(a, b) {
function k (line 141) | function k(a, b) {
function l (line 159) | function l(a, b, c) {
function m (line 170) | function m(a) {
function n (line 176) | function n(a, b) {
function a (line 203) | function a() {
function a (line 229) | function a(a) {
function b (line 244) | function b(b) {
function l (line 365) | function l() {
function m (line 371) | function m(a) {
function n (line 377) | function n(a) {
function o (line 383) | function o(a) {
function p (line 395) | function p(a) {
function q (line 414) | function q(a, b, f) {
function r (line 459) | function r(a, c) {
function a (line 536) | function a(b) {
function d (line 615) | function d() {
function e (line 619) | function e() {
function a (line 624) | function a(b) {
function e (line 949) | function e(a) {
function g (line 984) | function g(a) {
function h (line 1007) | function h(a) {
function j (line 1024) | function j(a) {
function k (line 1047) | function k(a) {
function m (line 1073) | function m(a) {
function e (line 1189) | function e(a) {
function g (line 1229) | function g(a) {
function h (line 1232) | function h(a) {
function j (line 1235) | function j(a) {
function k (line 1238) | function k(a) {
function n (line 1241) | function n(a) {
function o (line 1249) | function o(a) {
function p (line 1252) | function p(a, b) {
function q (line 1255) | function q(a, b) {
function r (line 1263) | function r(a, b) {
function s (line 1269) | function s(b, c) {
function t (line 1282) | function t(a) {
function u (line 1289) | function u(b, c) {
function c (line 1362) | function c(a) {
function c (line 1382) | function c(a) {
function a (line 1508) | function a() {
function e (line 1762) | function e(a, e, f, g) {
function g (line 1953) | function g(a, c, f) {
function O (line 2117) | function O(a) {
function Q (line 2138) | function Q(a, b, c, d, e, f) {
function d (line 2142) | function d(a, b) {
function e (line 2526) | function e(e) {
function c (line 2598) | function c(a, c) {
function q (line 2636) | function q(a) {
function a (line 2684) | function a() {
function b (line 2833) | function b(a, b, c) {
function g (line 2861) | function g(a, c, f, g, h) {
function a (line 2891) | function a() {
function a (line 2923) | function a() {
function b (line 2931) | function b(b) {
function g (line 2956) | function g() {
function c (line 2995) | function c(a) {
function i (line 3058) | function i(a) {
function c (line 3064) | function c() {
function b (line 3217) | function b(b, c, d) {
function c (line 3244) | function c() {
function b (line 3283) | function b() {
function d (line 3292) | function d() {
function e (line 3307) | function e(a) {
function e (line 3342) | function e() {
function d (line 3371) | function d(a) {
function g (line 3391) | function g(a) {
function l (line 3428) | function l() {
function n (line 3432) | function n() {
function p (line 3436) | function p() {
function t (line 3442) | function t(a) {
function v (line 3446) | function v() {
function w (line 3449) | function w(a) {
function A (line 3458) | function A(a) {
function D (line 3621) | function D(a, b) {
function E (line 3656) | function E(a) {
function F (line 3672) | function F(a) {
function c (line 3701) | function c(a) {
function k (line 3818) | function k(a) {
function m (line 3821) | function m(a) {
function n (line 3832) | function n(a) {
function o (line 3839) | function o(a) {
function p (line 3842) | function p(a) {
function q (line 3845) | function q(a) {
function r (line 3848) | function r(a) {
function s (line 3856) | function s(a) {
function u (line 3870) | function u() {
function v (line 3875) | function v(a, b, d) {
function a (line 3913) | function a() {
function g (line 4060) | function g(a) {
function a (line 4075) | function a() {
function e (line 4197) | function e(a) {
function e (line 4220) | function e(a) {
function e (line 4243) | function e(a) {
function a (line 4266) | function a(b) {
function b (line 4398) | function b(a) {
function j (line 4423) | function j(a) {
function k (line 4426) | function k(a, b) {
function b (line 4445) | function b(a, c) {
function d (line 4519) | function d(b, d) {
function k (line 4627) | function k(a) {
function d (line 4664) | function d() {
function b (line 4754) | function b(a) {
function c (line 4767) | function c(b) {
function d (line 4785) | function d(a) {
function o (line 4884) | function o(a, b) {
function p (line 4913) | function p(a) {
function r (line 4943) | function r(a) {
function d (line 4970) | function d(b, d) {
function e (line 5003) | function e(b, e) {
function s (line 5091) | function s(b) {
function d (line 5191) | function d(d, e, f) {
function e (line 5226) | function e(b, e) {
function g (line 5283) | function g(c, f) {
function h (line 5341) | function h(a, b, c) {
function i (line 5358) | function i(c) {
function g (line 5399) | function g() {
function g (line 5453) | function g() {
function e (line 5495) | function e(a, c) {
function c (line 5517) | function c(a, c) {
function d (line 5545) | function d(a) {
function h (line 5575) | function h() {
function d (line 5627) | function d(b) {
function l (line 5697) | function l(d) {
function m (line 5721) | function m(a) {
function a (line 5758) | function a() {
function h (line 5773) | function h(a) {
function m (line 5776) | function m() {
function o (line 5782) | function o() {
function p (line 5788) | function p() {
function q (line 5794) | function q() {
function r (line 5800) | function r() {
function s (line 5811) | function s() {
function t (line 5823) | function t() {
function u (line 5829) | function u() {
function v (line 5835) | function v(a) {
function w (line 5841) | function w(a) {
function x (line 5846) | function x(b) {
function y (line 5858) | function y(a) {
function z (line 5863) | function z(b) {
function A (line 5880) | function A(a, b) {
function B (line 5888) | function B(a, b) {
function C (line 5891) | function C(a) {
function D (line 5898) | function D(a) {
function E (line 5901) | function E(a) {
function F (line 5910) | function F(a) {
function H (line 5922) | function H() {
function d (line 5980) | function d(a) {
function e (line 5994) | function e(a, c) {
function a (line 6110) | function a(a, b) {
function b (line 6118) | function b(b) {
function c (line 6144) | function c(a, b) {
function d (line 6147) | function d(b) {
function e (line 6152) | function e(a) {
function f (line 6158) | function f(a) {
function j (line 6165) | function j(a) {
function k (line 6171) | function k(a) {
function o (line 6189) | function o(a) {
function p (line 6192) | function p(a, c, d) {
function u (line 6215) | function u(a) {
function v (line 6226) | function v(a, b) {
function w (line 6241) | function w(a, b, c, d) {
function x (line 6260) | function x(a) {
function y (line 6269) | function y(a) {
function z (line 6272) | function z(a) {
function A (line 6286) | function A(a, b) {
function a (line 6300) | function a(b) {
function E (line 6321) | function E(a) {
function F (line 6324) | function F(a, b) {
function G (line 6327) | function G(a, b) {
function g (line 6381) | function g() {
function b (line 6405) | function b(a) {
function g (line 6434) | function g() {
function d (line 6461) | function d(a) {
function e (line 6466) | function e(a) {
function f (line 6472) | function f(a) {
function r (line 6840) | function r(a) {
function s (line 6843) | function s(a) {
function t (line 6863) | function t(b) {
function u (line 6867) | function u(a, b) {
function v (line 6870) | function v(a, c, e) {
function w (line 6887) | function w(a, b) {
function x (line 6896) | function x(b, c) {
function a (line 6985) | function a(a, b) {
function i (line 7048) | function i(a, b) {
function j (line 7052) | function j(a, b) {
function k (line 7059) | function k(a, b) {
function e (line 7105) | function e(a) {
function g (line 7108) | function g(a) {
function e (line 7137) | function e(a) {
function g (line 7193) | function g(a) {
function d (line 7223) | function d(a) {
function e (line 7253) | function e(a) {
function g (line 7277) | function g(a) {
function h (line 7282) | function h(a) {
function i (line 7289) | function i(a) {
function a (line 7314) | function a(a) {
function b (line 7348) | function b(a, b) {
function c (line 7351) | function c(a, b, c) {
function d (line 7354) | function d(a, b, c) {
function e (line 7357) | function e(a) {
function f (line 7360) | function f(a) {
function g (line 7363) | function g(a) {
function h (line 7366) | function h(a) {
function i (line 7369) | function i(a, b) {
function q (line 7393) | function q(a, b) {
function r (line 7398) | function r() {
function s (line 7409) | function s() {
function t (line 7455) | function t(a, b) {
function u (line 7470) | function u() {
function v (line 7489) | function v() {
function w (line 7495) | function w(a) {
function x (line 7501) | function x(a, b) {
function y (line 7508) | function y(b) {
function c (line 7649) | function c(d) {
function a (line 9613) | function a() {}
function e (line 10273) | function e(a) {
function i (line 10300) | function i(a) {
function s (line 10431) | function s(a) {
function t (line 10457) | function t(a) {
function v (line 10475) | function v(a) {
function w (line 10501) | function w(a, b) {
function x (line 10513) | function x(a) {
function y (line 10535) | function y(a, b) {
function z (line 10544) | function z(a, b, c) {
function A (line 10557) | function A(a) {
function a (line 10578) | function a(b) {
function I (line 10719) | function I(a) {
function J (line 10745) | function J(a, b) {
function K (line 10803) | function K(a, b) {
function L (line 10818) | function L(a, b) {
function aa (line 10823) | function aa(a, b) {
function ba (line 10837) | function ba(a, b) {
function M (line 10933) | function M(a) {
function fa (line 10959) | function fa(a, b) {
function ga (line 10971) | function ga(a) {
function ha (line 10993) | function ha(a, b, c) {
function la (line 11069) | function la(a) {
function ma (line 11095) | function ma(a, b) {
function na (line 11110) | function na(a, b) {
function oa (line 11115) | function oa(a, b) {
function ra (line 11129) | function ra(a, b) {
function sa (line 11148) | function sa(a, b, c, d) {
function ta (line 11160) | function ta(a, b, c, d) {
function ua (line 11173) | function ua(a, b) {
function va (line 11250) | function va(a, b) {
function O (line 11304) | function O(a) {
function wa (line 11330) | function wa(a, b) {
function xa (line 11399) | function xa(a, b) {
function ya (line 11404) | function ya(a, b) {
function za (line 11416) | function za(a) {
function Aa (line 11438) | function Aa(a, b, c) {
function a (line 11528) | function a(a, b) {
function Ea (line 11749) | function Ea(a) {
function Fa (line 11827) | function Fa(a) {
function Ga (line 11833) | function Ga(a) {
function Ja (line 11863) | function Ja(a) {
function Na (line 11911) | function Na(a) {
function Ta (line 11947) | function Ta(a) {
function Ua (line 11974) | function Ua(a) {
function Va (line 11982) | function Va(a, b) {
function Wa (line 11991) | function Wa(a) {
function T (line 12011) | function T(a) {
function Za (line 12039) | function Za(a) {
function $a (line 12044) | function $a(a) {
function ab (line 12047) | function ab(a) {
function gb (line 12074) | function gb(a) {
function hb (line 12083) | function hb(a, b) {
function ib (line 12096) | function ib(a) {
function jb (line 12109) | function jb(a) {
function U (line 12127) | function U(a, b) {
function a (line 12143) | function a(b) {
function mb (line 12274) | function mb(a, b) {
function nb (line 12286) | function nb(a) {
function ob (line 12308) | function ob(a, b, c) {
function V (line 12321) | function V(a) {
function pb (line 12347) | function pb(a, b) {
function qb (line 12356) | function qb(a) {
function rb (line 12376) | function rb(a, b) {
function sb (line 12380) | function sb(a, b) {
function tb (line 12395) | function tb(a) {
function ub (line 12429) | function ub(a, b, c) {
function vb (line 12439) | function vb() {
function wb (line 12455) | function wb(a, b) {
function xb (line 12462) | function xb(a) {
function g (line 12505) | function g() {
function Ab (line 12527) | function Ab() {
function Bb (line 12533) | function Bb(a, b) {
function X (line 12541) | function X(a, b) {
function Cb (line 12544) | function Cb(a) {
function Db (line 12547) | function Db(a) {
function Gb (line 12747) | function Gb(a) {
function Nb (line 12816) | function Nb(a, b, c) {
function Ob (line 12876) | function Ob(a) {
function Pb (line 12879) | function Pb(a, b) {
function Qb (line 12904) | function Qb(a) {
function Rb (line 12913) | function Rb(a) {
function Sb (line 12916) | function Sb(a, b) {
function Tb (line 12927) | function Tb(a, b) {
function bc (line 13033) | function bc(a) {
function cc (line 13059) | function cc(a) {
function dc (line 13063) | function dc(a) {
function ec (line 13098) | function ec(a) {
function fc (line 13136) | function fc(a) {
function gc (line 13188) | function gc(a) {
function hc (line 13191) | function hc(a) {
function ic (line 13200) | function ic(a, b) {
function m (line 13414) | function m(a) {
function n (line 13417) | function n(a) {
function o (line 13437) | function o(a) {
function p (line 13440) | function p(a) {
function t (line 13614) | function t(a) {
function u (line 13624) | function u(a) {
function v (line 13640) | function v(a) {
function w (line 13643) | function w(a) {
function x (line 13658) | function x(a, b) {
function y (line 13673) | function y(a) {
function z (line 13684) | function z(a) {
function A (line 13695) | function A(a) {
function B (line 13714) | function B(a) {
function C (line 13725) | function C(a) {
function D (line 13736) | function D(a, b, c) {
function E (line 13758) | function E(a, b) {
function F (line 13774) | function F(a) {
function G (line 13783) | function G(a) {
function H (line 13786) | function H(a) {
function I (line 13789) | function I(a) {
function J (line 13804) | function J(a) {
function K (line 13807) | function K(a, d) {
function L (line 13816) | function L(b, c) {
function q (line 13911) | function q(a) {
function r (line 13914) | function r(a, c) {
function s (line 13928) | function s(a, c) {
function b (line 13950) | function b(a) {
function c (line 14036) | function c() {
function i (line 14064) | function i(a, c) {
function d (line 14179) | function d() {
function h (line 14265) | function h(c, d) {
function q (line 14290) | function q() {
function r (line 14304) | function r(b) {
function s (line 14310) | function s(a, b, c) {
function d (line 14329) | function d(a) {
function n (line 14517) | function n() {
function o (line 14525) | function o() {
function p (line 14528) | function p(a, b) {
function s (line 14545) | function s() {
function t (line 14568) | function t() {
function u (line 14572) | function u(b) {
function v (line 14578) | function v() {
function a (line 14706) | function a(a, b) {
function h (line 14748) | function h(a) {
function i (line 14751) | function i(a) {
function Y (line 14863) | function Y(a) {
function Z (line 14867) | function Z() {
function oa (line 14963) | function oa(a) {
function $ (line 15227) | function $(a, b, c) {
function pa (line 15263) | function pa() {
function qa (line 15273) | function qa(a, b, c) {
function ra (line 15293) | function ra(a, b, c) {
function sa (line 15301) | function sa(a, b, c) {
function ta (line 15320) | function ta(a, b, c, d, e) {
function ua (line 15328) | function ua(b, c, d) {
function va (line 15355) | function va(a, b) {
function wa (line 15362) | function wa(a, b, c) {
function xa (line 15371) | function xa(a) {
function ya (line 15378) | function ya(a, b, c, d, e) {
function za (line 15428) | function za(a) {
function Aa (line 15479) | function Aa() {
function Ba (line 15497) | function Ba() {
function Ca (line 15513) | function Ca() {
function Da (line 15527) | function Da(a) {
function Ea (line 15530) | function Ea() {
function Fa (line 15536) | function Fa(a) {
FILE: apps/frontend/src/app/(app)/(preview)/p/[id]/layout.tsx
function AppLayout (line 4) | async function AppLayout({ children }: { children: ReactNode }) {
FILE: apps/frontend/src/app/(app)/(preview)/p/[id]/page.tsx
function Auth (line 28) | async function Auth({
FILE: apps/frontend/src/app/(app)/(site)/agents/[id]/page.tsx
function Page (line 8) | async function Page() {
FILE: apps/frontend/src/app/(app)/(site)/agents/layout.tsx
function Layout (line 7) | async function Layout({
FILE: apps/frontend/src/app/(app)/(site)/agents/page.tsx
function Page (line 9) | async function Page() {
FILE: apps/frontend/src/app/(app)/(site)/analytics/page.tsx
function Index (line 9) | async function Index() {
FILE: apps/frontend/src/app/(app)/(site)/billing/lifetime/page.tsx
function Page (line 9) | async function Page() {
FILE: apps/frontend/src/app/(app)/(site)/billing/page.tsx
function Page (line 9) | async function Page() {
FILE: apps/frontend/src/app/(app)/(site)/err/page.tsx
function Page (line 7) | async function Page() {
FILE: apps/frontend/src/app/(app)/(site)/launches/page.tsx
function Index (line 9) | async function Index() {
FILE: apps/frontend/src/app/(app)/(site)/layout.tsx
function Layout (line 3) | async function Layout({
FILE: apps/frontend/src/app/(app)/(site)/media/page.tsx
function Page (line 10) | async function Page() {
FILE: apps/frontend/src/app/(app)/(site)/plugs/page.tsx
function Index (line 9) | async function Index() {
FILE: apps/frontend/src/app/(app)/(site)/settings/page.tsx
function Index (line 9) | async function Index({
FILE: apps/frontend/src/app/(app)/(site)/third-party/page.tsx
function Index (line 12) | async function Index() {
FILE: apps/frontend/src/app/(app)/api/uploads/[[...path]]/route.ts
function iteratorToStream (line 10) | function iteratorToStream(iterator: any) {
FILE: apps/frontend/src/app/(app)/auth/activate/[code]/page.tsx
function Auth (line 11) | async function Auth() {
FILE: apps/frontend/src/app/(app)/auth/activate/page.tsx
function Auth (line 11) | async function Auth() {
FILE: apps/frontend/src/app/(app)/auth/forgot/[token]/page.tsx
function Auth (line 9) | async function Auth(params: {
FILE: apps/frontend/src/app/(app)/auth/forgot/page.tsx
function Auth (line 9) | async function Auth() {
FILE: apps/frontend/src/app/(app)/auth/layout.tsx
function AuthLayout (line 10) | async function AuthLayout({
FILE: apps/frontend/src/app/(app)/auth/login-required/page.tsx
function LoginRequiredPage (line 1) | async function LoginRequiredPage() {
FILE: apps/frontend/src/app/(app)/auth/login/page.tsx
function Auth (line 9) | async function Auth() {
FILE: apps/frontend/src/app/(app)/auth/page.tsx
function Auth (line 13) | async function Auth(params: {searchParams: {provider: string}}) {
FILE: apps/frontend/src/app/(app)/integrations/social/[provider]/page.tsx
function Page (line 6) | async function Page({
FILE: apps/frontend/src/app/(app)/integrations/social/layout.tsx
function IntegrationLayout (line 3) | async function IntegrationLayout({
FILE: apps/frontend/src/app/(app)/layout.tsx
function AppLayout (line 36) | async function AppLayout({ children }: { children: ReactNode }) {
FILE: apps/frontend/src/app/(app)/oauth/authorize/layout.tsx
function OAuthLayout (line 8) | async function OAuthLayout({
FILE: apps/frontend/src/app/(app)/oauth/authorize/page.tsx
function OAuthAuthorizePage (line 8) | function OAuthAuthorizePage() {
FILE: apps/frontend/src/app/(extension)/layout.tsx
function AppLayout (line 18) | async function AppLayout({ children }: { children: ReactNode }) {
FILE: apps/frontend/src/app/(extension)/modal/[style]/[platform]/page.tsx
function Modal (line 4) | async function Modal() {
FILE: apps/frontend/src/app/(extension)/modal/layout.tsx
function AppLayoutIn (line 3) | async function AppLayoutIn({
FILE: apps/frontend/src/app/global-error.tsx
function GlobalError (line 7) | function GlobalError({
FILE: apps/frontend/src/components/agents/agent.input.tsx
constant MAX_NEWLINES (line 6) | const MAX_NEWLINES = 6;
FILE: apps/frontend/src/components/agents/agent.textarea.tsx
type AutoResizingTextareaProps (line 3) | interface AutoResizingTextareaProps {
FILE: apps/frontend/src/components/analytics/chart-social.tsx
function mergeDataPoints (line 9) | function mergeDataPoints(data: TotalList[], numPoints: number): TotalLis...
FILE: apps/frontend/src/components/analytics/stars.and.forks.interface.ts
type StarsList (line 1) | interface StarsList {
type TotalList (line 5) | interface TotalList {
type ForksList (line 9) | interface ForksList {
type Stars (line 13) | interface Stars {
type StarsAndForksInterface (line 20) | interface StarsAndForksInterface {
FILE: apps/frontend/src/components/auth/activate.tsx
type ResendInputs (line 11) | type ResendInputs = {
type ResendStatus (line 15) | type ResendStatus = 'idle' | 'sent' | 'already_activated';
constant COOLDOWN_SECONDS (line 17) | const COOLDOWN_SECONDS = 60;
function Activate (line 19) | function Activate() {
FILE: apps/frontend/src/components/auth/forgot-return.tsx
type Inputs (line 11) | type Inputs = {
function ForgotReturn (line 16) | function ForgotReturn({ token }: { token: string }) {
FILE: apps/frontend/src/components/auth/forgot.tsx
type Inputs (line 12) | type Inputs = {
function Forgot (line 15) | function Forgot() {
FILE: apps/frontend/src/components/auth/login.tsx
type Inputs (line 18) | type Inputs = {
function Login (line 24) | function Login() {
FILE: apps/frontend/src/components/auth/register.tsx
type Inputs (line 33) | type Inputs = {
function Register (line 40) | function Register() {
function getHelpfulReasonForRegistrationFailure (line 75) | function getHelpfulReasonForRegistrationFailure(httpCode: number) {
function RegisterAfter (line 84) | function RegisterAfter({
FILE: apps/frontend/src/components/billing/first.billing.component.tsx
type FeatureItem (line 305) | type FeatureItem = {
FILE: apps/frontend/src/components/launches/calendar.context.tsx
type Integrations (line 83) | interface Integrations {
function getDateRange (line 106) | function getDateRange(display: string, referenceDate?: string) {
FILE: apps/frontend/src/components/launches/comments/comment.component.tsx
type Comments (line 61) | interface Comments {
FILE: apps/frontend/src/components/launches/continue.integration.tsx
type TwoStepState (line 15) | interface TwoStepState {
type SuccessState (line 22) | interface SuccessState {
FILE: apps/frontend/src/components/launches/filters.tsx
function getDateRange (line 13) | function getDateRange(
FILE: apps/frontend/src/components/launches/helpers/use.values.ts
class Empty (line 6) | class Empty {
FILE: apps/frontend/src/components/launches/launches.component.tsx
type MenuComponentInterface (line 75) | interface MenuComponentInterface {
FILE: apps/frontend/src/components/launches/polonto.tsx
method key (line 26) | get key() {
FILE: apps/frontend/src/components/launches/statistics.tsx
type AnalyticsData (line 10) | interface AnalyticsData {
FILE: apps/frontend/src/components/launches/web3/web3.provider.interface.ts
type Web3ProviderInterface (line 1) | interface Web3ProviderInterface {
FILE: apps/frontend/src/components/layout/impersonate.tsx
type Charge (line 15) | interface Charge {
FILE: apps/frontend/src/components/layout/layout.context.tsx
function LayoutContext (line 8) | function LayoutContext(params: { children: ReactNode }) {
function setCookie (line 15) | function setCookie(cname: string, cvalue: string, exdays: number) {
function LayoutContextInner (line 24) | function LayoutContextInner(params: { children: ReactNode }) {
FILE: apps/frontend/src/components/layout/new-modal.tsx
type OpenModalInterface (line 19) | interface OpenModalInterface {
type ModalManagerStoreInterface (line 38) | interface ModalManagerStoreInterface {
type State (line 44) | interface State extends ModalManagerStoreInterface {
type ModalManagerInterface (line 70) | interface ModalManagerInterface extends ModalManagerStoreInterface {
FILE: apps/frontend/src/components/layout/top.menu.tsx
type MenuItemInterface (line 10) | interface MenuItemInterface {
FILE: apps/frontend/src/components/media/media.component.tsx
constant CHUNK_SIZE (line 198) | const CHUNK_SIZE = 1024 * 1024;
constant MAX_UPLOAD_SIZE (line 199) | const MAX_UPLOAD_SIZE = 1024 * 1024 * 1024;
FILE: apps/frontend/src/components/media/new.uploader.tsx
class CompressionWrapper (line 17) | class CompressionWrapper<M = any, B = any> extends Compressor<any, any> {
method prepareUpload (line 18) | override async prepareUpload(fileIDs: string[]) {
function useUppyUploader (line 38) | function useUppyUploader(props: {
FILE: apps/frontend/src/components/new-launch/add.edit.modal.tsx
type AddEditModalProps (line 13) | interface AddEditModalProps {
FILE: apps/frontend/src/components/new-launch/editor.tsx
constant MAX_UPLOAD_SIZE (line 71) | const MAX_UPLOAD_SIZE = 1024 * 1024 * 1024;
method addKeyboardShortcuts (line 76) | addKeyboardShortcuts() {
method addKeyboardShortcuts (line 90) | addKeyboardShortcuts() {
method renderHTML (line 1005) | renderHTML({ options, node }) {
FILE: apps/frontend/src/components/new-launch/manage.modal.tsx
function countCharacters (line 48) | function countCharacters(text: string, type: string): number {
FILE: apps/frontend/src/components/new-launch/mention.component.tsx
method onUpdate (line 203) | onUpdate(props: any) {
method onKeyDown (line 233) | onKeyDown(props: any) {
method onExit (line 243) | onExit() {
FILE: apps/frontend/src/components/new-launch/providers/continue-provider/facebook/facebook.continue.tsx
type FacebookItem (line 5) | interface FacebookItem {
FILE: apps/frontend/src/components/new-launch/providers/continue-provider/gmb/gmb.continue.tsx
type GmbItem (line 5) | interface GmbItem {
type GmbSelection (line 17) | interface GmbSelection {
FILE: apps/frontend/src/components/new-launch/providers/continue-provider/instagram/instagram.continue.tsx
type InstagramItem (line 5) | interface InstagramItem {
type InstagramSelection (line 17) | interface InstagramSelection {
FILE: apps/frontend/src/components/new-launch/providers/continue-provider/linkedin/linkedin.continue.tsx
type LinkedinItem (line 5) | interface LinkedinItem {
type LinkedinSelection (line 13) | interface LinkedinSelection {
FILE: apps/frontend/src/components/new-launch/providers/continue-provider/with-continue-provider.tsx
constant SWR_OPTIONS (line 10) | const SWR_OPTIONS = {
type ContinueProviderProps (line 20) | interface ContinueProviderProps {
type EmptyStateMessage (line 27) | interface EmptyStateMessage {
type ContinueProviderConfig (line 32) | interface ContinueProviderConfig<TItem, TSelection> {
function withContinueProvider (line 45) | function withContinueProvider<TItem, TSelection>(
FILE: apps/frontend/src/components/new-launch/providers/continue-provider/youtube/youtube.continue.tsx
type YoutubeItem (line 5) | interface YoutubeItem {
type YoutubeSelection (line 17) | interface YoutubeSelection {
FILE: apps/frontend/src/components/new-launch/providers/high.order.provider.tsx
class Empty (line 26) | class Empty {
type PostComment (line 31) | enum PostComment {
type CharacterCondition (line 37) | interface CharacterCondition {
FILE: apps/frontend/src/components/new-launch/select.current.tsx
function useHasScroll (line 19) | function useHasScroll(ref: RefObject<HTMLElement>): boolean {
FILE: apps/frontend/src/components/new-launch/store.ts
type Values (line 10) | interface Values {
type Internal (line 17) | interface Internal {
type SelectedIntegrations (line 22) | interface SelectedIntegrations {
type StoreState (line 28) | interface StoreState {
FILE: apps/frontend/src/components/notifications/notification.component.tsx
function replaceLinks (line 10) | function replaceLinks(text: string) {
FILE: apps/frontend/src/components/onboarding/onboarding.modal.tsx
type OnboardingModalProps (line 13) | interface OnboardingModalProps {
FILE: apps/frontend/src/components/platform-analytics/render.analytics.tsx
type AnalyticsDataItem (line 9) | interface AnalyticsDataItem {
FILE: apps/frontend/src/components/plugs/plug.tsx
function convertBackRegex (line 29) | function convertBackRegex(s: string) {
method onClose (line 242) | onClose() {
FILE: apps/frontend/src/components/plugs/plugs.context.ts
type PlugSettings (line 4) | interface PlugSettings {
type PlugInterface (line 9) | interface PlugInterface extends PlugSettings {
type FieldsInterface (line 12) | interface FieldsInterface {
type PlugsInterface (line 19) | interface PlugsInterface {
FILE: apps/frontend/src/components/settings/email-notifications.component.tsx
type EmailNotifications (line 10) | interface EmailNotifications {
FILE: apps/frontend/src/components/settings/shortlink-preference.component.tsx
type ShortLinkPreference (line 10) | type ShortLinkPreference = 'ASK' | 'YES' | 'NO';
type ShortlinkPreferenceResponse (line 12) | interface ShortlinkPreferenceResponse {
FILE: apps/frontend/src/components/ui/icons/index.tsx
type IconProps (line 6) | type IconProps = SVGProps<SVGSVGElement> & {
FILE: apps/frontend/src/components/ui/is.scroll.hook.tsx
function useHasScroll (line 3) | function useHasScroll(
FILE: apps/frontend/src/components/ui/translated-label.tsx
type TranslatedLabelProps (line 4) | interface TranslatedLabelProps {
function TranslatedLabel (line 19) | function TranslatedLabel({
FILE: apps/frontend/src/components/videos/providers/image-text-slides.provider.tsx
type Voices (line 10) | interface Voices {
type Voice (line 14) | interface Voice {
FILE: apps/frontend/src/components/videos/providers/veo3.provider.tsx
type Voice (line 8) | interface Voice {
FILE: apps/frontend/src/instrumentation.ts
function register (line 1) | async function register() {
FILE: apps/frontend/src/middleware.ts
function middleware (line 15) | async function middleware(request: NextRequest) {
FILE: apps/orchestrator/src/activities/autopost.activity.ts
class AutopostActivity (line 20) | class AutopostActivity {
method constructor (line 21) | constructor(private _autoPostService: AutopostService) {}
method autoPost (line 24) | async autoPost(id: string) {
FILE: apps/orchestrator/src/activities/email.activity.ts
class EmailActivity (line 8) | class EmailActivity {
method constructor (line 9) | constructor(
method sendEmail (line 15) | async sendEmail(to: string, subject: string, html: string, replyTo?: s...
method sendEmailAsync (line 20) | async sendEmailAsync(to: string, subject: string, html: string, sendTo...
method getUserOrgs (line 25) | async getUserOrgs(id: string) {
method setStreak (line 30) | async setStreak(organizationId: string, type: 'start' | 'end') {
FILE: apps/orchestrator/src/activities/integrations.activity.ts
class IntegrationsActivity (line 9) | class IntegrationsActivity {
method constructor (line 10) | constructor(
method getIntegrationsById (line 16) | async getIntegrationsById(id: string, orgId: string) {
method refreshToken (line 20) | async refreshToken(integration: Integration) {
FILE: apps/orchestrator/src/activities/post.activity.ts
class PostActivity (line 29) | class PostActivity {
method constructor (line 30) | constructor(
method getIntegrationById (line 42) | async getIntegrationById(orgId: string, id: string) {
method searchForMissingThreeHoursPosts (line 47) | async searchForMissingThreeHoursPosts() {
method updatePost (line 82) | async updatePost(id: string, postId: string, releaseURL: string) {
method getPostsList (line 87) | async getPostsList(orgId: string, postId: string) {
method isCommentable (line 108) | async isCommentable(integration: Integration) {
method postComment (line 117) | async postComment(
method postSocial (line 161) | async postSocial(integration: Integration, posts: Post[]) {
method inAppNotification (line 215) | async inAppNotification(
method globalPlugs (line 234) | async globalPlugs(integration: Integration) {
method changeState (line 243) | async changeState(id: string, state: State, err?: any, body?: any) {
method internalPlugs (line 248) | async internalPlugs(integration: Integration, settings: any) {
method sendWebhooks (line 258) | async sendWebhooks(postId: string, orgId: string, integrationId: strin...
method processPlug (line 286) | async processPlug(data: {
method processInternalPlug (line 297) | async processInternalPlug(data: {
method refreshToken (line 310) | async refreshToken(
FILE: apps/orchestrator/src/app.module.ts
method exports (line 22) | get exports() {
class AppModule (line 26) | class AppModule {}
FILE: apps/orchestrator/src/main.ts
function bootstrap (line 11) | async function bootstrap() {
FILE: apps/orchestrator/src/signals/email.signal.ts
type Email (line 3) | type Email = {
FILE: apps/orchestrator/src/signals/send.email.signal.ts
type SendEmail (line 3) | type SendEmail = {
FILE: apps/orchestrator/src/workflows/autopost.workflow.ts
function autoPostWorkflow (line 14) | async function autoPostWorkflow({
FILE: apps/orchestrator/src/workflows/digest.email.workflow.ts
function digestEmailWorkflow (line 22) | async function digestEmailWorkflow({
FILE: apps/orchestrator/src/workflows/missing.post.workflow.ts
function missingPostWorkflow (line 13) | async function missingPostWorkflow() {
FILE: apps/orchestrator/src/workflows/post-workflows/post.workflow.v1.0.1.ts
function postWorkflowV101 (line 51) | async function postWorkflowV101({
FILE: apps/orchestrator/src/workflows/refresh.token.workflow.ts
function refreshTokenWorkflow (line 14) | async function refreshTokenWorkflow({
FILE: apps/orchestrator/src/workflows/send.email.workflow.ts
constant RATE_LIMIT_MS (line 20) | const RATE_LIMIT_MS = 700;
function sendEmailWorkflow (line 22) | async function sendEmailWorkflow({
FILE: apps/orchestrator/src/workflows/streak.workflow.ts
function streakWorkflow (line 10) | async function streakWorkflow({
FILE: apps/sdk/src/index.ts
function toQueryString (line 5) | function toQueryString(obj: Record<string, any>): string {
class Postiz (line 15) | class Postiz {
method constructor (line 16) | constructor(
method post (line 21) | async post(posts: CreatePostDto) {
method postList (line 34) | async postList(filters: GetPostsDto) {
method upload (line 46) | async upload(file: Buffer, extension: string) {
method integrations (line 74) | async integrations() {
method deletePost (line 86) | deletePost(id: string) {
FILE: libraries/helpers/src/auth/auth.service.ts
function deriveLegacyKeyIv (line 9) | function deriveLegacyKeyIv(secret: string) {
function decrypt_legacy_using_IV (line 22) | function decrypt_legacy_using_IV(hexCiphertext: string) {
function encrypt_legacy_using_IV (line 29) | function encrypt_legacy_using_IV(utf8Plaintext: string) {
class AuthService (line 35) | class AuthService {
method hashPassword (line 36) | static hashPassword(password: string) {
method comparePassword (line 39) | static comparePassword(password: string, hash: string) {
method signJWT (line 42) | static signJWT(value: object) {
method verifyJWT (line 45) | static verifyJWT(token: string) {
method fixedEncryption (line 49) | static fixedEncryption(value: string) {
method fixedDecryption (line 53) | static fixedDecryption(hash: string) {
FILE: libraries/helpers/src/configuration/configuration.checker.ts
class ConfigurationChecker (line 5) | class ConfigurationChecker {
method readEnvFromFile (line 9) | readEnvFromFile() {
method readEnvFromProcess (line 22) | readEnvFromProcess() {
method check (line 26) | check() {
method checkNonEmpty (line 36) | checkNonEmpty(key: string, description?: string): boolean {
method get (line 56) | get(key: string): string | undefined {
method checkDatabaseServers (line 60) | checkDatabaseServers() {
method checkRedis (line 65) | checkRedis() {
method checkIsValidUrl (line 81) | checkIsValidUrl(key: string) {
method hasIssues (line 99) | hasIssues() {
method getIssues (line 103) | getIssues() {
method getIssuesCount (line 107) | getIssuesCount() {
FILE: libraries/helpers/src/decorators/plug.decorator.ts
function Plug (line 3) | function Plug(params: {
FILE: libraries/helpers/src/decorators/post.plug.ts
function PostPlug (line 3) | function PostPlug(params: {
FILE: libraries/helpers/src/subdomain/subdomain.management.ts
function getCookieUrlFromDomain (line 3) | function getCookieUrlFromDomain(domain: string) {
FILE: libraries/helpers/src/utils/custom.fetch.func.ts
type Params (line 1) | interface Params {
method baseUrl (line 89) | get baseUrl() {
FILE: libraries/helpers/src/utils/posts.list.minify.ts
constant POST_LIST_KEYS (line 4) | const POST_LIST_KEYS: Record<string, string> = {
constant POST_CALENDAR_KEYS (line 12) | const POST_CALENDAR_KEYS: Record<string, string> = {
constant POST_ITEM_KEYS (line 16) | const POST_ITEM_KEYS: Record<string, string> = {
constant INTEGRATION_KEYS (line 30) | const INTEGRATION_KEYS: Record<string, string> = {
constant TAG_KEYS (line 37) | const TAG_KEYS: Record<string, string> = {
constant TAG_INNER_KEYS (line 41) | const TAG_INNER_KEYS: Record<string, string> = {
function mapKeys (line 51) | function mapKeys(obj: Record<string, any>, keyMap: Record<string, string...
function reverseMap (line 59) | function reverseMap(keyMap: Record<string, string>) {
function minifyPostItem (line 67) | function minifyPostItem(post: any) {
function expandPostItem (line 90) | function expandPostItem(post: any) {
function minifyPostsList (line 117) | function minifyPostsList(data: {
function expandPostsList (line 133) | function expandPostsList(data: any) {
function minifyPosts (line 142) | function minifyPosts(data: { posts: any[] }) {
function expandPosts (line 152) | function expandPosts(data: any) {
FILE: libraries/helpers/src/utils/use.wait.for.class.tsx
function useWaitForClass (line 12) | function useWaitForClass(className: string, root: HTMLElement | null = n...
FILE: libraries/helpers/src/utils/valid.images.ts
class ValidContent (line 9) | class ValidContent implements ValidatorConstraintInterface {
method validate (line 10) | validate(contentRaw: string, args: ValidationArguments) {
method defaultMessage (line 23) | defaultMessage(args: ValidationArguments) {
FILE: libraries/helpers/src/utils/valid.url.path.ts
class ValidUrlExtension (line 8) | class ValidUrlExtension implements ValidatorConstraintInterface {
method validate (line 9) | validate(text: string, args: ValidationArguments) {
method defaultMessage (line 20) | defaultMessage(args: ValidationArguments) {
class ValidUrlPath (line 29) | class ValidUrlPath implements ValidatorConstraintInterface {
method validate (line 30) | validate(text: string, args: ValidationArguments) {
method defaultMessage (line 40) | defaultMessage(args: ValidationArguments) {
FILE: libraries/nestjs-libraries/src/3rdparties/heygen/heygen.provider.ts
class HeygenProvider (line 15) | class HeygenProvider extends ThirdPartyAbstract<{
method constructor (line 22) | constructor(private _openaiService: OpenaiService) {
method checkConnection (line 26) | async checkConnection(
method generateVoice (line 50) | async generateVoice(apiKey: string, data: { text: string }) {
method voices (line 56) | async voices(apiKey: string) {
method avatars (line 72) | async avatars(apiKey: string) {
method sendData (line 111) | async sendData(
FILE: libraries/nestjs-libraries/src/3rdparties/thirdparty.interface.ts
type ThirdPartyParams (line 11) | interface ThirdPartyParams {
function ThirdParty (line 25) | function ThirdParty(params: ThirdPartyParams) {
FILE: libraries/nestjs-libraries/src/3rdparties/thirdparty.manager.ts
class ThirdPartyManager (line 10) | class ThirdPartyManager {
method constructor (line 11) | constructor(
method getAllThirdParties (line 16) | getAllThirdParties(): any[] {
method getThirdPartyByName (line 27) | getThirdPartyByName(
method deleteIntegration (line 37) | deleteIntegration(org: string, id: string) {
method getIntegrationById (line 41) | getIntegrationById(org: string, id: string) {
method getAllThirdPartiesByOrganization (line 45) | getAllThirdPartiesByOrganization(org: string) {
method saveIntegration (line 49) | saveIntegration(
FILE: libraries/nestjs-libraries/src/3rdparties/thirdparty.module.ts
method exports (line 8) | get exports() {
class ThirdPartyModule (line 12) | class ThirdPartyModule {}
FILE: libraries/nestjs-libraries/src/agent/agent.graph.insert.service.ts
type WorkflowChannelsState (line 17) | interface WorkflowChannelsState {
class AgentGraphInsertService (line 38) | class AgentGraphInsertService {
method constructor (line 39) | constructor(private _postsService: PostsService) {}
method findCategory (line 55) | async findCategory(state: WorkflowChannelsState) {
method findTopic (line 73) | findTopic(state: WorkflowChannelsState) {
method findHook (line 91) | findHook(state: WorkflowChannelsState) {
method savePost (line 106) | async savePost(state: WorkflowChannelsState) {
method newPost (line 117) | newPost(post: string) {
FILE: libraries/nestjs-libraries/src/agent/agent.graph.service.ts
type WorkflowChannelsState (line 35) | interface WorkflowChannelsState {
class AgentGraphService (line 105) | class AgentGraphService {
method constructor (line 107) | constructor(
method startCall (line 134) | async startCall(state: WorkflowChannelsState) {
method saveResearch (line 152) | async saveResearch(state: WorkflowChannelsState) {
method findCategories (line 157) | async findCategories(state: WorkflowChannelsState) {
method findTopic (line 178) | async findTopic(state: WorkflowChannelsState) {
method findPopularPosts (line 205) | async findPopularPosts(state: WorkflowChannelsState) {
method generateHook (line 213) | async generateHook(state: WorkflowChannelsState) {
method generateContent (line 255) | async generateContent(state: WorkflowChannelsState) {
method fixArray (line 306) | async fixArray(state: WorkflowChannelsState) {
method generatePictures (line 316) | async generatePictures(state: WorkflowChannelsState) {
method uploadPictures (line 336) | async uploadPictures(state: WorkflowChannelsState) {
method isGeneratePicture (line 361) | async isGeneratePicture(state: WorkflowChannelsState) {
method postDateTime (line 369) | async postDateTime(state: WorkflowChannelsState) {
method start (line 373) | start(orgId: string, body: GeneratorDto) {
FILE: libraries/nestjs-libraries/src/agent/agent.module.ts
method exports (line 8) | get exports() {
class AgentModule (line 12) | class AgentModule {}
FILE: libraries/nestjs-libraries/src/chat/agent.tool.interface.ts
type ToolReturn (line 7) | type ToolReturn = Tool<
type AgentToolInterface (line 15) | interface AgentToolInterface {
FILE: libraries/nestjs-libraries/src/chat/async.storage.ts
type Ctx (line 4) | type Ctx = {
function runWithContext (line 11) | function runWithContext<T>(ctx: Ctx, fn: () => Promise<T> | T) {
function getContext (line 15) | function getContext(): Ctx | undefined {
function getAuth (line 19) | function getAuth<T = any>(): T | undefined {
function getRequestId (line 23) | function getRequestId(): string | undefined {
FILE: libraries/nestjs-libraries/src/chat/chat.module.ts
method exports (line 9) | get exports() {
class ChatModule (line 13) | class ChatModule {}
FILE: libraries/nestjs-libraries/src/chat/load.tools.service.ts
class LoadToolsService (line 21) | class LoadToolsService {
method constructor (line 22) | constructor(private _moduleRef: ModuleRef) {}
method loadTools (line 24) | async loadTools() {
method agent (line 43) | async agent() {
FILE: libraries/nestjs-libraries/src/chat/mastra.service.ts
class MastraService (line 8) | class MastraService {
method constructor (line 10) | constructor(private _loadToolsService: LoadToolsService) {}
method mastra (line 11) | async mastra() {
FILE: libraries/nestjs-libraries/src/chat/rules.description.decorator.ts
function Rules (line 3) | function Rules(description: string) {
FILE: libraries/nestjs-libraries/src/chat/tools/generate.image.tool.ts
class GenerateImageTool (line 10) | class GenerateImageTool implements AgentToolInterface {
method constructor (line 13) | constructor(private _mediaService: MediaService) {}
method run (line 16) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/generate.video.options.tool.ts
class GenerateVideoOptionsTool (line 13) | class GenerateVideoOptionsTool implements AgentToolInterface {
method constructor (line 14) | constructor(private _videoManagerService: VideoManager) {}
method run (line 17) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/generate.video.tool.ts
class GenerateVideoTool (line 18) | class GenerateVideoTool implements AgentToolInterface {
method constructor (line 19) | constructor(
method run (line 25) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/integration.list.tool.ts
class IntegrationListTool (line 13) | class IntegrationListTool implements AgentToolInterface {
method constructor (line 14) | constructor(private _integrationService: IntegrationService) {}
method run (line 17) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/integration.schedule.post.ts
function countCharacters (line 16) | function countCharacters(text: string, type: string): number {
class IntegrationSchedulePostTool (line 24) | class IntegrationSchedulePostTool implements AgentToolInterface {
method constructor (line 25) | constructor(
method run (line 31) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/integration.trigger.tool.ts
class IntegrationTriggerTool (line 16) | class IntegrationTriggerTool implements AgentToolInterface {
method constructor (line 17) | constructor(
method run (line 24) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/integration.validation.tool.ts
class IntegrationValidationTool (line 13) | class IntegrationValidationTool implements AgentToolInterface {
method constructor (line 14) | constructor(private _integrationManager: IntegrationManager) {}
method run (line 17) | run() {
FILE: libraries/nestjs-libraries/src/chat/tools/video.function.tool.ts
class VideoFunctionTool (line 10) | class VideoFunctionTool implements AgentToolInterface {
method constructor (line 11) | constructor(
method run (line 17) | run() {
FILE: libraries/nestjs-libraries/src/chat/validation.schemas.helper.ts
function getValidationSchemas (line 9) | function getValidationSchemas() {
FILE: libraries/nestjs-libraries/src/crypto/nowpayments.ts
type ProcessPayment (line 6) | interface ProcessPayment {
class Nowpayments (line 25) | class Nowpayments {
method constructor (line 26) | constructor(private _subscriptionService: SubscriptionService) {}
method processPayment (line 28) | async processPayment(path: string, body: ProcessPayment) {
method createPaymentPage (line 46) | async createPaymentPage(orgId: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/agencies/agencies.repository.ts
class AgenciesRepository (line 7) | class AgenciesRepository {
method constructor (line 8) | constructor(
method getAllAgencies (line 13) | getAllAgencies() {
method getCount (line 29) | getCount() {
method getAllAgenciesSlug (line 38) | getAllAgenciesSlug() {
method approveOrDecline (line 50) | approveOrDecline(action: string, id: string) {
method getAgencyById (line 61) | getAgencyById(id: string) {
method getAgencyInformation (line 76) | getAgencyInformation(agency: string) {
method getAgencyByUser (line 90) | getAgencyByUser(user: User) {
method createAgency (line 103) | async createAgency(user: User, body: CreateAgencyDto) {
FILE: libraries/nestjs-libraries/src/database/prisma/agencies/agencies.service.ts
class AgenciesService (line 8) | class AgenciesService {
method constructor (line 9) | constructor(
method getAgencyByUser (line 13) | getAgencyByUser(user: User) {
method getCount (line 17) | getCount() {
method getAllAgencies (line 21) | getAllAgencies() {
method getAllAgenciesSlug (line 25) | getAllAgenciesSlug() {
method getAgencyInformation (line 29) | getAgencyInformation(agency: string) {
method approveOrDecline (line 33) | async approveOrDecline(email: string, action: string, id: string) {
method createAgency (line 85) | async createAgency(user: User, body: CreateAgencyDto) {
FILE: libraries/nestjs-libraries/src/database/prisma/autopost/autopost.repository.ts
class AutopostRepository (line 7) | class AutopostRepository {
method constructor (line 8) | constructor(private _autoPost: PrismaRepository<'autoPost'>) {}
method getTotal (line 10) | getTotal(orgId: string) {
method getAutoposts (line 19) | getAutoposts(orgId: string) {
method deleteAutopost (line 28) | deleteAutopost(orgId: string, id: string) {
method getAutopost (line 40) | getAutopost(id: string) {
method updateUrl (line 49) | updateUrl(id: string, url: string) {
method changeActive (line 60) | changeActive(orgId: string, id: string, active: boolean) {
method createAutopost (line 72) | async createAutopost(orgId: string, body: AutopostDto, id?: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/autopost/autopost.service.ts
type WorkflowChannelsState (line 24) | interface WorkflowChannelsState {
class AutopostService (line 62) | class AutopostService {
method constructor (line 63) | constructor(
method stopAll (line 70) | async stopAll(org: string) {
method getAutoposts (line 77) | getAutoposts(orgId: string) {
method createAutopost (line 81) | async createAutopost(orgId: string, body: AutopostDto, id?: string) {
method changeActive (line 93) | async changeActive(orgId: string, id: string, active: boolean) {
method processCron (line 103) | async processCron(active: boolean, orgId: string, id: string) {
method deleteAutopost (line 129) | async deleteAutopost(orgId: string, id: string) {
method loadXML (line 135) | async loadXML(url: string) {
method loadUrl (line 185) | async loadUrl(url: string) {
method generateDescription (line 201) | async generateDescription(state: WorkflowChannelsState) {
method generatePicture (line 244) | async generatePicture(state: WorkflowChannelsState) {
method schedulePost (line 265) | async schedulePost(state: WorkflowChannelsState) {
method updateUrl (line 309) | async updateUrl(state: WorkflowChannelsState) {
method startAutopost (line 313) | async startAutopost(id: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/database.module.ts
method exports (line 89) | get exports() {
class DatabaseModule (line 93) | class DatabaseModule {}
FILE: libraries/nestjs-libraries/src/database/prisma/integrations/integration.repository.ts
class IntegrationRepository (line 11) | class IntegrationRepository {
method constructor (line 13) | constructor(
method getMentions (line 22) | getMentions(platform: string, q: string) {
method insertMentions (line 53) | insertMentions(
method checkPreviousConnections (line 71) | async checkPreviousConnections(org: string, id: string) {
method updateProviderSettings (line 89) | updateProviderSettings(org: string, id: string, settings: string) {
method setTimes (line 101) | async setTimes(org: string, id: string, times: IntegrationTimeDto) {
method getPlug (line 116) | getPlug(plugId: string) {
method getPlugs (line 127) | async getPlugs(orgId: string, integrationId: string) {
method updateIntegration (line 145) | async updateIntegration(id: string, params: Partial<Integration>) {
method disconnectChannel (line 196) | disconnectChannel(org: string, id: string) {
method createOrUpdateIntegration (line 208) | async createOrUpdateIntegration(
method needsToBeRefreshed (line 330) | needsToBeRefreshed() {
method setBetweenRefreshSteps (line 343) | async setBetweenRefreshSteps(id: string) {
method refreshNeeded (line 353) | refreshNeeded(org: string, id: string) {
method updateNameAndUrl (line 365) | updateNameAndUrl(id: string, name: string, url: string) {
method getIntegrationById (line 377) | getIntegrationById(org: string, id: string) {
method getIntegrationForOrder (line 386) | async getIntegrationForOrder(
method updateOnCustomerName (line 422) | async updateOnCustomerName(org: string, id: string, name: string) {
method updateIntegrationGroup (line 455) | updateIntegrationGroup(org: string, id: string, group: string) {
method customers (line 477) | customers(orgId: string) {
method getIntegrationsList (line 486) | getIntegrationsList(org: string) {
method disableChannel (line 498) | async disableChannel(org: string, id: string) {
method enableChannel (line 510) | async enableChannel(org: string, id: string) {
method getPostsForChannel (line 522) | getPostsForChannel(org: string, id: string) {
method deleteChannel (line 533) | deleteChannel(org: string, id: string) {
method checkForDeletedOnceAndUpdate (line 545) | async checkForDeletedOnceAndUpdate(org: string, page: string) {
method disableIntegrations (line 560) | async disableIntegrations(org: string, totalChannels: number) {
method getPlugsByIntegrationId (line 585) | getPlugsByIntegrationId(org: string, id: string) {
method createOrUpdatePlug (line 594) | createOrUpdatePlug(org: string, integrationId: string, body: PlugDto) {
method changePlugActivation (line 619) | changePlugActivation(orgId: string, plugId: string, status: boolean) {
method loadExisingData (line 631) | async loadExisingData(
method saveExisingData (line 647) | async saveExisingData(
method getPostingTimes (line 661) | async getPostingTimes(orgId: string, integrationsId?: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts
class IntegrationService (line 32) | class IntegrationService {
method constructor (line 34) | constructor(
method changeActiveCron (line 44) | async changeActiveCron(orgId: string) {
method getMentions (line 56) | getMentions(platform: string, q: string) {
method insertMentions (line 60) | insertMentions(
method setTimes (line 67) | async setTimes(
method updateProviderSettings (line 75) | updateProviderSettings(org: string, id: string, additionalSettings: st...
method checkPreviousConnections (line 83) | checkPreviousConnections(org: string, id: string) {
method createOrUpdateIntegration (line 87) | async createOrUpdateIntegration(
method updateIntegrationGroup (line 139) | updateIntegrationGroup(org: string, id: string, group: string) {
method updateOnCustomerName (line 143) | updateOnCustomerName(org: string, id: string, name: string) {
method getIntegrationsList (line 147) | getIntegrationsList(org: string) {
method getIntegrationForOrder (line 151) | getIntegrationForOrder(id: string, order: string, user: string, org: s...
method updateNameAndUrl (line 160) | updateNameAndUrl(id: string, name: string, url: string) {
method getIntegrationById (line 164) | getIntegrationById(org: string, id: string) {
method refreshToken (line 168) | async refreshToken(provider: SocialProvider, refresh: string) {
method disconnectChannel (line 183) | async disconnectChannel(orgId: string, integration: Integration) {
method informAboutRefreshError (line 188) | async informAboutRefreshError(
method refreshNeeded (line 203) | async refreshNeeded(org: string, id: string) {
method setBetweenRefreshSteps (line 207) | async setBetweenRefreshSteps(id: string) {
method refreshTokens (line 211) | async refreshTokens() {
method disableChannel (line 250) | async disableChannel(org: string, id: string) {
method enableChannel (line 254) | async enableChannel(org: string, totalChannels: number, id: string) {
method getPostsForChannel (line 268) | async getPostsForChannel(org: string, id: string) {
method deleteChannel (line 272) | async deleteChannel(org: string, id: string) {
method disableIntegrations (line 276) | async disableIntegrations(org: string, totalChannels: number) {
method checkForDeletedOnceAndUpdate (line 280) | async checkForDeletedOnceAndUpdate(org: string, page: string) {
method saveProviderPage (line 284) | async saveProviderPage(org: string, id: string, data: any) {
method checkAnalytics (line 329) | async checkAnalytics(
method customers (line 407) | customers(orgId: string) {
method getPlugsByIntegrationId (line 411) | getPlugsByIntegrationId(org: string, integrationId: string) {
method processInternalPlug (line 418) | async processInternalPlug(
method processPlugs (line 468) | async processPlugs(data: {
method createOrUpdatePlug (line 505) | async createOrUpdatePlug(
method changePlugActivation (line 521) | async changePlugActivation(orgId: string, plugId: string, status: bool...
method getPlugs (line 532) | async getPlugs(orgId: string, integrationId: string) {
method loadExisingData (line 536) | async loadExisingData(
method findFreeDateTime (line 550) | async findFreeDateTime(
FILE: libraries/nestjs-libraries/src/database/prisma/media/media.repository.ts
class MediaRepository (line 6) | class MediaRepository {
method constructor (line 7) | constructor(private _media: PrismaRepository<'media'>) {}
method saveFile (line 9) | saveFile(org: string, fileName: string, filePath: string, originalName...
method getMediaById (line 32) | getMediaById(id: string) {
method deleteMedia (line 40) | deleteMedia(org: string, id: string) {
method saveMediaInformation (line 52) | saveMediaInformation(org: string, data: SaveMediaInformationDto) {
method getMedia (line 75) | async getMedia(org: string, page: number) {
FILE: libraries/nestjs-libraries/src/database/prisma/media/media.service.ts
class MediaService (line 17) | class MediaService {
method constructor (line 20) | constructor(
method deleteMedia (line 27) | async deleteMedia(org: string, id: string) {
method getMediaById (line 31) | getMediaById(id: string) {
method generateImage (line 35) | async generateImage(
method saveFile (line 55) | saveFile(org: string, fileName: string, filePath: string, originalName...
method getMedia (line 59) | getMedia(org: string, page: number) {
method saveMediaInformation (line 63) | saveMediaInformation(org: string, data: SaveMediaInformationDto) {
method getVideoOptions (line 67) | getVideoOptions() {
method generateVideoAllowed (line 71) | async generateVideoAllowed(org: Organization, type: string) {
method generateVideo (line 84) | async generateVideo(org: Organization, body: VideoDto) {
method videoFunction (line 125) | async videoFunction(identifier: string, functionName: string, body: an...
FILE: libraries/nestjs-libraries/src/database/prisma/notifications/notification.service.ts
type NotificationType (line 9) | type NotificationType = 'success' | 'fail' | 'info';
class NotificationService (line 12) | class NotificationService {
method constructor (line 13) | constructor(
method getMainPageCount (line 20) | getMainPageCount(organizationId: string, userId: string) {
method getNotificationsPaginated (line 27) | getNotificationsPaginated(organizationId: string, page: number) {
method getNotifications (line 34) | getNotifications(organizationId: string, userId: string) {
method inAppNotification (line 41) | async inAppNotification(
method sendEmailsToOrg (line 88) | async sendEmailsToOrg(
method sendEmail (line 110) | async sendEmail(to: string, subject: string, html: string, replyTo?: s...
method hasEmailProvider (line 114) | hasEmailProvider() {
FILE: libraries/nestjs-libraries/src/database/prisma/notifications/notifications.repository.ts
class NotificationsRepository (line 5) | class NotificationsRepository {
method constructor (line 6) | constructor(
method getLastReadNotification (line 11) | getLastReadNotification(userId: string) {
method getMainPageCount (line 22) | async getMainPageCount(organizationId: string, userId: string) {
method createNotification (line 39) | async createNotification(organizationId: string, content: string) {
method getNotificationsSince (line 48) | async getNotificationsSince(organizationId: string, since: string) {
method getNotificationsPaginated (line 59) | async getNotificationsPaginated(organizationId: string, page: number) {
method getNotifications (line 95) | async getNotifications(organizationId: string, userId: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/oauth/oauth.repository.ts
class OAuthRepository (line 5) | class OAuthRepository {
method constructor (line 6) | constructor(
method getAppByOrgId (line 11) | getAppByOrgId(orgId: string) {
method getAppByClientId (line 23) | getAppByClientId(clientId: string) {
method createApp (line 35) | createApp(
method updateApp (line 62) | async updateApp(
method deleteApp (line 89) | async deleteApp(orgId: string) {
method updateClientSecret (line 107) | async updateClientSecret(orgId: string, newSecret: string) {
method createAuthorization (line 125) | createAuthorization(data: {
method findByCode (line 156) | findByCode(encryptedCode: string) {
method exchangeCodeForToken (line 165) | exchangeCodeForToken(id: string, encryptedToken: string) {
method findByAccessToken (line 176) | findByAccessToken(encryptedToken: string) {
method getApprovedApps (line 201) | getApprovedApps(userId: string) {
method revokeAuthorization (line 221) | revokeAuthorization(userId: string, authId: string) {
method revokeAllForApp (line 233) | revokeAllForApp(oauthAppId: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/oauth/oauth.service.ts
class OAuthService (line 9) | class OAuthService {
method constructor (line 10) | constructor(private _oauthRepository: OAuthRepository) {}
method getApp (line 12) | async getApp(orgId: string) {
method createApp (line 19) | async createApp(orgId: string, dto: CreateOAuthAppDto) {
method updateApp (line 44) | async updateApp(orgId: string, dto: UpdateOAuthAppDto) {
method deleteApp (line 53) | async deleteApp(orgId: string) {
method rotateSecret (line 63) | async rotateSecret(orgId: string) {
method validateAuthorizationRequest (line 75) | async validateAuthorizationRequest(clientId: string) {
method createAuthorizationCode (line 83) | async createAuthorizationCode(
method exchangeCodeForToken (line 103) | async exchangeCodeForToken(
method getOrgByOAuthToken (line 153) | async getOrgByOAuthToken(token: string) {
method getApprovedApps (line 158) | async getApprovedApps(userId: string) {
method revokeApp (line 162) | async revokeApp(userId: string, authId: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/organizations/organization.repository.ts
class OrganizationRepository (line 9) | class OrganizationRepository {
method constructor (line 10) | constructor(
method createMaxUser (line 16) | createMaxUser(id: string, name: string, saasName: string, email: strin...
method getOrgByApiKey (line 55) | getOrgByApiKey(api: string) {
method getCount (line 72) | getCount() {
method getUserOrg (line 76) | getUserOrg(id: string) {
method getImpersonateUser (line 106) | getImpersonateUser(name: string) {
method updateApiKey (line 147) | updateApiKey(orgId: string) {
method getOrgsByUserId (line 158) | async getOrgsByUserId(userId: string) {
method getOrgById (line 189) | async getOrgById(id: string) {
method addUserToOrg (line 197) | async addUserToOrg(
method createOrgAndUser (line 251) | async createOrgAndUser(
method getOrgByCustomerId (line 294) | getOrgByCustomerId(customerId: string) {
method setStreak (line 302) | async setStreak(organizationId: string, type: 'start' | 'end') {
method getTeam (line 321) | async getTeam(orgId: string) {
method getAllUsersOrgs (line 345) | getAllUsersOrgs(orgId: string) {
method deleteTeamMember (line 367) | async deleteTeamMember(orgId: string, userId: string) {
method disableOrEnableNonSuperAdminUsers (line 378) | disableOrEnableNonSuperAdminUsers(orgId: string, disable: boolean) {
method getShortlinkPreference (line 392) | getShortlinkPreference(orgId: string) {
method updateShortlinkPreference (line 403) | updateShortlinkPreference(orgId: string, shortlink: ShortLinkPreferenc...
FILE: libraries/nestjs-libraries/src/database/prisma/organizations/organization.service.ts
class OrganizationService (line 13) | class OrganizationService {
method constructor (line 14) | constructor(
method createOrgAndUser (line 18) | async createOrgAndUser(
method getCount (line 31) | async getCount() {
method createMaxUser (line 35) | async createMaxUser(id: string, name: string, saasName: string, email:...
method addUserToOrg (line 39) | addUserToOrg(
method getOrgById (line 48) | getOrgById(id: string) {
method getOrgByApiKey (line 52) | getOrgByApiKey(api: string) {
method getUserOrg (line 56) | getUserOrg(id: string) {
method getOrgsByUserId (line 60) | getOrgsByUserId(userId: string) {
method updateApiKey (line 64) | updateApiKey(orgId: string) {
method getTeam (line 68) | getTeam(orgId: string) {
method setStreak (line 72) | async setStreak(organizationId: string, type: 'start' | 'end') {
method getOrgByCustomerId (line 76) | getOrgByCustomerId(customerId: string) {
method inviteTeamMember (line 80) | async inviteTeamMember(orgId: string, body: AddTeamMemberDto) {
method deleteTeamMember (line 96) | async deleteTeamMember(org: Organization, userId: string) {
method disableOrEnableNonSuperAdminUsers (line 116) | disableOrEnableNonSuperAdminUsers(orgId: string, disable: boolean) {
method getShortlinkPreference (line 123) | getShortlinkPreference(orgId: string) {
method updateShortlinkPreference (line 127) | updateShortlinkPreference(orgId: string, shortlink: ShortLinkPreferenc...
FILE: libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts
class PostsRepository (line 21) | class PostsRepository {
method constructor (line 22) | constructor(
method searchForMissingThreeHoursPosts (line 31) | searchForMissingThreeHoursPosts() {
method getOldPosts (line 60) | getOldPosts(orgId: string, date: string) {
method updateImages (line 97) | updateImages(id: string, images: string) {
method getPostUrls (line 108) | getPostUrls(orgId: string, ids: string[]) {
method getPosts (line 123) | async getPosts(orgId: string, query: GetPostsDto) {
method getPostsList (line 215) | async getPostsList(orgId: string, query: GetPostsListDto) {
method deletePost (line 290) | async deletePost(orgId: string, group: string) {
method getPostsByGroup (line 313) | getPostsByGroup(orgId: string, group: string) {
method getPost (line 331) | getPost(
method updatePost (line 359) | updatePost(id: string, postId: string, releaseURL: string) {
method updateReleaseId (line 372) | updateReleaseId(id: string, orgId: string, releaseId: string) {
method changeState (line 385) | async changeState(id: string, state: State, err?: any, body?: any) {
method changeDate (line 422) | async changeDate(
method countPostsFromDay (line 449) | countPostsFromDay(orgId: string, date: Date) {
method createOrUpdatePost (line 471) | async createOrUpdatePost(
method submit (line 614) | async submit(id: string, order: string, buyerOrganizationId: string) {
method updateMessage (line 636) | updateMessage(id: string, messageId: string) {
method getPostById (line 647) | getPostById(id: string, org?: string) {
method findAllExistingCategories (line 675) | findAllExistingCategories() {
method findAllExistingTopicsOfCategory (line 684) | findAllExistingTopicsOfCategory(category: string) {
method findPopularPosts (line 696) | findPopularPosts(category: string, topic?: string) {
method createPopularPosts (line 709) | createPopularPosts(post: {
method getPostsCountsByDates (line 725) | async getPostsCountsByDates(
method getComments (line 755) | async getComments(postId: string) {
method getTags (line 766) | async getTags(orgId: string) {
method createTag (line 775) | createTag(orgId: string, body: CreateTagDto) {
method editTag (line 785) | editTag(id: string, orgId: string, body: CreateTagDto) {
method deleteTag (line 797) | deleteTag(id: string, orgId: string) {
method createComment (line 809) | createComment(
method getPostByForWebhookId (line 825) | async getPostByForWebhookId(postId: string) {
method getPostsSince (line 851) | async getPostsSince(orgId: string, since: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts
type PostWithConditionals (line 41) | type PostWithConditionals = Post & {
class PostsService (line 47) | class PostsService {
method constructor (line 49) | constructor(
method searchForMissingThreeHoursPosts (line 60) | searchForMissingThreeHoursPosts() {
method updatePost (line 64) | updatePost(id: string, postId: string, releaseURL: string) {
method getMissingContent (line 68) | async getMissingContent(
method updateReleaseId (line 128) | async updateReleaseId(orgId: string, postId: string, releaseId: string) {
method checkPostAnalytics (line 132) | async checkPostAnalytics(
method getStatistics (line 215) | async getStatistics(orgId: string, id: string) {
method mapTypeToPost (line 227) | async mapTypeToPost(
method getPostsRecursively (line 278) | async getPostsRecursively(
method getPosts (line 308) | async getPosts(orgId: string, query: GetPostsDto) {
method getPostsMinified (line 312) | async getPostsMinified(orgId: string, query: GetPostsDto) {
method getPostsList (line 318) | async getPostsList(orgId: string, query: GetPostsListDto) {
method updateMedia (line 324) | async updateMedia(id: string, imagesList: any[], convertToJPEG = false) {
method getPostsByGroup (line 423) | async getPostsByGroup(orgId: string, group: string) {
method arrangePostsByGroup (line 446) | arrangePostsByGroup(all: any, parent?: string): PostWithConditionals[] {
method getPost (line 464) | async getPost(orgId: string, id: string, convertToJPEG = false) {
method getOldPosts (line 486) | async getOldPosts(orgId: string, date: string) {
method updateTags (line 490) | public async updateTags(orgId: string, post: Post[]): Promise<Post[]> {
method checkInternalPlug (line 514) | public async checkInternalPlug(
method checkPlugs (line 556) | public async checkPlugs(
method deletePost (line 588) | async deletePost(orgId: string, group: string) {
method countPostsFromDay (line 619) | async countPostsFromDay(orgId: string, date: Date) {
method getPostByForWebhookId (line 623) | getPostByForWebhookId(id: string) {
method startWorkflow (line 627) | async startWorkflow(
method createPost (line 687) | async createPost(orgId: string, body: CreatePostDto): Promise<any[]> {
method separatePosts (line 732) | async separatePosts(content: string, len: number) {
method changeState (line 736) | async changeState(id: string, state: State, err?: any, body?: any) {
method changeDate (line 740) | async changeDate(
method generatePostsDraft (line 772) | async generatePostsDraft(orgId: string, body: CreateGeneratedPostsDto) {
method findAllExistingCategories (line 853) | findAllExistingCategories() {
method findAllExistingTopicsOfCategory (line 857) | findAllExistingTopicsOfCategory(category: string) {
method findPopularPosts (line 861) | findPopularPosts(category: string, topic?: string) {
method findFreeDateTime (line 865) | async findFreeDateTime(orgId: string, integrationId?: string) {
method createPopularPosts (line 877) | async createPopularPosts(post: {
method findFreeDateTimeRecursive (line 886) | private async findFreeDateTimeRecursive(
method getComments (line 911) | getComments(postId: string) {
method getTags (line 915) | getTags(orgId: string) {
method createTag (line 919) | createTag(orgId: string, body: CreateTagDto) {
method editTag (line 923) | editTag(id: string, orgId: string, body: CreateTagDto) {
method deleteTag (line 927) | deleteTag(id: string, orgId: string) {
method createComment (line 931) | createComment(
FILE: libraries/nestjs-libraries/src/database/prisma/prisma.service.ts
class PrismaService (line 5) | class PrismaService extends PrismaClient implements OnModuleInit, OnModu...
method constructor (line 6) | constructor() {
method onModuleInit (line 16) | async onModuleInit() {
method onModuleDestroy (line 20) | async onModuleDestroy() {
class PrismaRepository (line 26) | class PrismaRepository<T extends keyof PrismaService> {
method constructor (line 28) | constructor(private _prismaService: PrismaService) {
class PrismaTransaction (line 34) | class PrismaTransaction {
method constructor (line 36) | constructor(private _prismaService: PrismaService) {
FILE: libraries/nestjs-libraries/src/database/prisma/sets/sets.repository.ts
class SetsRepository (line 7) | class SetsRepository {
method constructor (line 8) | constructor(private _sets: PrismaRepository<'sets'>) {}
method getTotal (line 10) | getTotal(orgId: string) {
method getSets (line 18) | getSets(orgId: string) {
method deleteSet (line 29) | deleteSet(orgId: string, id: string) {
method createSet (line 38) | async createSet(orgId: string, body: SetsDto) {
FILE: libraries/nestjs-libraries/src/database/prisma/sets/sets.service.ts
class SetsService (line 6) | class SetsService {
method constructor (line 7) | constructor(private _setsRepository: SetsRepository) {}
method getTotal (line 9) | getTotal(orgId: string) {
method getSets (line 13) | getSets(orgId: string) {
method createSet (line 17) | createSet(orgId: string, body: SetsDto) {
method deleteSet (line 21) | deleteSet(orgId: string, id: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/signatures/signature.repository.ts
class SignatureRepository (line 7) | class SignatureRepository {
method constructor (line 8) | constructor(private _signatures: PrismaRepository<'signatures'>) {}
method getSignaturesByOrgId (line 10) | getSignaturesByOrgId(orgId: string) {
method getDefaultSignature (line 16) | getDefaultSignature(orgId: string) {
method createOrUpdateSignature (line 22) | async createOrUpdateSignature(
method deleteSignature (line 49) | deleteSignature(orgId: string, id: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/signatures/signature.service.ts
class SignatureService (line 6) | class SignatureService {
method constructor (line 7) | constructor(private _signatureRepository: SignatureRepository) {}
method getSignaturesByOrgId (line 9) | getSignaturesByOrgId(orgId: string) {
method getDefaultSignature (line 13) | getDefaultSignature(orgId: string) {
method createOrUpdateSignature (line 17) | createOrUpdateSignature(orgId: string, signature: SignatureDto, id?: s...
method deleteSignature (line 25) | deleteSignature(orgId: string, id: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/subscriptions/pricing.ts
type PricingInnerInterface (line 1) | interface PricingInnerInterface {
type PricingInterface (line 19) | interface PricingInterface {
FILE: libraries/nestjs-libraries/src/database/prisma/subscriptions/subscription.repository.ts
class SubscriptionRepository (line 10) | class SubscriptionRepository {
method constructor (line 11) | constructor(
method getUserAccount (line 19) | getUserAccount(userId: string) {
method getCode (line 31) | getCode(code: string) {
method updateAccount (line 39) | updateAccount(userId: string, account: string) {
method getSubscriptionByOrganizationId (line 50) | getSubscriptionByOrganizationId(organizationId: string) {
method updateConnectedStatus (line 59) | updateConnectedStatus(account: string, accountCharges: boolean) {
method getCustomerIdByOrgId (line 70) | getCustomerIdByOrgId(organizationId: string) {
method checkSubscription (line 81) | checkSubscription(organizationId: string, subscriptionId: string) {
method deleteSubscriptionByCustomerId (line 91) | deleteSubscriptionByCustomerId(customerId: string) {
method updateCustomerId (line 101) | updateCustomerId(organizationId: string, customerId: string) {
method getSubscriptionByOrgId (line 112) | async getSubscriptionByOrgId(orgId: string) {
method getSubscriptionByCustomerId (line 120) | async getSubscriptionByCustomerId(customerId: string) {
method getOrganizationByCustomerId (line 130) | async getOrganizationByCustomerId(customerId: string) {
method createOrUpdateSubscription (line 138) | async createOrUpdateSubscription(
method getSubscriptionByIdentifier (line 208) | getSubscriptionByIdentifier(identifier: string) {
method getSubscription (line 220) | getSubscription(organizationId: string) {
method getCreditsFrom (line 229) | async getCreditsFrom(
method useCredit (line 251) | async useCredit<T>(
method setCustomerId (line 276) | setCustomerId(orgId: string, customerId: string) {
FILE: libraries/nestjs-libraries/src/database/prisma/subscriptions/subscription.service.ts
class SubscriptionService (line 11) | class SubscriptionService {
method constructor (line 12) | constructor(
method getSubscriptionByOrganizationId (line 18) | getSubscriptionByOrganizationId(organizationId: string) {
method useCredit (line 24) | useCredit<T>(
method getCode (line 32) | getCode(code: string) {
method deleteSubscription (line 36) | async deleteSubscription(customerId: string) {
method updateCustomerId (line 47) | updateCustomerId(organizationId: string, customerId: string) {
method checkSubscription (line 54) | async checkSubscription(organizationId: string, subscriptionId: string) {
method modifySubscriptionByOrg (line 61) | async modifySubscriptionByOrg(
method modifySubscription (line 110) | async modifySubscription(
method createOrUpdateSubscription (line 173) | async createOrUpdateSubscription(
method getSubscriptionByIdentifier (line 211) | getSubscriptionByIdentifier(identifier: string) {
method getSubscription (line 215) | async getSubscription(organizationId: string) {
method checkCredits (line 219) | async checkCredits(organization: Organization, checkType = 'ai_images') {
method lifeTime (line 250) | async lifeTime(orgId: string, identifier: string, subscription: any) {
method addSubscription (line 264) | async addSubscription(orgId: string, userId: string, subscription: any) {
FILE: libraries/nestjs-libraries/src/database/prisma/third-party/third-party.repository.ts
class ThirdPartyRepository (line 6) | class ThirdPartyRepository {
method constructor (line 7) | constructor(private _thirdParty: PrismaRepository<'thirdParty'>) {}
method getAllThirdPartiesByOrganization (line 9) | getAllThirdPartiesByOrganization(org: string) {
method deleteIntegration (line 20) | deleteIntegration(org: string, id: string) {
method getIntegrationById (line 27) | getIntegrationById(org: string, id: string) {
method saveIntegration (line 33) | saveIntegration(
FILE: libraries/nestjs-libraries/src/database/prisma/third-party/third-party.service.ts
class ThirdPartyService (line 5) | class ThirdPartyService {
method constructor (line 6) | constructor(private _thirdPartyRepository: ThirdPartyRepository) {}
method getAllThirdPartiesByOrganization (line 8) | getAllThirdPartiesByOrganization(org: string) {
method deleteIntegration (line 12) | deleteIntegration(org: string, id: string) {
method getIntegrationById (line 16) | getIntegrationById(org: string, id: string) {
method saveIntegration (line 20) | saveIntegration(
FILE: libraries/nestjs-libraries/src/database/prisma/users/users.repository.ts
class UsersRepository (line 9) | class UsersRepository {
method constructor (line 10) | constructor(private _user: PrismaRepository<'user'>) {}
method getImpersonateUser (line 12) | getImpersonateUser(name: string) {
method getUserById (line 42) | getUserById(id: string) {
method getUserByEmail (line 50) | getUserByEmail(email: string) {
method activateUser (line 67) | activateUser(id: string) {
method getUserByProvider (line 78) | getUserByProvider(providerId: string, provider: Provider) {
method updatePassword (line 87) | updatePassword(id: string, password: string) {
method changeAudienceSize (line 99) | changeAudienceSize(userId: string, audience: number) {
method getPersonal (line 110) | async getPersonal(userId: string) {
method changePersonal (line 131) | async changePersonal(userId: string, body: UserDetailDto) {
method getEmailNotifications (line 152) | async getEmailNotifications(userId: string) {
method updateEmailNotifications (line 165) | async updateEmailNotifications(userId: string, body: EmailNotification...
FILE: libraries/nestjs-libraries/src/database/prisma/users/users.service.ts
class UsersService (line 9) | class UsersService {
method constructor (line 10) | constructor(
method getUserByEmail (line 15) | getUserByEmail(email: string) {
method getUserById (line 19) | getUserById(id: string) {
method getImpersonateUser (line 23) | getImpersonateUser(name: string) {
method getUserByProvider (line 27) | getUserByProvider(providerId: string, provider: Provider) {
method activateUser (line 31) | activateUser(id: string) {
method updatePassword (line 35) | updatePassword(id: string, password: string) {
method getPersonal (line 39) | getPersonal(userId: string) {
method changePersonal (line 43) | changePersonal(userId: string, body: UserDetailDto) {
method getEmailNotifications (line 47) | getEmailNotifications(userId: string) {
method updateEmailNotifications (line 51) | updateEmailNotifications(userId: string, body: EmailNotificationsDto) {
FILE: libraries/nestjs-libraries/src/database/prisma/webhooks/webhooks.repository.ts
class WebhooksRepository (line 7) | class WebhooksRepository {
method constructor (line 8) | constructor(private _webhooks: PrismaRepository<'webhooks'>) {}
method getTotal (line 10) | getTotal(orgId: string) {
method getWebhooks (line 19) | getWebhooks(orgId: string) {
method deleteWebhook (line 41) | deleteWebhook(orgId: string, id: string) {
method createWebhook (line 53) | async createWebhook(orgId: string, body: WebhooksDto) {
FILE: libraries/nestjs-libraries/src/database/prisma/webhooks/webhooks.service.ts
class WebhooksService (line 6) | class WebhooksService {
method constructor (line 7) | constructor(private _webhooksRepository: WebhooksRepository) {}
method getTotal (line 9) | getTotal(orgId: string) {
method getWebhooks (line 13) | getWebhooks(orgId: string) {
method createWebhook (line 17) | createWebhook(orgId: string, body: WebhooksDto) {
method deleteWebhook (line 21) | deleteWebhook(orgId: string, id: string) {
FILE: libraries/nestjs-libraries/src/dtos/agencies/create.agency.dto.ts
class CreateAgencyLogoDto (line 14) | class CreateAgencyLogoDto {
class CreateAgencyDto (line 21) | class CreateAgencyDto {
FILE: libraries/nestjs-libraries/src/dtos/analytics/stars.list.dto.ts
class StarsListDto (line 3) | class StarsListDto {
FILE: libraries/nestjs-libraries/src/dtos/auth/create.org.user.dto.ts
class CreateOrgUserDto (line 11) | class CreateOrgUserDto {
FILE: libraries/nestjs-libraries/src/dtos/auth/forgot-return.password.dto.ts
class ForgotReturnPasswordDto (line 10) | class ForgotReturnPasswordDto {
FILE: libraries/nestjs-libraries/src/dtos/auth/forgot.password.dto.ts
class ForgotPasswordDto (line 3) | class ForgotPasswordDto {
FILE: libraries/nestjs-libraries/src/dtos/auth/login.user.dto.ts
class LoginUserDto (line 10) | class LoginUserDto {
FILE: libraries/nestjs-libraries/src/dtos/auth/resend-activation.dto.ts
class ResendActivationDto (line 3) | class ResendActivationDto {
FILE: libraries/nestjs-libraries/src/dtos/autopost/autopost.dto.ts
class Integrations (line 12) | class Integrations {
class AutopostDto (line 18) | class AutopostDto {
FILE: libraries/nestjs-libraries/src/dtos/billing/billing.subscribe.dto.ts
class BillingSubscribeDto (line 3) | class BillingSubscribeDto {
FILE: libraries/nestjs-libraries/src/dtos/comments/add.comment.dto.ts
class AddCommentDto (line 1) | class AddCommentDto {
FILE: libraries/nestjs-libraries/src/dtos/generator/create.generated.posts.dto.ts
class InnerPost (line 12) | class InnerPost {
class PostGroup (line 18) | class PostGroup {
class CreateGeneratedPostsDto (line 27) | class CreateGeneratedPostsDto {
FILE: libraries/nestjs-libraries/src/dtos/generator/generator.dto.ts
class GeneratorDto (line 3) | class GeneratorDto {
FILE: libraries/nestjs-libraries/src/dtos/integrations/api.key.dto.ts
class ApiKeyDto (line 3) | class ApiKeyDto {
FILE: libraries/nestjs-libraries/src/dtos/integrations/connect.integration.dto.ts
class ConnectIntegrationDto (line 3) | class ConnectIntegrationDto {
FILE: libraries/nestjs-libraries/src/dtos/integrations/integration.function.dto.ts
class IntegrationFunctionDto (line 3) | class IntegrationFunctionDto {
FILE: libraries/nestjs-libraries/src/dtos/integrations/integration.time.dto.ts
class IntegrationValidateTimeDto (line 4) | class IntegrationValidateTimeDto {
class IntegrationTimeDto (line 9) | class IntegrationTimeDto {
FILE: libraries/nestjs-libraries/src/dtos/media/media.dto.ts
class MediaDto (line 4) | class MediaDto {
FILE: libraries/nestjs-libraries/src/dtos/media/save.media.information.dto.ts
class SaveMediaInformationDto (line 3) | class SaveMediaInformationDto {
FILE: libraries/nestjs-libraries/src/dtos/media/upload.dto.ts
class UploadDto (line 4) | class UploadDto {
FILE: libraries/nestjs-libraries/src/dtos/notifications/get.notifications.dto.ts
class GetNotificationsDto (line 4) | class GetNotificationsDto {
FILE: libraries/nestjs-libraries/src/dtos/oauth/authorize-oauth.dto.ts
class AuthorizeOAuthQueryDto (line 3) | class AuthorizeOAuthQueryDto {
class ApproveOAuthDto (line 18) | class ApproveOAuthDto {
FILE: libraries/nestjs-libraries/src/dtos/oauth/create-oauth-app.dto.ts
class CreateOAuthAppDto (line 3) | class CreateOAuthAppDto {
FILE: libraries/nestjs-libraries/src/dtos/oauth/token-exchange.dto.ts
class TokenExchangeDto (line 3) | class TokenExchangeDto {
FILE: libraries/nestjs-libraries/src/dtos/oauth/update-oauth-app.dto.ts
class UpdateOAuthAppDto (line 3) | class UpdateOAuthAppDto {
FILE: libraries/nestjs-libraries/src/dtos/plugs/plug.dto.ts
class FieldsDto (line 4) | class FieldsDto {
class PlugDto (line 14) | class PlugDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/create.post.dto.ts
class Integration (line 24) | class Integration {
class PostContent (line 30) | class PostContent {
class Post (line 50) | class Post {
class Tags (line 81) | class Tags {
class CreatePostDto (line 91) | class CreatePostDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/create.tag.dto.ts
class CreateTagDto (line 3) | class CreateTagDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts
class GetPostsDto (line 7) | class GetPostsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/get.posts.list.dto.ts
class GetPostsListDto (line 10) | class GetPostsListDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/all.providers.settings.ts
type ProviderExtension (line 28) | type ProviderExtension<T extends string, M> = { __type: T } & M;
type AllProvidersSettings (line 29) | type AllProvidersSettings =
type None (line 64) | type None = NonNullable<unknown>;
class EmptySettings (line 104) | class EmptySettings {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/dev.to.settings.dto.ts
class DevToSettingsDto (line 16) | class DevToSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/dev.to.tags.settings.dto.ts
class DevToTagsSettingsDto (line 3) | class DevToTagsSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/discord.dto.ts
class DiscordDto (line 4) | class DiscordDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/dribbble.dto.ts
class DribbbleDto (line 9) | class DribbbleDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/facebook.dto.ts
class FacebookDto (line 3) | class FacebookDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/farcaster.dto.ts
class FarcasterId (line 4) | class FarcasterId {
class FarcasterValue (line 8) | class FarcasterValue {
class FarcasterDto (line 13) | class FarcasterDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/gmb.settings.dto.ts
class GmbSettingsDto (line 3) | class GmbSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/hashnode.settings.dto.ts
class HashnodeTagsSettings (line 15) | class HashnodeTagsSettings {
class HashnodeSettingsDto (line 23) | class HashnodeSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/instagram.dto.ts
class Collaborators (line 11) | class Collaborators {
class InstagramDto (line 16) | class InstagramDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/kick.dto.ts
class KickDto (line 1) | class KickDto {}
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/lemmy.dto.ts
class LemmySettingsDtoInner (line 13) | class LemmySettingsDtoInner {
class LemmySettingsValueDto (line 34) | class LemmySettingsValueDto {
class LemmySettingsDto (line 41) | class LemmySettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/linkedin.dto.ts
class LinkedinDto (line 3) | class LinkedinDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/listmonk.dto.ts
class ListmonkDto (line 4) | class ListmonkDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/medium.settings.dto.ts
class MediumTagsSettings (line 14) | class MediumTagsSettings {
class MediumSettingsDto (line 22) | class MediumSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/mewe.dto.ts
class MeweDto (line 4) | class MeweDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/moltbook.dto.ts
class MoltbookDto (line 3) | class MoltbookDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/pinterest.dto.ts
class PinterestSettingsDto (line 6) | class PinterestSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/reddit.dto.ts
class RedditFlairDto (line 15) | class RedditFlairDto {
class RedditSettingsDtoInner (line 25) | class RedditSettingsDtoInner {
class RedditSettingsValueDto (line 66) | class RedditSettingsValueDto {
class RedditSettingsDto (line 73) | class RedditSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/skool.dto.ts
class SkoolDto (line 4) | class SkoolDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/slack.dto.ts
class SlackDto (line 4) | class SlackDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/tiktok.dto.ts
class TikTokDto (line 5) | class TikTokDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/twitch.dto.ts
class TwitchDto (line 3) | class TwitchDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/whop.dto.ts
class WhopDto (line 4) | class WhopDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/wordpress.dto.ts
class WordpressDto (line 11) | class WordpressDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/x.dto.ts
class XDto (line 3) | class XDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/providers-settings/youtube.settings.dto.ts
class YoutubeTagsSettings (line 7) | class YoutubeTagsSettings {
class YoutubeSettingsDto (line 15) | class YoutubeSettingsDto {
FILE: libraries/nestjs-libraries/src/dtos/posts/transformers/integration.settings.transformer.ts
class IntegrationSettingsTransformer (line 6) | class IntegrationSettingsTransformer {
method constructor (line 7) | constructor(private integrationService: IntegrationService) {}
method transformPost (line 9) | async transformPost(post: any, orgId: string) {
FILE: libraries/nestjs-libraries/src/dtos/sets/sets.dto.ts
class SetsDto (line 3) | class SetsDto {
class UpdateSetsDto (line 17) | class UpdateSetsDto {
FILE: libraries/nestjs-libraries/src/dtos/settings/add.team.member.dto.ts
class AddTeamMemberDto (line 10) | class AddTeamMemberDto {
FILE: libraries/nestjs-libraries/src/dtos/settings/shortlink-preference.dto.ts
class ShortlinkPreferenceDto (line 4) | class ShortlinkPreferenceDto {
FILE: libraries/nestjs-libraries/src/dtos/signature/signature.dto.ts
class SignatureDto (line 3) | class SignatureDto {
FILE: libraries/nestjs-libraries/src/dtos/users/email-notifications.dto.ts
class EmailNotificationsDto (line 3) | class EmailNotificationsDto {
FILE: libraries/nestjs-libraries/src/dtos/users/user.details.dto.ts
class UserDetailDto (line 9) | class UserDetailDto {
FILE: libraries/nestjs-libraries/src/dtos/videos/video.dto.ts
class ValidIn (line 7) | class ValidIn implements ValidatorConstraintInterface {
method _load (line 8) | private _load() {
method validate (line 14) | validate(text: string, args: ValidationArguments) {
method defaultMessage (line 20) | defaultMessage(args: ValidationArguments) {
class VideoDto (line 26) | class VideoDto {
FILE: libraries/nestjs-libraries/src/dtos/videos/video.function.dto.ts
class VideoFunctionDto (line 3) | class VideoFunctionDto {
FILE: libraries/nestjs-libraries/src/dtos/webhooks/webhooks.dto.ts
class WebhooksIntegrationDto (line 4) | class WebhooksIntegrationDto {
class WebhooksDto (line 10) | class WebhooksDto {
class UpdateDto (line 27) | class UpdateDto {
FILE: libraries/nestjs-libraries/src/emails/email.interface.ts
type EmailInterface (line 1) | interface EmailInterface {
FILE: libraries/nestjs-libraries/src/emails/empty.provider.ts
class EmptyProvider (line 3) | class EmptyProvider implements EmailInterface {
method sendEmail (line 6) | async sendEmail(to: string, subject: string, html: string) {
FILE: libraries/nestjs-libraries/src/emails/node.mailer.provider.ts
class NodeMailerProvider (line 14) | class NodeMailerProvider implements EmailInterface {
method sendEmail (line 23) | async sendEmail(
FILE: libraries/nestjs-libraries/src/emails/resend.provider.ts
class ResendProvider (line 6) | class ResendProvider implements EmailInterface {
method sendEmail (line 9) | async sendEmail(
FILE: libraries/nestjs-libraries/src/integrations/integration.manager.ts
class IntegrationManager (line 78) | class IntegrationManager {
method getAllIntegrations (line 79) | async getAllIntegrations() {
method getAllTools (line 98) | getAllTools(): {
method getAllRulesDescription (line 116) | getAllRulesDescription(): {
method getAllPlugs (line 132) | getAllPlugs() {
method getInternalPlugs (line 154) | getInternalPlugs(providerName: string) {
method getAllowedSocialsIntegrations (line 167) | getAllowedSocialsIntegrations() {
method getSocialIntegration (line 170) | getSocialIntegration(integration: string): SocialProvider {
FILE: libraries/nestjs-libraries/src/integrations/integration.missing.scopes.ts
class NotEnoughScopesFilter (line 7) | class NotEnoughScopesFilter implements ExceptionFilter {
method catch (line 8) | catch(exception: NotEnoughScopes, host: ArgumentsHost) {
FILE: libraries/nestjs-libraries/src/integrations/refresh.integration.service.ts
class RefreshIntegrationService (line 12) | class RefreshIntegrationService {
method constructor (line 13) | constructor(
method refresh (line 19) | async refresh(integration: Integration): Promise<false | AuthTokenDeta...
method setBetweenSteps (line 47) | public async setBetweenSteps(integration: Integration) {
method startRefreshWorkflow (line 55) | public async startRefreshWorkflow(orgId: string, id: string, integrati...
method refreshProcess (line 70) | private async refreshProcess(
FILE: libraries/nestjs-libraries/src/integrations/social.abstract.ts
class RefreshToken (line 5) | class RefreshToken extends ApplicationFailure {
method constructor (line 6) | constructor(identifier: string, json: string, body: BodyInit, message ...
class BadBody (line 17) | class BadBody extends ApplicationFailure {
method constructor (line 18) | constructor(identifier: string, json: string, body: BodyInit, message ...
class NotEnoughScopes (line 29) | class NotEnoughScopes {
method constructor (line 30) | constructor(
function safeStringify (line 35) | function safeStringify(obj: any) {
method handleErrors (line 53) | public handleErrors(
method mention (line 61) | public async mention(
method runInConcurrent (line 73) | async runInConcurrent<T>(
method fetch (line 100) | async fetch(
method checkScopes (line 174) | checkScopes(required: string[], got: string | string[]) {
FILE: libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts
function reduceImageBySize (line 31) | async function reduceImageBySize(url: string, maxSizeKB = 976) {
function uploadVideo (line 64) | async function uploadVideo(
class BlueskyProvider (line 148) | class BlueskyProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 156) | maxLength() {
method customFields (line 160) | async customFields() {
method refreshToken (line 184) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 196) | async generateAuthUrl() {
method authenticate (line 205) | async authenticate(params: {
method getAgent (line 243) | private async getAgent(integration: Integration) {
method uploadMediaForPost (line 263) | private async uploadMediaForPost(
method post (line 312) | async post(
method comment (line 347) | async comment(
method autoRepostPost (line 427) | async autoRepostPost(
method autoPlugPost (line 488) | async autoPlugPost(
method mention (line 542) | override async mention(
method mentionFormat (line 572) | mentionFormat(idOrHandle: string, name: string) {
FILE: libraries/nestjs-libraries/src/integrations/social/dev.to.provider.ts
class DevToProvider (line 14) | class DevToProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 21) | maxLength() {
method generateAuthUrl (line 26) | async generateAuthUrl() {
method handleErrors (line 35) | override handleErrors(body: string) {
method refreshToken (line 46) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method customFields (line 58) | async customFields() {
method authenticate (line 69) | async authenticate(params: {
method tags (line 99) | async tags(token: string) {
method organizations (line 112) | async organizations(token: string) {
method post (line 147) | async post(
FILE: libraries/nestjs-libraries/src/integrations/social/discord.provider.ts
class DiscordProvider (line 13) | class DiscordProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 20) | maxLength() {
method refreshToken (line 25) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 62) | async generateAuthUrl() {
method authenticate (line 75) | async authenticate(params: {
method channels (line 121) | async channels(accessToken: string, params: any, id: string) {
method post (line 138) | async post(
method comment (line 193) | async comment(
method changeNickname (line 282) | async changeNickname(id: string, accessToken: string, name: string) {
method mention (line 301) | override async mention(
method mentionFormat (line 365) | mentionFormat(idOrHandle: string, name: string) {
FILE: libraries/nestjs-libraries/src/integrations/social/dribbble.provider.ts
class DribbbleProvider (line 17) | class DribbbleProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 24) | maxLength() {
method refreshToken (line 29) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method teams (line 69) | async teams(accessToken: string) {
method generateAuthUrl (line 87) | async generateAuthUrl() {
method authenticate (line 100) | async authenticate(params: {
method post (line 136) | async post(
method analytics (line 183) | analytics(
method postAnalytics (line 191) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts
class FacebookProvider (line 15) | class FacebookProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 29) | maxLength() {
method handleErrors (line 34) | override handleErrors(body: string):
method refreshToken (line 161) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 173) | async generateAuthUrl() {
method reConnect (line 189) | async reConnect(
method authenticate (line 207) | async authenticate(params: {
method pages (line 264) | async pages(accessToken: string) {
method fetchPageInformation (line 325) | async fetchPageInformation(accessToken: string, data: { page: string }) {
method post (line 395) | async post(
method comment (line 494) | async comment(
method analytics (line 534) | async analytics(
method postAnalytics (line 569) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/farcaster.provider.ts
class FarcasterProvider (line 23) | class FarcasterProvider
method maxLength (line 34) | maxLength() {
method refreshToken (line 39) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 51) | async generateAuthUrl() {
method authenticate (line 60) | async authenticate(params: {
method post (line 77) | async post(
method comment (line 119) | async comment(
method subreddits (line 165) | async subreddits(
FILE: libraries/nestjs-libraries/src/integrations/social/gmb.provider.ts
class GmbProvider (line 37) | class GmbProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 50) | maxLength() {
method handleErrors (line 54) | override handleErrors(body: string):
method refreshToken (line 107) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 130) | async generateAuthUrl() {
method authenticate (line 146) | async authenticate(params: {
method pages (line 176) | async pages(accessToken: string) {
method fetchPageInformation (line 298) | async fetchPageInformation(
method reConnect (line 353) | async reConnect(
method post (line 380) | async post(
method formatDate (line 477) | private formatDate(dateString?: string): any {
method formatTime (line 493) | private formatTime(timeString?: string): any {
method analytics (line 506) | async analytics(
method postAnalytics (line 590) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/hashnode.provider.ts
class HashnodeProvider (line 16) | class HashnodeProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 23) | maxLength() {
method generateAuthUrl (line 28) | async generateAuthUrl() {
method refreshToken (line 37) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method customFields (line 49) | async customFields() {
method authenticate (line 60) | async authenticate(params: {
method tags (line 107) | async tags() {
method tagsList (line 112) | tagsList() {
method publications (line 117) | async publications(accessToken: string) {
method post (line 158) | async post(
FILE: libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts
class InstagramProvider (line 19) | class InstagramProvider
method maxLength (line 39) | maxLength() {
method refreshToken (line 43) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method handleErrors (line 55) | public override handleErrors(body: string):
method reConnect (line 318) | async reConnect(
method generateAuthUrl (line 341) | async generateAuthUrl() {
method authenticate (line 357) | async authenticate(params: {
method pages (line 414) | async pages(accessToken: string) {
method fetchPageInformation (line 496) | async fetchPageInformation(
method post (line 521) | async post(
method comment (line 713) | async comment(
method setTitle (line 752) | private setTitle(name: string) {
method analytics (line 794) | async analytics(
method music (line 847) | music(accessToken: string, data: { q: string }) {
method postAnalytics (line 855) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/instagram.standalone.provider.ts
class InstagramStandaloneProvider (line 20) | class InstagramStandaloneProvider
method maxLength (line 38) | maxLength() {
method handleErrors (line 42) | public override handleErrors(
method refreshToken (line 50) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 79) | async generateAuthUrl() {
method authenticate (line 99) | async authenticate(params: {
method post (line 154) | async post(
method comment (line 169) | async comment(
method analytics (line 188) | async analytics(id: string, accessToken: string, date: number) {
method postAnalytics (line 197) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/kick.provider.ts
class KickProvider (line 14) | class KickProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 23) | maxLength() {
method generatePKCE (line 27) | private generatePKCE() {
method refreshToken (line 40) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 70) | async generateAuthUrl() {
method authenticate (line 93) | async authenticate(params: {
method getUserInfo (line 134) | private async getUserInfo(
method post (line 156) | async post(
method comment (line 191) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/lemmy.provider.ts
class LemmyProvider (line 15) | class LemmyProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 22) | maxLength() {
method customFields (line 27) | async customFields() {
method refreshToken (line 51) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 63) | async generateAuthUrl() {
method authenticate (line 72) | async authenticate(params: {
method getJwtAndService (line 123) | private async getJwtAndService(integration: Integration): Promise<{ jw...
method post (line 144) | async post(
method comment (line 211) | async comment(
method subreddits (line 269) | async subreddits(
FILE: libraries/nestjs-libraries/src/integrations/social/linkedin.page.provider.ts
class LinkedinPageProvider (line 19) | class LinkedinPageProvider
method refreshToken (line 40) | override async refreshToken(
method addComment (line 93) | override async addComment(
method repostPostUsers (line 108) | override async repostPostUsers(
method generateAuthUrl (line 123) | override async generateAuthUrl() {
method companies (line 138) | async companies(accessToken: string) {
method reConnect (line 163) | async reConnect(
method fetchPageInformation (line 181) | async fetchPageInformation(accessToken: string, params: { page: string...
method authenticate (line 204) | override async authenticate(params: {
method post (line 267) | override async post(
method comment (line 276) | override async comment(
method analytics (line 295) | async analytics(
method postAnalytics (line 420) | async postAnalytics(
method autoRepostPost (line 563) | async autoRepostPost(
method autoPlugPost (line 641) | async autoPlugPost(
type Root (line 691) | interface Root {
type TotalPageStatistics (line 714) | interface TotalPageStatistics {
type Clicks (line 719) | interface Clicks {
type Views (line 724) | interface Views {
type MobileProductsPageViews (line 754) | interface MobileProductsPageViews {
type AllDesktopPageViews (line 759) | interface AllDesktopPageViews {
type InsightsPageViews (line 764) | interface InsightsPageViews {
type MobileAboutPageViews (line 769) | interface MobileAboutPageViews {
type AllMobilePageViews (line 774) | interface AllMobilePageViews {
type ProductsPageViews (line 779) | interface ProductsPageViews {
type DesktopProductsPageViews (line 784) | interface DesktopProductsPageViews {
type JobsPageViews (line 789) | interface JobsPageViews {
type PeoplePageViews (line 794) | interface PeoplePageViews {
type OverviewPageViews (line 799) | interface OverviewPageViews {
type MobileOverviewPageViews (line 804) | interface MobileOverviewPageViews {
type LifeAtPageViews (line 809) | interface LifeAtPageViews {
type DesktopOverviewPageViews (line 814) | interface DesktopOverviewPageViews {
type MobileCareersPageViews (line 819) | interface MobileCareersPageViews {
type AllPageViews (line 824) | interface AllPageViews {
type CareersPageViews (line 829) | interface CareersPageViews {
type MobileJobsPageViews (line 834) | interface MobileJobsPageViews {
type MobileLifeAtPageViews (line 839) | interface MobileLifeAtPageViews {
type DesktopJobsPageViews (line 844) | interface DesktopJobsPageViews {
type DesktopPeoplePageViews (line 849) | interface DesktopPeoplePageViews {
type AboutPageViews (line 854) | interface AboutPageViews {
type DesktopAboutPageViews (line 859) | interface DesktopAboutPageViews {
type MobilePeoplePageViews (line 864) | interface MobilePeoplePageViews {
type DesktopCareersPageViews (line 869) | interface DesktopCareersPageViews {
type DesktopInsightsPageViews (line 874) | interface DesktopInsightsPageViews {
type DesktopLifeAtPageViews (line 879) | interface DesktopLifeAtPageViews {
type MobileInsightsPageViews (line 884) | interface MobileInsightsPageViews {
type TimeRange (line 889) | interface TimeRange {
type PostShareStatElement (line 895) | interface PostShareStatElement {
type SocialActionsResponse (line 910) | interface SocialActionsResponse {
FILE: libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts
class LinkedinProvider (line 22) | class LinkedinProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 40) | maxLength() {
method handleErrors (line 44) | override handleErrors(
method refreshToken (line 66) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 117) | async generateAuthUrl() {
method authenticate (line 132) | async authenticate(params: {
method company (line 197) | async company(token: string, data: { url: string }) {
method uploadPicture (line 229) | protected async uploadPicture(
method fixText (line 335) | protected fixText(text: string) {
method convertImagesToPdfCarousel (line 370) | private async convertImagesToPdfCarousel(
method streamToBuffer (line 421) | private async streamToBuffer(stream: Readable): Promise<Buffer> {
method processMediaForPosts (line 430) | private async processMediaForPosts(
method prepareMediaBuffer (line 479) | private async prepareMediaBuffer(mediaUrl: string): Promise<Buffer> {
method buildPostContent (line 494) | private buildPostContent(isPdf: boolean, mediaIds: string[], pdfTitle?...
method createLinkedInPostPayload (line 519) | private createLinkedInPostPayload(
method createMainPost (line 545) | private async createMainPost(
method createCommentPost (line 584) | private async createCommentPost(
method createPostResponse (line 618) | private createPostResponse(
method post (line 635) | async post(
method comment (line 682) | async comment(
method addComment (line 718) | async addComment(
method repostPostUsers (line 752) | async repostPostUsers(
method mention (line 787) | override async mention(token: string, data: { query: string }) {
method mentionFormat (line 813) | mentionFormat(idOrHandle: string, name: string) {
FILE: libraries/nestjs-libraries/src/integrations/social/listmonk.provider.ts
class ListmonkProvider (line 16) | class ListmonkProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 25) | maxLength() {
method customFields (line 29) | async customFields() {
method refreshToken (line 53) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 65) | async generateAuthUrl() {
method authenticate (line 74) | async authenticate(params: {
method list (line 114) | async list(
method templates (line 141) | async templates(
method post (line 170) | async post(
FILE: libraries/nestjs-libraries/src/integrations/social/mastodon.custom.provider.ts
class MastodonCustomProvider (line 10) | class MastodonCustomProvider extends MastodonProvider {
method externalUrl (line 16) | async externalUrl(url: string) {
method generateAuthUrl (line 37) | override async generateAuthUrl(
method authenticate (line 57) | override async authenticate(
method post (line 73) | override async post(
method comment (line 86) | override async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/mastodon.provider.ts
class MastodonProvider (line 12) | class MastodonProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 19) | maxLength() {
method refreshToken (line 23) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateUrlDynamic (line 34) | protected generateUrlDynamic(
method generateAuthUrl (line 45) | async generateAuthUrl() {
method dynamicAuthenticate (line 60) | protected async dynamicAuthenticate(
method authenticate (line 103) | async authenticate(params: {
method uploadFile (line 116) | async uploadFile(instanceUrl: string, fileUrl: string, accessToken: st...
method dynamicPost (line 131) | async dynamicPost(
method dynamicComment (line 174) | async dynamicComment(
method post (line 221) | async post(
method comment (line 234) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/medium.provider.ts
class MediumProvider (line 14) | class MediumProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 22) | maxLength() {
method generateAuthUrl (line 26) | async generateAuthUrl() {
method refreshToken (line 35) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method customFields (line 47) | async customFields() {
method authenticate (line 58) | async authenticate(params: {
method publications (line 90) | async publications(accessToken: string, _: any, id: string) {
method post (line 102) | async post(
FILE: libraries/nestjs-libraries/src/integrations/social/mewe.provider.ts
class MeweProvider (line 14) | class MeweProvider extends SocialAbstract implements SocialProvider {
method meweHost (line 22) | private get meweHost() {
method authHeaders (line 26) | private authHeaders(apiToken: string) {
method maxLength (line 35) | maxLength() {
method handleErrors (line 39) | override handleErrors(
method refreshToken (line 68) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 80) | async generateAuthUrl() {
method authenticate (line 95) | async authenticate(params: {
method groups (line 170) | async groups(
method uploadPhoto (line 202) | private async uploadPhoto(
method post (line 235) | async post(
FILE: libraries/nestjs-libraries/src/integrations/social/moltbook.provider.ts
constant MOLTBOOK_API_BASE (line 13) | const MOLTBOOK_API_BASE = 'https://www.moltbook.com/api/v1';
class MoltbookProvider (line 15) | class MoltbookProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 24) | maxLength() {
method refreshToken (line 28) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 40) | async generateAuthUrl() {
method registerAgent (line 49) | async registerAgent(name: string, description: string) {
method checkAgentStatus (line 63) | async checkAgentStatus(apiKey: string) {
method getAgentProfile (line 71) | async getAgentProfile(apiKey: string) {
method authenticate (line 83) | async authenticate(params: {
method post (line 103) | async post(
method comment (line 150) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/nostr.provider.ts
class NostrProvider (line 29) | class NostrProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 38) | maxLength() {
method customFields (line 42) | async customFields() {
method refreshToken (line 53) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 65) | async generateAuthUrl() {
method findRelayInformation (line 74) | private async findRelayInformation(pubkey: string) {
method publish (line 99) | private async publish(pubkey: string, event: any) {
method authenticate (line 132) | async authenticate(params: {
method buildContent (line 163) | private buildContent(post: PostDetails): string {
method post (line 170) | async post(
method comment (line 200) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/pinterest.provider.ts
class PinterestProvider (line 21) | class PinterestProvider
method maxLength (line 36) | maxLength() {
method handleErrors (line 44) | public override handleErrors(body: string):
method refreshToken (line 61) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 100) | async generateAuthUrl() {
method authenticate (line 115) | async authenticate(params: {
method boards (line 160) | async boards(accessToken: string) {
method post (line 178) | async post(
method analytics (line 298) | async analytics(
method postAnalytics (line 362) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/reddit.provider.ts
class RedditProvider (line 21) | class RedditProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 30) | maxLength() {
method refreshToken (line 34) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 70) | async generateAuthUrl() {
method authenticate (line 85) | async authenticate(params: { code: string; codeVerifier: string }) {
method uploadFileToReddit (line 129) | private async uploadFileToReddit(accessToken: string, path: string) {
method post (line 178) | async post(
method comment (line 294) | async comment(
method subreddits (line 352) | async subreddits(accessToken: string, data: any) {
method getPermissions (line 383) | private getPermissions(submissionType: string, allow_images: string) {
method restrictions (line 411) | async restrictions(accessToken: string, data: { subreddit: string }) {
FILE: libraries/nestjs-libraries/src/integrations/social/skool.provider.ts
class SkoolProvider (line 16) | class SkoolProvider extends SocialAbstract implements SocialProvider {
method getCookies (line 30) | private getCookies(integration: Integration): {
method handleErrors (line 40) | override handleErrors(
method maxLength (line 54) | maxLength() {
method refreshToken (line 58) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 70) | async generateAuthUrl() {
method authenticate (line 79) | async authenticate(params: {
method groups (line 121) | async groups(accessToken: string, params: any, id: string, integration...
method label (line 145) | async label(accessToken: string, params: any, id: string, integration:...
method uploadMediaToSkool (line 187) | private async uploadMediaToSkool(
method post (line 237) | async post(
method comment (line 285) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/slack.provider.ts
class SlackProvider (line 14) | class SlackProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 30) | maxLength() {
method refreshToken (line 34) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 45) | async generateAuthUrl() {
method authenticate (line 63) | async authenticate(params: {
method channels (line 115) | async channels(accessToken: string, params: any, id: string) {
method post (line 134) | async post(
method comment (line 210) | async comment(
method changeProfilePicture (line 278) | async changeProfilePicture(id: string, accessToken: string, url: strin...
method changeNickname (line 284) | async changeNickname(id: string, accessToken: string, name: string) {
FILE: libraries/nestjs-libraries/src/integrations/social/social.integrations.interface.ts
type ClientInformation (line 3) | interface ClientInformation {
type IAuthenticator (line 8) | interface IAuthenticator {
type AnalyticsData (line 53) | interface AnalyticsData {
type GenerateAuthUrlResponse (line 60) | type GenerateAuthUrlResponse = {
type AuthTokenDetails (line 66) | type AuthTokenDetails = {
type ISocialMediaIntegration (line 84) | interface ISocialMediaIntegration {
type PostResponse (line 102) | type PostResponse = {
type PostDetails (line 109) | type PostDetails<T = any> = {
type PollDetails (line 117) | type PollDetails = {
type MediaContent (line 122) | type MediaContent = {
type FetchPageInformationResult (line 130) | type FetchPageInformationResult = {
type SocialProvider (line 138) | interface SocialProvider
FILE: libraries/nestjs-libraries/src/integrations/social/telegram.provider.ts
class TelegramProvider (line 21) | class TelegramProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 29) | maxLength() {
method refreshToken (line 33) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 45) | async generateAuthUrl() {
method authenticate (line 54) | async authenticate(params: {
method getBotId (line 82) | async getBotId(query: { id?: number; word: string }) {
method processMedia (line 141) | private processMedia(mediaFiles: PostDetails['media']) {
method sendMessage (line 171) | private async sendMessage(
method post (line 254) | async post(
method comment (line 281) | async comment(
method chunkMedia (line 310) | private chunkMedia(media: { type: string; media: string }[], size: num...
method botIsAdmin (line 318) | async botIsAdmin(chatId: number, botId: number): Promise<boolean> {
FILE: libraries/nestjs-libraries/src/integrations/social/threads.provider.ts
class ThreadsProvider (line 17) | class ThreadsProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 32) | maxLength() {
method handleErrors (line 36) | override handleErrors(body: string):
method refreshToken (line 57) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 79) | async generateAuthUrl() {
method authenticate (line 99) | async authenticate(params: {
method checkLoaded (line 145) | private async checkLoaded(
method fetchUserInfo (line 168) | private async fetchUserInfo(accessToken: string) {
method createSingleMediaContent (line 183) | private async createSingleMediaContent(
method createCarouselContent (line 215) | private async createCarouselContent(
method createTextContent (line 261) | private async createTextContent(
method publishThread (line 291) | private async publishThread(
method createThreadContent (line 316) | private async createThreadContent(
method post (line 355) | async post(
method comment (line 394) | async comment(
method analytics (line 437) | async analytics(
method autoPlugPost (line 489) | async autoPlugPost(
method postAnalytics (line 534) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/tiktok.provider.ts
class TiktokProvider (line 21) | class TiktokProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 37) | maxLength() {
method handleErrors (line 41) | override handleErrors(body: string):
method refreshToken (line 240) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 285) | async generateAuthUrl() {
method authenticate (line 307) | async authenticate(params: {
method maxVideoLength (line 364) | async maxVideoLength(accessToken: string) {
method uploadedVideoSuccess (line 385) | private async uploadedVideoSuccess(
method postingMethod (line 446) | private postingMethod(
method buildTikokPostInfoBody (line 459) | private buildTikokPostInfoBody(firstPost: PostDetails<TikTokDto>) {
method buildTikokSourceInfoBody (line 509) | private buildTikokSourceInfoBody(firstPost: PostDetails<TikTokDto>) {
method post (line 541) | async post(
method analytics (line 592) | async analytics(
method missing (line 733) | async missing(
method postAnalytics (line 767) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/social/twitch.provider.ts
class TwitchProvider (line 13) | class TwitchProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 22) | maxLength() {
method refreshToken (line 26) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 56) | async generateAuthUrl() {
method authenticate (line 76) | async authenticate(params: {
method getUserInfo (line 116) | private async getUserInfo(
method sendAnnouncement (line 138) | private async sendAnnouncement(
method sendChatMessage (line 164) | private async sendChatMessage(
method post (line 201) | async post(
method comment (line 243) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/vk.provider.ts
class VkProvider (line 16) | class VkProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 32) | maxLength() {
method refreshToken (line 36) | async refreshToken(refresh: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 77) | async generateAuthUrl() {
method authenticate (line 109) | async authenticate(params: {
method uploadMedia (line 162) | private async uploadMedia(
method post (line 228) | async post(
method comment (line 268) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/whop.provider.ts
class WhopProvider (line 16) | class WhopProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 26) | maxLength() {
method generateCodeChallenge (line 30) | private generateCodeChallenge(codeVerifier: string): string {
method handleErrors (line 34) | override handleErrors(
method refreshToken (line 71) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 101) | async generateAuthUrl() {
method authenticate (line 125) | async authenticate(params: {
method companies (line 172) | async companies(accessToken: string, params: any, id: string) {
method experiences (line 195) | async experiences(accessToken: string, params: any, id: string) {
method uploadMediaToWhop (line 219) | private async uploadMediaToWhop(
method post (line 287) | async post(
method comment (line 330) | async comment(
FILE: libraries/nestjs-libraries/src/integrations/social/wordpress.provider.ts
class WordpressProvider (line 18) | class WordpressProvider
method maxLength (line 29) | maxLength() {
method generateAuthUrl (line 33) | async generateAuthUrl() {
method refreshToken (line 42) | async refreshToken(refreshToken: string): Promise<AuthTokenDetails> {
method handleErrors (line 53) | override handleErrors(
method customFields (line 67) | async customFields() {
method authenticate (line 90) | async authenticate(params: {
method postTypes (line 145) | async postTypes(token: string) {
method post (line 182) | async post(
FILE: libraries/nestjs-libraries/src/integrations/social/x.provider.ts
class XProvider (line 26) | class XProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 38) | maxLength(isTwitterPremium: boolean) {
method handleErrors (line 42) | override handleErrors(body: string):
method autoRepostPost (line 106) | async autoRepostPost(
method repostPostUsers (line 140) | async repostPostUsers(
method autoPlugPost (line 190) | async autoPlugPost(
method refreshToken (line 221) | async refreshToken(): Promise<AuthTokenDetails> {
method generateAuthUrl (line 233) | async generateAuthUrl() {
method authenticate (line 255) | async authenticate(params: { code: string; codeVerifier: string }) {
method getClient (line 301) | private async getClient(accessToken: string) {
method uploadMedia (line 311) | private async uploadMedia(
method post (line 356) | async post(
method comment (line 420) | async comment(
method analytics (line 504) | async analytics(
method postAnalytics (line 594) | async postAnalytics(
method mention (line 684) | override async mention(token: string, d: { query: string }) {
method mentionFormat (line 715) | mentionFormat(idOrHandle: string, name: string) {
FILE: libraries/nestjs-libraries/src/integrations/social/youtube.provider.ts
class YoutubeProvider (line 52) | class YoutubeProvider extends SocialAbstract implements SocialProvider {
method maxLength (line 70) | maxLength() {
method handleErrors (line 74) | override handleErrors(body: string):
method refreshToken (line 138) | async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
method generateAuthUrl (line 161) | async generateAuthUrl() {
method authenticate (line 177) | async authenticate(params: {
method pages (line 207) | async pages(accessToken: string) {
method fetchPageInformation (line 238) | async fetchPageInformation(accessToken: string, data: { id: string }) {
method reConnect (line 268) | async reConnect(
method post (line 293) | async post(
method analytics (line 365) | async analytics(
method postAnalytics (line 453) | async postAnalytics(
FILE: libraries/nestjs-libraries/src/integrations/tool.decorator.ts
function Tool (line 3) | function Tool(params: {
FILE: libraries/nestjs-libraries/src/newsletter/newsletter.interface.ts
type NewsletterInterface (line 1) | interface NewsletterInterface {
FILE: libraries/nestjs-libraries/src/newsletter/newsletter.service.ts
class NewsletterService (line 3) | class NewsletterService {
method getProvider (line 4) | static getProvider() {
method register (line 14) | static async register(email: string) {
FILE: libraries/nestjs-libraries/src/newsletter/providers/beehiiv.provider.ts
class BeehiivProvider (line 3) | class BeehiivProvider implements NewsletterInterface {
method register (line 5) | async register(email: string) {
FILE: libraries/nestjs-libraries/src/newsletter/providers/email-empty.provider.ts
class EmailEmptyProvider (line 3) | class EmailEmptyProvider implements NewsletterInterface {
method register (line 5) | async register(email: string) {
FILE: libraries/nestjs-libraries/src/newsletter/providers/listmonk.provider.ts
class ListmonkProvider (line 3) | class ListmonkProvider implements NewsletterInterface {
method register (line 5) | async register(email: string) {
FILE: libraries/nestjs-libraries/src/openai/extract.content.service.ts
function findDepth (line 4) | function findDepth(element: Element) {
class ExtractContentService (line 16) | class ExtractContentService {
method extractContent (line 17) | async extractContent(url: string) {
FILE: libraries/nestjs-libraries/src/openai/fal.service.ts
class FalService (line 7) | class FalService {
method generateImageFromText (line 8) | async generateImageFromText(
FILE: libraries/nestjs-libraries/src/openai/openai.service.ts
class OpenaiService (line 20) | class OpenaiService {
method generateImage (line 21) | async generateImage(prompt: string, isUrl: boolean, isVertical = false) {
method generatePromptForPicture (line 34) | async generatePromptForPicture(prompt: string) {
method generateVoiceFromText (line 55) | async generateVoiceFromText(prompt: string) {
method generatePosts (line 76) | async generatePosts(content: string) {
method extractWebsiteText (line 134) | async extractWebsiteText(content: string) {
method separatePosts (line 155) | async separatePosts(content: string, len: number) {
method generateSlidesFromText (line 229) | async generateSlidesFromText(text: string) {
FILE: libraries/nestjs-libraries/src/redis/redis.service.ts
class MockRedis (line 4) | class MockRedis {
method get (line 7) | async get(key: string) {
method set (line 11) | async set(key: string, value: any) {
method del (line 16) | async del(key: string) {
FILE: libraries/nestjs-libraries/src/sentry/sentry.exception.ts
constant FILTER (line 4) | const FILTER = {
FILE: libraries/nestjs-libraries/src/services/codes.service.ts
class CodesService (line 5) | class CodesService {
method generateCodes (line 6) | generateCodes(providerToken: string) {
FILE: libraries/nestjs-libraries/src/services/email.service.ts
class EmailService (line 10) | class EmailService {
method constructor (line 12) | constructor(private _temporalService: TemporalService) {
method hasProvider (line 22) | hasProvider() {
method selectProvider (line 26) | selectProvider(provider: string) {
method sendEmail (line 37) | async sendEmail(
method sendEmailSync (line 56) | async sendEmailSync(
FILE: libraries/nestjs-libraries/src/services/exception.filter.ts
class HttpForbiddenException (line 10) | class HttpForbiddenException extends HttpException {
method constructor (line 11) | constructor() {
class HttpExceptionFilter (line 17) | class HttpExceptionFilter implements ExceptionFilter {
method catch (line 18) | catch(exception: HttpForbiddenException, host: ArgumentsHost) {
FILE: libraries/nestjs-libraries/src/services/stripe.service.ts
class StripeService (line 18) | class StripeService {
method constructor (line 19) | constructor(
method validateRequest (line 25) | validateRequest(rawBody: Buffer, signature: string, endpointSecret: st...
method checkValidCard (line 29) | async checkValidCard(
method createSubscription (line 102) | async createSubscription(event: Stripe.CustomerSubscriptionCreatedEven...
method updateSubscription (line 132) | async updateSubscription(event: Stripe.CustomerSubscriptionUpdatedEven...
method deleteSubscription (line 159) | async deleteSubscription(event: Stripe.CustomerSubscriptionDeletedEven...
method createOrGetCustomer (line 165) | async createOrGetCustomer(organization: Organization) {
method getPackages (line 182) | async getPackages() {
method prorate (line 206) | async prorate(organizationId: string, body: BillingSubscribeDto) {
method getCustomerSubscriptions (line 292) | async getCustomerSubscriptions(organizationId: string) {
method setToCancel (line 301) | async setToCancel(organizationId: string) {
method getCustomerByOrganizationId (line 360) | async getCustomerByOrganizationId(organizationId: string) {
method createBillingPortalLink (line 365) | async createBillingPortalLink(customer: string) {
method findAutoApplyPromotionCode (line 377) | private async findAutoApplyPromotionCode(): Promise<string | null> {
method createEmbeddedCheckout (line 424) | private async createEmbeddedCheckout(
method createCheckoutSession (line 497) | private async createCheckoutSession(
method finishTrial (line 546) | async finishTrial(paymentId: string) {
method checkDiscount (line 558) | async checkDiscount(customer: string) {
method applyDiscount (line 597) | async applyDiscount(customer: string) {
method checkSubscription (line 624) | async checkSubscription(organizationId: string, subscriptionId: string) {
method embedded (line 652) | async embedded(
method subscribe (line 718) | async subscribe(
method paymentSucceeded (line 826) | async paymentSucceeded(event: Stripe.InvoicePaymentSucceededEvent) {
method getCharges (line 848) | async getCharges(organizationId: string) {
method refundCharges (line 873) | async refundCharges(organizationId: string, chargeIds: string[]) {
method cancelSubscription (line 894) | async cancelSubscription(organizationId: string) {
method lifetimeDeal (line 919) | async lifetimeDeal(organizationId: string, code: string) {
FILE: libraries/nestjs-libraries/src/short-linking/providers/dub.ts
constant DUB_API_ENDPOINT (line 3) | const DUB_API_ENDPOINT = process.env.DUB_API_ENDPOINT || 'https://api.du...
constant DUB_SHORT_LINK_DOMAIN (line 4) | const DUB_SHORT_LINK_DOMAIN = process.env.DUB_SHORT_LINK_DOMAIN || 'dub....
class Dub (line 13) | class Dub implements ShortLinking {
method linksStatistics (line 16) | async linksStatistics(links: string[]) {
method convertLinkToShortLink (line 37) | async convertLinkToShortLink(id: string, link: string) {
method convertShortLinkToLink (line 53) | async convertShortLinkToLink(shortLink: string) {
method getAllLinksStatistics (line 65) | async getAllLinksStatistics(
FILE: libraries/nestjs-libraries/src/short-linking/providers/empty.ts
class Empty (line 3) | class Empty implements ShortLinking {
method linksStatistics (line 6) | async linksStatistics(links: string[]) {
method convertLinkToShortLink (line 10) | async convertLinkToShortLink(link: string) {
method convertShortLinkToLink (line 14) | async convertShortLinkToLink(shortLink: string) {
method getAllLinksStatistics (line 18) | getAllLinksStatistics(
FILE: libraries/nestjs-libraries/src/short-linking/providers/kutt.ts
constant KUTT_API_ENDPOINT (line 3) | const KUTT_API_ENDPOINT = process.env.KUTT_API_ENDPOINT || 'https://kutt...
constant KUTT_SHORT_LINK_DOMAIN (line 4) | const KUTT_SHORT_LINK_DOMAIN = process.env.KUTT_SHORT_LINK_DOMAIN || 'ku...
class Kutt (line 13) | class Kutt implements ShortLinking {
method linksStatistics (line 16) | async linksStatistics(links: string[]) {
method convertLinkToShortLink (line 49) | async convertLinkToShortLink(id: string, link: string) {
method convertShortLinkToLink (line 72) | async convertShortLinkToLink(shortLink: string) {
method getAllLinksStatistics (line 92) | async getAllLinksStatistics(
FILE: libraries/nestjs-libraries/src/short-linking/providers/linkdrip.ts
constant LINK_DRIP_API_ENDPOINT (line 3) | const LINK_DRIP_API_ENDPOINT =
constant LINK_DRIP_SHORT_LINK_DOMAIN (line 5) | const LINK_DRIP_SHORT_LINK_DOMAIN =
class LinkDrip (line 15) | class LinkDrip implements ShortLinking {
method linksStatistics (line 18) | async linksStatistics(links: string[]) {
method convertLinkToShortLink (line 22) | async convertLinkToShortLink(id: string, link: string) {
method convertShortLinkToLink (line 46) | async convertShortLinkToLink(shortLink: string) {
method getAllLinksStatistics (line 50) | getAllLinksStatistics(
FILE: libraries/nestjs-libraries/src/short-linking/providers/short.io.ts
class ShortIo (line 10) | class ShortIo implements ShortLinking {
method linksStatistics (line 13) | async linksStatistics(links: string[]) {
method convertLinkToShortLink (line 36) | async convertLinkToShortLink(id: string, link: string) {
method convertShortLinkToLink (line 51) | async convertShortLinkToLink(shortLink: string) {
method getAllLinksStatistics (line 65) | async getAllLinksStatistics(
FILE: libraries/nestjs-libraries/src/short-linking/short-linking.interface.ts
type ShortLinking (line 1) | interface ShortLinking {
FILE: libraries/nestjs-libraries/src/short-linking/short.link.service.ts
class ShortLinkService (line 32) | class ShortLinkService {
method askShortLinkedin (line 35) | askShortLinkedin(messages: string[]): boolean {
method convertTextToShortLinks (line 54) | async convertTextToShortLinks(id: string, messagesList: string[]) {
method convertShortLinksToLinks (line 96) | async convertShortLinksToLinks(messages: string[]) {
method getStatistics (line 130) | async getStatistics(messages: string[]) {
method getAllLinks (line 152) | async getAllLinks(id: string) {
FILE: libraries/nestjs-libraries/src/temporal/infinite.workflow.register.ts
class InfiniteWorkflowRegister (line 5) | class InfiniteWorkflowRegister implements OnModuleInit {
method constructor (line 6) | constructor(private _temporalService: TemporalService) {}
method onModuleInit (line 8) | async onModuleInit(): Promise<void> {
method exports (line 27) | get exports() {
class InfiniteWorkflowRegisterModule (line 31) | class InfiniteWorkflowRegisterModule {}
FILE: libraries/nestjs-libraries/src/temporal/temporal.register.ts
class TemporalRegister (line 6) | class TemporalRegister implements OnModuleInit {
method constructor (line 7) | constructor(private _client: TemporalService) {}
method onModuleInit (line 9) | async onModuleInit(): Promise<void> {
method exports (line 44) | get exports() {
class TemporalRegisterMissingSearchAttributesModule (line 48) | class TemporalRegisterMissingSearchAttributesModule {}
FILE: libraries/nestjs-libraries/src/throttler/throttler.provider.ts
class ThrottlerBehindProxyGuard (line 6) | class ThrottlerBehindProxyGuard extends ThrottlerGuard {
method canActivate (line 7) | public override async canActivate(
method getTracker (line 18) | protected override async getTracker(
FILE: libraries/nestjs-libraries/src/track/track.service.ts
class TrackService (line 21) | class TrackService {
method hashValue (line 22) | private hashValue(value: string) {
method track (line 25) | track(
FILE: libraries/nestjs-libraries/src/upload/cloudflare.storage.ts
class CloudflareStorage (line 10) | class CloudflareStorage implements IUploadProvider {
method constructor (line 13) | constructor(
method uploadSimple (line 60) | async uploadSimple(path: string) {
method uploadFile (line 82) | async uploadFile(file: Express.Multer.File): Promise<any> {
method removeFile (line 116) | async removeFile(filePath: string): Promise<void> {
FILE: libraries/nestjs-libraries/src/upload/custom.upload.validation.ts
class CustomFileValidationPipe (line 11) | class CustomFileValidationPipe implements PipeTransform {
method transform (line 12) | async transform(value: any) {
method getMaxSize (line 37) | private getMaxSize(mimeType: string): number {
FILE: libraries/nestjs-libraries/src/upload/local.storage.ts
class LocalStorage (line 6) | class LocalStorage implements IUploadProvider {
method constructor (line 7) | constructor(private uploadDirectory: string) {}
method uploadSimple (line 9) | async uploadSimple(path: string) {
method uploadFile (line 38) | async uploadFile(file: Express.Multer.File): Promise<any> {
method removeFile (line 74) | async removeFile(filePath: string): Promise<void> {
FILE: libraries/nestjs-libraries/src/upload/r2.uploader.ts
function generateRandomString (line 34) | function generateRandomString() {
function handleR2Upload (line 38) | async function handleR2Upload(
function simpleUpload (line 60) | async function simpleUpload(
function createMultipartUpload (line 81) | async function createMultipartUpload(req: Request, res: Response) {
function prepareUploadParts (line 108) | async function prepareUploadParts(req: Request, res: Response) {
function listParts (line 139) | async function listParts(req: Request, res: Response) {
function completeMultipartUpload (line 158) | async function completeMultipartUpload(req: Request, res: Response) {
function abortMultipartUpload (line 187) | async function abortMultipartUpload(req: Request, res: Response) {
function signPart (line 206) | async function signPart(req: Request, res: Response) {
FILE: libraries/nestjs-libraries/src/upload/upload.factory.ts
class UploadFactory (line 5) | class UploadFactory {
method createStorage (line 6) | static createStorage(): IUploadProvider {
FILE: libraries/nestjs-libraries/src/upload/upload.interface.ts
type IUploadProvider (line 1) | interface IUploadProvider {
FILE: libraries/nestjs-libraries/src/upload/upload.module.ts
class UploadModule (line 10) | class UploadModule {}
FILE: libraries/nestjs-libraries/src/user/track.enum.ts
type TrackEnum (line 1) | enum TrackEnum {
FILE: libraries/nestjs-libraries/src/videos/images-slides/images.slides.ts
function getAudioDuration (line 26) | async function getAudioDuration(buffer: Buffer): Promise<number> {
class ImagesSlidesParams (line 31) | class ImagesSlidesParams {
class ImagesSlides (line 60) | class ImagesSlides extends VideoAbstract<ImagesSlidesParams> {
method constructor (line 63) | constructor(
method process (line 70) | async process(
method loadVoices (line 244) | async loadVoices(data: any) {
FILE: libraries/nestjs-libraries/src/videos/veo3/veo3.ts
class Image (line 10) | class Image {
class Veo3Params (line 17) | class Veo3Params {
class Veo3 (line 38) | class Veo3 extends VideoAbstract<Veo3Params> {
method process (line 40) | async process(
FILE: libraries/nestjs-libraries/src/videos/video.interface.ts
type URL (line 3) | type URL = string;
method processAndValidate (line 8) | async processAndValidate(customParams?: T) {
type VideoParams (line 29) | interface VideoParams {
function ExposeVideoFunction (line 40) | function ExposeVideoFunction(description?: string) {
function Video (line 54) | function Video(params: VideoParams) {
FILE: libraries/nestjs-libraries/src/videos/video.manager.ts
class VideoManager (line 10) | class VideoManager {
method constructor (line 11) | constructor(private _moduleRef: ModuleRef) {}
method getAllVideos (line 13) | getAllVideos(): {
method checkAvailableVideoFunction (line 37) | checkAvailableVideoFunction(method: any) {
method getVideoByName (line 42) | getVideoByName(
FILE: libraries/nestjs-libraries/src/videos/video.module.ts
method exports (line 9) | get exports() {
class VideoModule (line 13) | class VideoModule {}
FILE: libraries/react-shared-libraries/src/helpers/image.with.fallback.tsx
type ImageSrc (line 3) | interface ImageSrc {
FILE: libraries/react-shared-libraries/src/helpers/use.is.visible.tsx
function usePageVisibility (line 4) | function usePageVisibility(page: number) {
FILE: libraries/react-shared-libraries/src/helpers/use.state.callback.ts
function useStateCallback (line 2) | function useStateCallback<T>(
FILE: libraries/react-shared-libraries/src/helpers/variable.context.tsx
type VariableContextInterface (line 4) | interface VariableContextInterface {
FILE: libraries/react-shared-libraries/src/sentry/initialize.sentry.next.basic.ts
method beforeSend (line 43) | beforeSend(event, hint) {
FILE: libraries/react-shared-libraries/src/translation/get.transation.service.client.ts
function useT (line 8) | function useT(ns?: string, options?: UseTranslationOptions<any>) {
function useTranslationSettings (line 13) | function useTranslationSettings() {
FILE: libraries/react-shared-libraries/src/translation/get.translation.service.backend.ts
function getT (line 4) | async function getT(ns?: string, options?: any) {
FILE: libraries/react-shared-libraries/src/translation/translated-label.tsx
type TranslatedLabelProps (line 4) | interface TranslatedLabelProps {
function TranslatedLabel (line 19) | function TranslatedLabel({
Condensed preview — 803 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,816K chars).
[
{
"path": ".coderabbit.yaml",
"chars": 3408,
"preview": "language: en-US\ntone_instructions: ''\nearly_access: false\nenable_free_tier: true\nreviews:\n profile: chill\n request_cha"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 306,
"preview": "{\n\t\"name\": \"Postiz Dev Container\",\n\t\"image\": \"localhost/postiz-devcontainer\",\n\t\"features\": {},\n\t\"customizations\": {\n\t\t\"v"
},
{
"path": ".dockerignore",
"chars": 458,
"preview": "# We want the docker builds to be clean, and as fast as possible. Don't send\n# any half-built stuff in the build context"
},
{
"path": ".eslintignore",
"chars": 13,
"preview": "node_modules\n"
},
{
"path": ".github/Dependabot.yml",
"chars": 524,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/FUNDING.yaml",
"chars": 61,
"preview": "#patreon: Postiz\nopen_collective: postiz\n# github: gitroomhq\n"
},
{
"path": ".github/ISSUE_TEMPLATE/01_bug_report.yml",
"chars": 2797,
"preview": "name: \"🐛 Bug Report\"\ndescription: \"Submit a bug report to help us improve,\\nif you have a problem installing the app ple"
},
{
"path": ".github/ISSUE_TEMPLATE/02_feature_request.yml",
"chars": 2016,
"preview": "name: 🚀 Feature\ndescription: \"Submit a proposal for a new feature\"\ntitle: \"Give your feature request a title\"\nlabels: [\""
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 490,
"preview": "# Disable the default option to open a blank issue\nblank_issues_enabled: true \n\n# Define your custom links\ncontact_links"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 871,
"preview": "# What kind of change does this PR introduce?\n\neg: Bug fix, feature, docs update, ...\n\n# Why was this change needed?\n\nPl"
},
{
"path": ".github/copilot-instructions.md",
"chars": 4154,
"preview": "\n# Copilot Coding Agent Instructions for Postiz\n\n## Project Architecture\n- Monorepo managed by NX, with apps in `apps/` "
},
{
"path": ".github/workflows/build-containers.yml",
"chars": 3597,
"preview": "---\nname: \"Build Containers\"\n\non:\n workflow_dispatch:\n push:\n tags:\n - '*'\n\njobs:\n build-containers-common:\n "
},
{
"path": ".github/workflows/build-extension.yaml",
"chars": 843,
"preview": "name: Build Extension\n\non:\n workflow_dispatch:\n\njobs:\n submit:\n runs-on: ubuntu-latest\n\n steps:\n - uses: ac"
},
{
"path": ".github/workflows/build.yml",
"chars": 1268,
"preview": "---\nname: Build\n\non:\n push:\n\njobs:\n build:\n runs-on: ubuntu-latest\n \n\n strategy:\n matrix:\n node-v"
},
{
"path": ".github/workflows/codeql.yml",
"chars": 839,
"preview": "---\nname: \"Code Quality Analysis\"\n\non:\n push:\n branches:\n - main\n paths:\n - apps/**\n - '!apps/doc"
},
{
"path": ".github/workflows/eslint",
"chars": 1515,
"preview": "---\nname: ESLint\n\non:\n push:\n branches:\n - main\n paths:\n - package.json\n - apps/**\n - '!apps/"
},
{
"path": ".github/workflows/issue-label-triggers.yml",
"chars": 927,
"preview": "---\nname: Issue Label Triggers\non:\n issues:\n types:\n - labeled\n\njobs:\n closed-public-website:\n if: github.e"
},
{
"path": ".github/workflows/pr-docker-build.yml",
"chars": 954,
"preview": "name: Build and Publish PR Docker Image\n\non:\n pull_request_target:\n types: [opened, synchronize]\n\npermissions: write"
},
{
"path": ".github/workflows/pr-quality.yml",
"chars": 277,
"preview": "name: PR Quality\n\npermissions:\n contents: read\n issues: read\n pull-requests: write\n\non:\n pull_request_target:\n ty"
},
{
"path": ".github/workflows/publish-extension.yml",
"chars": 841,
"preview": "name: Publish Extension\n\non:\n workflow_dispatch:\n\njobs:\n submit:\n runs-on: ubuntu-latest\n steps:\n - uses: a"
},
{
"path": ".github/workflows/stale.yml",
"chars": 1180,
"preview": "name: Close inactive issues\n\non:\n workflow_dispatch:\n schedule:\n - cron: \"*/30 * * * *\"\n\njobs:\n close-issues:\n "
},
{
"path": ".gitignore",
"chars": 717,
"preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# compiled output\ndist\ntmp\n/out-tsc\n.env\n# de"
},
{
"path": ".gitmodules",
"chars": 145,
"preview": "[submodule \"libraries/plugins/src/list/public-api\"]\n\tpath = libraries/plugins/src/list/public-api\n\turl = git@github.com:"
},
{
"path": ".npmrc",
"chars": 156,
"preview": "ignore-workspace-root-check=true\nnode-linker=hoisted\nrestrict-manifest-changes=true\nsync-injected-deps-after-scripts[]=b"
},
{
"path": ".prettierignore",
"chars": 83,
"preview": "# Add files here to ignore them from prettier formatting\n/dist\n/coverage\n/.nx/cache"
},
{
"path": ".prettierrc",
"chars": 26,
"preview": "{\n \"singleQuote\": true\n}\n"
},
{
"path": "CLAUDE.md",
"chars": 2384,
"preview": "This project is Postiz, a tool to schedule social media and chat posts to 28+ channels.\nYou can add posts to the calenda"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5217,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "CONTRIBUTING.md",
"chars": 3051,
"preview": "# Contributing\n\nContributions are welcome - code, docs, whatever it might be! If this is your first contribution to an O"
},
{
"path": "Dockerfile.dev",
"chars": 699,
"preview": "FROM node:22.20-bookworm-slim\nARG NEXT_PUBLIC_VERSION\nENV NEXT_PUBLIC_VERSION=$NEXT_PUBLIC_VERSION\nRUN apt-get update &&"
},
{
"path": "Jenkins/Build.Jenkinsfile",
"chars": 4561,
"preview": "// Declarative Pipeline for building Node.js application and running SonarQube analysis triggered by a push event.\npipel"
},
{
"path": "Jenkins/BuildPR.Jenkinsfile",
"chars": 4758,
"preview": "// Declarative Pipeline for building Node.js application and running SonarQube analysis for a Pull Request.\npipeline {\n "
},
{
"path": "LICENSE",
"chars": 34478,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "README.md",
"chars": 7927,
"preview": "<p align=\"center\">\n <a href=\"https://postiz.com/\" target=\"_blank\">\n <picture>\n <source media=\"(prefers-color-scheme"
},
{
"path": "SECURITY.md",
"chars": 2026,
"preview": "# Security Policy\n\n## Introduction\n\nThe Postiz app is committed to ensuring the security and integrity of our users' dat"
},
{
"path": "apps/backend/.gitignore",
"chars": 99,
"preview": "dist/\nnode_modules/\n[._]*.s[a-v][a-z]\n[._]*.sw[a-p]\n[._]s[a-rt-v][a-z]\n[._]ss[a-gi-z]\n[._]sw[a-p]\n\n"
},
{
"path": "apps/backend/nest-cli.json",
"chars": 474,
"preview": "{\n \"$schema\": \"https://json.schemastore.org/nest-cli\",\n \"collection\": \"@nestjs/schematics\",\n \"monorepo\": false,\n \"so"
},
{
"path": "apps/backend/package.json",
"chars": 457,
"preview": "{\n \"name\": \"postiz-backend\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"dev\": \"dotenv -e ../../.env"
},
{
"path": "apps/backend/src/api/api.module.ts",
"chars": 5176,
"preview": "import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';\nimport { AuthController } from '@gitroom/backen"
},
{
"path": "apps/backend/src/api/routes/analytics.controller.ts",
"chars": 1152,
"preview": "import { Controller, Get, Param, Query } from '@nestjs/common';\nimport { Organization } from '@prisma/client';\nimport { "
},
{
"path": "apps/backend/src/api/routes/approved-apps.controller.ts",
"chars": 771,
"preview": "import { Controller, Delete, Get, Param } from '@nestjs/common';\nimport { GetUserFromRequest } from '@gitroom/nestjs-lib"
},
{
"path": "apps/backend/src/api/routes/auth.controller.ts",
"chars": 7827,
"preview": "import {\n Body,\n Controller,\n Get,\n Param,\n Post,\n Query,\n Req,\n Res,\n} from '@nestjs/common';\nimport { Response"
},
{
"path": "apps/backend/src/api/routes/autopost.controller.ts",
"chars": 1977,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Put,\n Query,\n} from '@nestjs/common';\nimport { GetOr"
},
{
"path": "apps/backend/src/api/routes/billing.controller.ts",
"chars": 5681,
"preview": "import { Body, Controller, Get, HttpException, Param, Post, Req } from '@nestjs/common';\nimport { SubscriptionService } "
},
{
"path": "apps/backend/src/api/routes/copilot.controller.ts",
"chars": 4429,
"preview": "import {\n Logger,\n Controller,\n Get,\n Post,\n Req,\n Res,\n Query,\n Param,\n} from '@nestjs/common';\nimport {\n Copi"
},
{
"path": "apps/backend/src/api/routes/enterprise.controller.ts",
"chars": 3811,
"preview": "import { Body, Controller, Param, Post, Res } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport {"
},
{
"path": "apps/backend/src/api/routes/integrations.controller.ts",
"chars": 13781,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Put,\n Query,\n} from '@nestjs/common';\nimport { ioRed"
},
{
"path": "apps/backend/src/api/routes/media.controller.ts",
"chars": 5775,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Query,\n Req,\n Res,\n UploadedFile,\n UseInterceptor"
},
{
"path": "apps/backend/src/api/routes/monitor.controller.ts",
"chars": 352,
"preview": "import { Controller, Get, Param } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\n\n@ApiTags('Monitor')"
},
{
"path": "apps/backend/src/api/routes/no.auth.integrations.controller.ts",
"chars": 11407,
"preview": "import {\n Body,\n Controller,\n Get,\n HttpException,\n Param,\n Post,\n UseFilters,\n} from '@nestjs/common';\nimport { "
},
{
"path": "apps/backend/src/api/routes/notifications.controller.ts",
"chars": 1075,
"preview": "import { Controller, Get } from '@nestjs/common';\nimport { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/use"
},
{
"path": "apps/backend/src/api/routes/oauth-app.controller.ts",
"chars": 1969,
"preview": "import { Body, Controller, Delete, Get, Post, Put } from '@nestjs/common';\nimport { GetOrgFromRequest } from '@gitroom/n"
},
{
"path": "apps/backend/src/api/routes/oauth.controller.ts",
"chars": 2651,
"preview": "import {\n Body,\n Controller,\n Get,\n HttpException,\n HttpStatus,\n Post,\n Query,\n} from '@nestjs/common';\nimport { "
},
{
"path": "apps/backend/src/api/routes/posts.controller.ts",
"chars": 6453,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Put,\n Query,\n Res,\n} from '@nestjs/common';\nimport "
},
{
"path": "apps/backend/src/api/routes/public.controller.ts",
"chars": 6722,
"preview": "import {\n Body,\n Controller,\n Get,\n Param,\n Post,\n Query,\n Req,\n Res,\n StreamableFile,\n} from '@nestjs/common';"
},
{
"path": "apps/backend/src/api/routes/root.controller.ts",
"chars": 167,
"preview": "import { Controller, Get } from '@nestjs/common';\n@Controller('/')\nexport class RootController {\n @Get('/')\n getRoot()"
},
{
"path": "apps/backend/src/api/routes/sets.controller.ts",
"chars": 1211,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Put,\n} from '@nestjs/common';\nimport { GetOrgFromRequ"
},
{
"path": "apps/backend/src/api/routes/settings.controller.ts",
"chars": 2352,
"preview": "import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';\nimport { GetOrgFromRequest } from '@gitroom"
},
{
"path": "apps/backend/src/api/routes/signature.controller.ts",
"chars": 1535,
"preview": "import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';\nimport { GetOrgFromRequest } from '@gi"
},
{
"path": "apps/backend/src/api/routes/stripe.controller.ts",
"chars": 1510,
"preview": "import {\n Controller,\n HttpException,\n Post,\n RawBodyRequest,\n Req,\n} from '@nestjs/common';\nimport { StripeService"
},
{
"path": "apps/backend/src/api/routes/third-party.controller.ts",
"chars": 4277,
"preview": "import {\n Body,\n Controller,\n Get,\n HttpException,\n Param,\n Post,\n Delete,\n} from '@nestjs/common';\nimport { ApiT"
},
{
"path": "apps/backend/src/api/routes/users.controller.ts",
"chars": 9953,
"preview": "import {\n Body,\n Controller,\n Get,\n HttpException,\n Post,\n Query,\n Req,\n Res,\n} from '@nestjs/common';\nimport { "
},
{
"path": "apps/backend/src/api/routes/webhooks.controller.ts",
"chars": 1917,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n Param,\n Post,\n Put,\n Query,\n} from '@nestjs/common';\nimport { GetOr"
},
{
"path": "apps/backend/src/app.module.ts",
"chars": 2410,
"preview": "import { Global, Module } from '@nestjs/common';\nimport { DatabaseModule } from '@gitroom/nestjs-libraries/database/pris"
},
{
"path": "apps/backend/src/assets/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "apps/backend/src/main.ts",
"chars": 2858,
"preview": "import { initializeSentry } from '@gitroom/nestjs-libraries/sentry/initialize.sentry';\ninitializeSentry('backend', true)"
},
{
"path": "apps/backend/src/public-api/public.api.module.ts",
"chars": 1666,
"preview": "import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';\nimport { AuthService } from '@gitroom/backend/s"
},
{
"path": "apps/backend/src/public-api/routes/v1/public.integrations.controller.ts",
"chars": 13819,
"preview": "import {\n Body,\n Controller,\n Delete,\n Get,\n HttpException,\n Param,\n Post,\n Put,\n Query,\n UploadedFile,\n UseI"
},
{
"path": "apps/backend/src/services/auth/auth.middleware.ts",
"chars": 3391,
"preview": "import { Injectable, NestMiddleware } from '@nestjs/common';\nimport { Request, Response, NextFunction } from 'express';\n"
},
{
"path": "apps/backend/src/services/auth/auth.service.ts",
"chars": 9206,
"preview": "import { Injectable } from '@nestjs/common';\nimport { Provider, User } from '@prisma/client';\nimport { CreateOrgUserDto "
},
{
"path": "apps/backend/src/services/auth/permissions/permission.exception.class.ts",
"chars": 731,
"preview": "import { HttpException, HttpStatus } from '@nestjs/common';\n\nexport enum Sections {\n CHANNEL = 'channel',\n POSTS_PER_M"
},
{
"path": "apps/backend/src/services/auth/permissions/permissions.ability.ts",
"chars": 346,
"preview": "import { SetMetadata } from '@nestjs/common';\nimport { AuthorizationActions, Sections } from './permission.exception.cla"
},
{
"path": "apps/backend/src/services/auth/permissions/permissions.guard.ts",
"chars": 1962,
"preview": "import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nim"
},
{
"path": "apps/backend/src/services/auth/permissions/permissions.service.ts",
"chars": 4805,
"preview": "import { Ability, AbilityBuilder, AbilityClass } from '@casl/ability';\nimport { Injectable } from '@nestjs/common';\nimpo"
},
{
"path": "apps/backend/src/services/auth/permissions/subscription.exception.ts",
"chars": 1876,
"preview": "import {\n ArgumentsHost,\n Catch,\n ExceptionFilter,\n HttpException,\n} from '@nestjs/common';\nimport { AuthorizationAc"
},
{
"path": "apps/backend/src/services/auth/providers/farcaster.provider.ts",
"chars": 1053,
"preview": "import {\n AuthProvider,\n AuthProviderAbstract,\n} from '@gitroom/backend/services/auth/providers.interface';\nimport { N"
},
{
"path": "apps/backend/src/services/auth/providers/github.provider.ts",
"chars": 1559,
"preview": "import {\n AuthProvider,\n AuthProviderAbstract,\n} from '@gitroom/backend/services/auth/providers.interface';\n\n@AuthProv"
},
{
"path": "apps/backend/src/services/auth/providers/google.provider.ts",
"chars": 1924,
"preview": "import { google } from 'googleapis';\nimport { OAuth2Client } from 'google-auth-library/build/src/auth/oauth2client';\nimp"
},
{
"path": "apps/backend/src/services/auth/providers/oauth.provider.ts",
"chars": 2615,
"preview": "import {\n AuthProvider,\n AuthProviderAbstract,\n} from '@gitroom/backend/services/auth/providers.interface';\n\n@AuthProv"
},
{
"path": "apps/backend/src/services/auth/providers/providers.manager.ts",
"chars": 668,
"preview": "import { Injectable } from '@nestjs/common';\nimport { ModuleRef } from '@nestjs/core';\nimport { AuthProviderAbstract } f"
},
{
"path": "apps/backend/src/services/auth/providers/wallet.provider.ts",
"chars": 2142,
"preview": "import {\n AuthProvider,\n AuthProviderAbstract,\n} from '@gitroom/backend/services/auth/providers.interface';\nimport { r"
},
{
"path": "apps/backend/src/services/auth/providers.interface.ts",
"chars": 868,
"preview": "import { Injectable } from '@nestjs/common';\n\nexport abstract class AuthProviderAbstract {\n abstract generateLink(query"
},
{
"path": "apps/backend/src/services/auth/public.auth.middleware.ts",
"chars": 2191,
"preview": "import { HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';\nimport { Request, Response, NextFunction } from"
},
{
"path": "apps/backend/tsconfig.build.json",
"chars": 650,
"preview": "{\n \"extends\": \"./tsconfig.json\",\n \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"],\n \"compilerOptions\": {\n "
},
{
"path": "apps/backend/tsconfig.json",
"chars": 268,
"preview": "{\n \"extends\": \"../../tsconfig.base.json\",\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declaration\": true,\n "
},
{
"path": "apps/cli/.gitignore",
"chars": 34,
"preview": "node_modules\ndist\n*.log\n.DS_Store\n"
},
{
"path": "apps/cli/.npmignore",
"chars": 87,
"preview": "src\nexamples\ntsconfig.json\ntsup.config.ts\n*.md\n!README.md\nnode_modules\n.git\n.gitignore\n"
},
{
"path": "apps/cli/CHANGELOG.md",
"chars": 1053,
"preview": "# Changelog\n\nAll notable changes to the Postiz CLI will be documented in this file.\n\nThe format is based on [Keep a Chan"
},
{
"path": "apps/cli/FEATURES.md",
"chars": 7639,
"preview": "# Postiz CLI - Feature Summary\n\n## ✅ Complete Feature Set\n\n### Posts with Comments and Media - FULLY SUPPORTED\n\nThe Post"
},
{
"path": "apps/cli/HOW_TO_RUN.md",
"chars": 5225,
"preview": "# How to Run the Postiz CLI\n\nThere are several ways to run the CLI, depending on your needs.\n\n## Option 1: Direct Execut"
},
{
"path": "apps/cli/INTEGRATION_SETTINGS_DISCOVERY.md",
"chars": 8621,
"preview": "# Integration Settings Discovery\n\nThe CLI now has a powerful feature to discover what settings are available for each in"
},
{
"path": "apps/cli/INTEGRATION_TOOLS_WORKFLOW.md",
"chars": 8766,
"preview": "# Integration Tools Workflow\n\nSome integrations require additional data (like IDs, tags, playlists, etc.) before you can"
},
{
"path": "apps/cli/PROJECT_STRUCTURE.md",
"chars": 7935,
"preview": "# Postiz CLI - Project Structure\n\n## Overview\n\nThe Postiz CLI is a complete command-line interface package for interacti"
},
{
"path": "apps/cli/PROVIDER_SETTINGS.md",
"chars": 10411,
"preview": "# Provider-Specific Settings\n\nThe Postiz CLI supports platform-specific settings for each integration. Different platfor"
},
{
"path": "apps/cli/PROVIDER_SETTINGS_SUMMARY.md",
"chars": 5413,
"preview": "# Provider-Specific Settings - Quick Reference\n\n## ✅ What's Supported\n\nThe CLI now supports **platform-specific settings"
},
{
"path": "apps/cli/PUBLISHING.md",
"chars": 6126,
"preview": "# Publishing the Postiz CLI to npm\n\n## Quick Publish (Current Name: \"postiz\")\n\n```bash\n# From apps/cli directory\npnpm ru"
},
{
"path": "apps/cli/QUICK_START.md",
"chars": 4930,
"preview": "# Postiz CLI - Quick Start Guide\n\n## Installation\n\n### From Source (Development)\n\n```bash\n# Navigate to the monorepo roo"
},
{
"path": "apps/cli/README.md",
"chars": 16929,
"preview": "# Postiz CLI\n\n**Social media automation CLI for AI agents** - Schedule posts across 28+ platforms programmatically.\n\nThe"
},
{
"path": "apps/cli/SKILL.md",
"chars": 17603,
"preview": "| Property | Value |\n|----------|-------|\n| **name** | postiz |\n| **description** | Social media automation CLI for sche"
},
{
"path": "apps/cli/SUMMARY.md",
"chars": 6288,
"preview": "# Postiz CLI - Creation Summary\n\n## ✅ What Was Created\n\nA complete, production-ready CLI package for the Postiz API has "
},
{
"path": "apps/cli/SUPPORTED_FILE_TYPES.md",
"chars": 5822,
"preview": "# Supported File Types for Upload\n\nThe Postiz CLI now correctly detects and uploads various media types.\n\n## How It Work"
},
{
"path": "apps/cli/SYNTAX_UPGRADE.md",
"chars": 6786,
"preview": "# Postiz CLI - Improved Syntax! 🎉\n\n## What Changed\n\nThe CLI now supports a **much better** command-line syntax for creat"
},
{
"path": "apps/cli/examples/COMMAND_LINE_GUIDE.md",
"chars": 8263,
"preview": "# Postiz CLI - Command Line Guide\n\n## New Syntax: Multiple `-c` and `-m` Flags\n\nThe CLI now supports a much more intuiti"
},
{
"path": "apps/cli/examples/EXAMPLES.md",
"chars": 7668,
"preview": "# Postiz CLI - Advanced Examples\n\nThis directory contains examples demonstrating the full capabilities of the Postiz CLI"
},
{
"path": "apps/cli/examples/ai-agent-example.js",
"chars": 2841,
"preview": "#!/usr/bin/env node\n\n/**\n * Example: Using Postiz CLI from an AI Agent (Node.js)\n *\n * This demonstrates how AI agents c"
},
{
"path": "apps/cli/examples/basic-usage.sh",
"chars": 1080,
"preview": "#!/bin/bash\n\n# Basic Postiz CLI Usage Example\n# Make sure to set your API key first: export POSTIZ_API_KEY=your_key\n\nech"
},
{
"path": "apps/cli/examples/command-line-examples.sh",
"chars": 5050,
"preview": "#!/bin/bash\n\n# Postiz CLI - Command Line Examples\n# Demonstrating the new -c and -m flag syntax\n\necho \"🚀 Postiz CLI Comm"
},
{
"path": "apps/cli/examples/multi-platform-post.json",
"chars": 1984,
"preview": "{\n \"type\": \"schedule\",\n \"date\": \"2024-12-25T12:00:00Z\",\n \"shortLink\": true,\n \"tags\": [\n {\n \"value\": \"holiday"
},
{
"path": "apps/cli/examples/multi-platform-with-settings.json",
"chars": 4239,
"preview": "{\n \"type\": \"schedule\",\n \"date\": \"2024-03-15T09:00:00Z\",\n \"shortLink\": true,\n \"tags\": [\n { \"value\": \"product-launc"
},
{
"path": "apps/cli/examples/post-with-comments.json",
"chars": 1289,
"preview": "{\n \"type\": \"now\",\n \"date\": \"2024-01-15T12:00:00Z\",\n \"shortLink\": true,\n \"tags\": [],\n \"posts\": [\n {\n \"integr"
},
{
"path": "apps/cli/examples/reddit-post.json",
"chars": 832,
"preview": "{\n \"type\": \"now\",\n \"date\": \"2024-01-15T12:00:00Z\",\n \"shortLink\": true,\n \"tags\": [],\n \"posts\": [{\n \"integration\":"
},
{
"path": "apps/cli/examples/thread-post.json",
"chars": 1891,
"preview": "{\n \"type\": \"now\",\n \"date\": \"2024-01-15T12:00:00Z\",\n \"shortLink\": true,\n \"tags\": [],\n \"posts\": [\n {\n \"integr"
},
{
"path": "apps/cli/examples/tiktok-video.json",
"chars": 837,
"preview": "{\n \"type\": \"now\",\n \"date\": \"2024-01-15T12:00:00Z\",\n \"shortLink\": true,\n \"tags\": [],\n \"posts\": [{\n \"integration\":"
},
{
"path": "apps/cli/examples/youtube-video.json",
"chars": 1300,
"preview": "{\n \"type\": \"schedule\",\n \"date\": \"2024-12-25T09:00:00Z\",\n \"shortLink\": true,\n \"tags\": [\n { \"value\": \"tutorial\", \"l"
},
{
"path": "apps/cli/package.json",
"chars": 885,
"preview": "{\n \"name\": \"postiz\",\n \"version\": \"2.0.5\",\n \"description\": \"Postiz CLI - Command line interface for the Postiz social "
},
{
"path": "apps/cli/src/api.ts",
"chars": 4050,
"preview": "import fetch, { FormData } from 'node-fetch';\n\nexport interface PostizConfig {\n apiKey: string;\n apiUrl?: string;\n}\n\ne"
},
{
"path": "apps/cli/src/commands/integrations.ts",
"chars": 1961,
"preview": "import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\n\nexport async function listIntegrations() {\n "
},
{
"path": "apps/cli/src/commands/posts.ts",
"chars": 4722,
"preview": "import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\nimport { readFileSync, existsSync } from 'fs'"
},
{
"path": "apps/cli/src/commands/upload.ts",
"chars": 725,
"preview": "import { PostizAPI } from '../api';\nimport { getConfig } from '../config';\nimport { readFileSync } from 'fs';\n\nexport as"
},
{
"path": "apps/cli/src/config.ts",
"chars": 416,
"preview": "import { PostizConfig } from './api';\n\nexport function getConfig(): PostizConfig {\n const apiKey = process.env.POSTIZ_A"
},
{
"path": "apps/cli/src/index.ts",
"chars": 7991,
"preview": "import yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { createPost, listPosts, deletePost } from '."
},
{
"path": "apps/cli/tsconfig.json",
"chars": 341,
"preview": "{\n \"extends\": \"../../tsconfig.base.json\",\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declaration\": true,\n "
},
{
"path": "apps/cli/tsup.config.ts",
"chars": 299,
"preview": "import { defineConfig } from 'tsup';\n\nexport default defineConfig({\n entry: ['src/index.ts'],\n format: ['cjs'],\n dts:"
},
{
"path": "apps/commands/.gitignore",
"chars": 99,
"preview": "dist/\nnode_modules/\n[._]*.s[a-v][a-z]\n[._]*.sw[a-p]\n[._]s[a-rt-v][a-z]\n[._]ss[a-gi-z]\n[._]sw[a-p]\n\n"
},
{
"path": "apps/commands/nest-cli.json",
"chars": 476,
"preview": "{\n \"$schema\": \"https://json.schemastore.org/nest-cli\",\n \"collection\": \"@nestjs/schematics\",\n \"monorepo\": false,\n \"so"
},
{
"path": "apps/commands/package.json",
"chars": 350,
"preview": "{\n \"name\": \"postiz-command\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"dev\": \"dotenv -e ../../.env"
},
{
"path": "apps/commands/src/command.module.ts",
"chars": 702,
"preview": "import { Module } from '@nestjs/common';\nimport { CommandModule as ExternalCommandModule } from 'nestjs-command';\nimport"
},
{
"path": "apps/commands/src/main.ts",
"chars": 506,
"preview": "import { NestFactory } from '@nestjs/core';\nimport { CommandModule } from './command.module';\nimport { CommandService } "
},
{
"path": "apps/commands/src/tasks/agent.run.ts",
"chars": 456,
"preview": "import { Command } from 'nestjs-command';\nimport { Injectable } from '@nestjs/common';\nimport { AgentGraphService } from"
},
{
"path": "apps/commands/src/tasks/configuration.ts",
"chars": 868,
"preview": "import { Command } from 'nestjs-command';\nimport { Injectable } from '@nestjs/common';\nimport { ConfigurationChecker } f"
},
{
"path": "apps/commands/src/tasks/refresh.tokens.ts",
"chars": 483,
"preview": "import { Command } from 'nestjs-command';\nimport { Injectable } from '@nestjs/common';\nimport { IntegrationService } fro"
},
{
"path": "apps/commands/tsconfig.build.json",
"chars": 650,
"preview": "{\n \"extends\": \"./tsconfig.json\",\n \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"],\n \"compilerOptions\": {\n "
},
{
"path": "apps/commands/tsconfig.json",
"chars": 268,
"preview": "{\n \"extends\": \"../../tsconfig.base.json\",\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declaration\": true,\n "
},
{
"path": "apps/extension/.gitignore",
"chars": 6905,
"preview": "\n# Created by https://www.toptal.com/developers/gitignore/api/webstorm+all,visualstudiocode,sublimetext,node,react,windo"
},
{
"path": "apps/extension/custom-vite-plugins.ts",
"chars": 1700,
"preview": "import fs from 'fs';\nimport { resolve } from 'path';\nimport type { PluginOption } from 'vite';\n\n// plugin to remove dev "
},
{
"path": "apps/extension/manifest.dev.json",
"chars": 966,
"preview": "{\n \"manifest_version\": 3,\n \"name\": \"Postiz\",\n \"version\": \"2.0.0\",\n \"key\": \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCA"
},
{
"path": "apps/extension/manifest.json",
"chars": 561,
"preview": "{\n \"manifest_version\": 3,\n \"name\": \"Postiz\",\n \"version\": \"2.0.0\",\n \"description\": \"Postiz browser extension for soci"
},
{
"path": "apps/extension/package.json",
"chars": 480,
"preview": "{\n \"name\": \"postiz-extension\",\n \"version\": \"2.0.0\",\n \"description\": \"Postiz browser extension for cookie-based platfo"
},
{
"path": "apps/extension/src/background.ts",
"chars": 5963,
"preview": "import { ExtensionRequest, GetCookiesResponse, ProviderInfo, StoredRefreshEntry } from './types/messages';\nimport { getA"
},
{
"path": "apps/extension/src/providers/cookie-provider.interface.ts",
"chars": 707,
"preview": "export interface CookieDefinition {\n /** The cookie name to extract, e.g., 'client_id' */\n name: string;\n /** Whether"
},
{
"path": "apps/extension/src/providers/list/skool.provider.ts",
"chars": 330,
"preview": "import { CookieProvider } from '../cookie-provider.interface';\n\nexport const skoolProvider: CookieProvider = {\n identif"
},
{
"path": "apps/extension/src/providers/provider.registry.ts",
"chars": 478,
"preview": "import { CookieProvider } from './cookie-provider.interface';\nimport { skoolProvider } from './list/skool.provider';\n\nex"
},
{
"path": "apps/extension/src/types/messages.ts",
"chars": 1541,
"preview": "// ---- Request Types ----\n\nexport interface PingRequest {\n type: 'PING';\n}\n\nexport interface GetProvidersRequest {\n t"
},
{
"path": "apps/extension/tsconfig.json",
"chars": 647,
"preview": "{\n \"extends\": \"../../tsconfig.base.json\",\n \"compilerOptions\": {\n \"target\": \"esnext\",\n \"types\": [\"vite/client\", \""
},
{
"path": "apps/extension/vite.config.base.ts",
"chars": 1604,
"preview": "import react from '@vitejs/plugin-react';\nimport { resolve } from 'path';\nimport { ManifestV3Export } from '@crxjs/vite-"
},
{
"path": "apps/extension/vite.config.chrome.ts",
"chars": 1319,
"preview": "import { resolve } from 'path';\nimport { mergeConfig, defineConfig } from 'vite';\nimport { crx, ManifestV3Export } from "
},
{
"path": "apps/extension/vite.config.ts",
"chars": 550,
"preview": "import { resolve } from 'path';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n build: {\n outDi"
},
{
"path": "apps/frontend/.gitignore",
"chars": 480,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
},
{
"path": "apps/frontend/README.md",
"chars": 1450,
"preview": "This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-re"
},
{
"path": "apps/frontend/next.config.js",
"chars": 2950,
"preview": "// @ts-check\nimport { withSentryConfig } from '@sentry/nextjs';\n\n/** @type {import('next').NextConfig} */\nconst nextConf"
},
{
"path": "apps/frontend/package.json",
"chars": 421,
"preview": "{\n \"name\": \"postiz-frontend\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": "
},
{
"path": "apps/frontend/postcss.config.mjs",
"chars": 135,
"preview": "/** @type {import('postcss-load-config').Config} */\nconst config = {\n plugins: {\n tailwindcss: {},\n },\n};\n\nexport d"
},
{
"path": "apps/frontend/public/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "apps/frontend/public/f.js",
"chars": 523476,
"preview": "/**\n * Copyright (c) 2017-present, Facebook, Inc. All rights reserved.\n *\n * You are hereby granted a non-exclusive, wor"
},
{
"path": "apps/frontend/src/app/(app)/(preview)/p/[id]/layout.tsx",
"chars": 331,
"preview": "import { ReactNode } from 'react';\nimport { PreviewWrapper } from '@gitroom/frontend/components/preview/preview.wrapper'"
},
{
"path": "apps/frontend/src/app/(app)/(preview)/p/[id]/page.tsx",
"chars": 14165,
"preview": "import { internalFetch } from '@gitroom/helpers/utils/internal.fetch';\nexport const dynamic = 'force-dynamic';\nimport { "
},
{
"path": "apps/frontend/src/app/(app)/(site)/agents/[id]/page.tsx",
"chars": 336,
"preview": "import { Metadata } from 'next';\nimport { Agent } from '@gitroom/frontend/components/agents/agent';\nimport { AgentChat }"
},
{
"path": "apps/frontend/src/app/(app)/(site)/agents/layout.tsx",
"chars": 319,
"preview": "import { Metadata } from 'next';\nimport { Agent } from '@gitroom/frontend/components/agents/agent';\nexport const metadat"
},
{
"path": "apps/frontend/src/app/(app)/(site)/agents/page.tsx",
"chars": 239,
"preview": "import { Metadata } from 'next';\nimport { redirect } from 'next/navigation';\n\nexport const metadata: Metadata = {\n titl"
},
{
"path": "apps/frontend/src/app/(app)/(site)/analytics/page.tsx",
"chars": 464,
"preview": "export const dynamic = 'force-dynamic';\nimport { Metadata } from 'next';\nimport { PlatformAnalytics } from '@gitroom/fro"
},
{
"path": "apps/frontend/src/app/(app)/(site)/billing/lifetime/page.tsx",
"chars": 441,
"preview": "import { LifetimeDeal } from '@gitroom/frontend/components/billing/lifetime.deal';\nexport const dynamic = 'force-dynamic"
},
{
"path": "apps/frontend/src/app/(app)/(site)/billing/page.tsx",
"chars": 552,
"preview": "export const dynamic = 'force-dynamic';\nimport { BillingComponent } from '@gitroom/frontend/components/billing/billing.c"
},
{
"path": "apps/frontend/src/app/(app)/(site)/err/page.tsx",
"chars": 457,
"preview": "import { Metadata } from 'next';\nimport { getT } from '@gitroom/react/translation/get.translation.service.backend';\nexpo"
},
{
"path": "apps/frontend/src/app/(app)/(site)/launches/page.tsx",
"chars": 462,
"preview": "export const dynamic = 'force-dynamic';\nimport { LaunchesComponent } from '@gitroom/frontend/components/launches/launche"
},
{
"path": "apps/frontend/src/app/(app)/(site)/layout.tsx",
"chars": 241,
"preview": "import { LayoutComponent } from '@gitroom/frontend/components/new-layout/layout.component';\n\nexport default async functi"
},
{
"path": "apps/frontend/src/app/(app)/(site)/media/page.tsx",
"chars": 422,
"preview": "import { MediaLayoutComponent } from '@gitroom/frontend/components/new-layout/layout.media.component';\nimport { Metadata"
},
{
"path": "apps/frontend/src/app/(app)/(site)/plugs/page.tsx",
"chars": 410,
"preview": "import { Plugs } from '@gitroom/frontend/components/plugs/plugs';\nexport const dynamic = 'force-dynamic';\nimport { Metad"
},
{
"path": "apps/frontend/src/app/(app)/(site)/settings/page.tsx",
"chars": 508,
"preview": "import { SettingsPopup } from '@gitroom/frontend/components/layout/settings.component';\nexport const dynamic = 'force-dy"
},
{
"path": "apps/frontend/src/app/(app)/(site)/third-party/page.tsx",
"chars": 491,
"preview": "import { ThirdPartyComponent } from '@gitroom/frontend/components/third-parties/third-party.component';\n\nexport const dy"
},
{
"path": "apps/frontend/src/app/(app)/api/uploads/[[...path]]/route.ts",
"chars": 1439,
"preview": "import { NextRequest, NextResponse } from 'next/server';\nimport { createReadStream, statSync } from 'fs';\n// @ts-ignore\n"
},
{
"path": "apps/frontend/src/app/(app)/auth/activate/[code]/page.tsx",
"chars": 459,
"preview": "export const dynamic = 'force-dynamic';\nimport { Metadata } from 'next';\nimport { AfterActivate } from '@gitroom/fronten"
},
{
"path": "apps/frontend/src/app/(app)/auth/activate/page.tsx",
"chars": 443,
"preview": "export const dynamic = 'force-dynamic';\nimport { Metadata } from 'next';\nimport { Activate } from '@gitroom/frontend/com"
},
{
"path": "apps/frontend/src/app/(app)/auth/forgot/[token]/page.tsx",
"chars": 515,
"preview": "export const dynamic = 'force-dynamic';\nimport { ForgotReturn } from '@gitroom/frontend/components/auth/forgot-return';\n"
},
{
"path": "apps/frontend/src/app/(app)/auth/forgot/page.tsx",
"chars": 421,
"preview": "export const dynamic = 'force-dynamic';\nimport { Forgot } from '@gitroom/frontend/components/auth/forgot';\nimport { Meta"
},
{
"path": "apps/frontend/src/app/(app)/auth/layout.tsx",
"chars": 1555,
"preview": "import { getT } from '@gitroom/react/translation/get.translation.service.backend';\n\nexport const dynamic = 'force-dynami"
},
{
"path": "apps/frontend/src/app/(app)/auth/login/page.tsx",
"chars": 408,
"preview": "export const dynamic = 'force-dynamic';\nimport { Login } from '@gitroom/frontend/components/auth/login';\nimport { Metada"
},
{
"path": "apps/frontend/src/app/(app)/auth/login-required/page.tsx",
"chars": 250,
"preview": "export default async function LoginRequiredPage() {\n return (\n <div className=\"fixed left-0 top-0 w-full h-full bg-["
},
{
"path": "apps/frontend/src/app/(app)/auth/page.tsx",
"chars": 1353,
"preview": "import { internalFetch } from '@gitroom/helpers/utils/internal.fetch';\nexport const dynamic = 'force-dynamic';\nimport { "
},
{
"path": "apps/frontend/src/app/(app)/auth/return.url.component.tsx",
"chars": 632,
"preview": "'use client';\n\nimport { useSearchParams } from 'next/navigation';\nimport { FC, useCallback, useEffect } from 'react';\nco"
},
{
"path": "apps/frontend/src/app/(app)/integrations/social/[provider]/page.tsx",
"chars": 469,
"preview": "import { ContinueIntegration } from '@gitroom/frontend/components/launches/continue.integration';\nimport { cookies } fro"
},
{
"path": "apps/frontend/src/app/(app)/integrations/social/layout.tsx",
"chars": 246,
"preview": "import { ReactNode } from 'react';\n\nexport default async function IntegrationLayout({\n children,\n}: {\n children: React"
},
{
"path": "apps/frontend/src/app/(app)/layout.tsx",
"chars": 4622,
"preview": "import { SentryComponent } from '@gitroom/frontend/components/layout/sentry.component';\n\nexport const dynamic = 'force-d"
},
{
"path": "apps/frontend/src/app/(app)/oauth/authorize/layout.tsx",
"chars": 347,
"preview": "import { Metadata } from 'next';\nimport { ReactNode } from 'react';\n\nexport const metadata: Metadata = {\n title: 'Autho"
},
{
"path": "apps/frontend/src/app/(app)/oauth/authorize/page.tsx",
"chars": 7590,
"preview": "'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { useSearchParams } from 'next/navigatio"
},
{
"path": "apps/frontend/src/app/(extension)/layout.tsx",
"chars": 2765,
"preview": "export const dynamic = 'force-dynamic';\nimport '../global.scss';\nimport 'react-tooltip/dist/react-tooltip.css';\nimport '"
},
{
"path": "apps/frontend/src/app/(extension)/modal/[style]/[platform]/page.tsx",
"chars": 379,
"preview": "'use client';\n\nimport { StandaloneModal } from '@gitroom/frontend/components/standalone-modal/standalone.modal';\nexport "
},
{
"path": "apps/frontend/src/app/(extension)/modal/layout.tsx",
"chars": 255,
"preview": "import { ReactNode } from 'react';\nimport { AppLayout } from '@gitroom/frontend/components/launches/layout.standalone';\n"
},
{
"path": "apps/frontend/src/app/colors.scss",
"chars": 7457,
"preview": ":root {\n .dark {\n --new-back-drop: #000;\n --new-settings: #242323;\n --new-border: #252525;\n --new-bgColor: "
},
{
"path": "apps/frontend/src/app/global-error.tsx",
"chars": 885,
"preview": "'use client';\nimport * as Sentry from '@sentry/nextjs';\nimport NextError from 'next/error';\nimport { useEffect } from 'r"
},
{
"path": "apps/frontend/src/app/global.scss",
"chars": 14102,
"preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n@import './colors.scss';\n@import './polonto.css';\n@import '@u"
},
{
"path": "apps/frontend/src/app/polonto.css",
"chars": 397537,
"preview": ".bp5-icon {\n display: inline-block;\n flex: 0 0 auto;\n vertical-align: text-bottom;\n}\n.bp5-icon:not(:empty)::before {\n"
},
{
"path": "apps/frontend/src/chrome.d.ts",
"chars": 454,
"preview": "/**\n * Minimal Chrome extension API types for externally_connectable messaging.\n * Web pages listed in an extension's ex"
},
{
"path": "apps/frontend/src/components/agents/agent.chat.tsx",
"chars": 11058,
"preview": "'use client';\n\nimport React, {\n FC,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nim"
},
{
"path": "apps/frontend/src/components/agents/agent.input.tsx",
"chars": 3817,
"preview": "import React, { useMemo, useRef, useState } from 'react';\nimport { useCopilotContext, useCopilotReadable } from '@copilo"
},
{
"path": "apps/frontend/src/components/agents/agent.textarea.tsx",
"chars": 2072,
"preview": "import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle } from \"react\";\n\ninterface AutoResizingText"
},
{
"path": "apps/frontend/src/components/agents/agent.tsx",
"chars": 9586,
"preview": "'use client';\n\nimport React, {\n createContext,\n FC,\n useCallback,\n useMemo,\n useState,\n ReactNode,\n} from 'react';"
},
{
"path": "apps/frontend/src/components/analytics/analytics.component.tsx",
"chars": 8601,
"preview": "'use client';\n\nimport { StarsAndForks } from '@gitroom/frontend/components/analytics/stars.and.forks';\nimport { FC, useC"
},
{
"path": "apps/frontend/src/components/analytics/chart-social.tsx",
"chars": 3831,
"preview": "'use client';\n\nimport { FC, useEffect, useMemo, useRef } from 'react';\nimport DrawChart from 'chart.js/auto';\nimport { T"
},
{
"path": "apps/frontend/src/components/analytics/chart.tsx",
"chars": 1939,
"preview": "'use client';\n\nimport { FC, useEffect, useRef } from 'react';\nimport DrawChart from 'chart.js/auto';\nimport {\n ForksLis"
},
{
"path": "apps/frontend/src/components/analytics/stars.and.forks.interface.ts",
"chars": 510,
"preview": "export interface StarsList {\n totalStars: number;\n date: string;\n}\nexport interface TotalList {\n total: number;\n dat"
}
]
// ... and 603 more files (download for full content)
About this extraction
This page contains the full source code of the gitroomhq/postiz-app GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 803 files (4.3 MB), approximately 1.2M tokens, and a symbol index with 2266 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.