├── .env.example
├── .github
└── workflows
│ ├── ci.yml
│ └── pullrequest_validation.yml
├── .gitignore
├── LICENSE
├── README.md
├── app
├── api
│ ├── stacks
│ │ ├── basic-openai
│ │ │ └── route.ts
│ │ ├── boilerplate-basic
│ │ │ └── route.ts
│ │ ├── chat-gemini-streaming-langchain
│ │ │ └── route.ts
│ │ ├── chat-with-gemini-langchain
│ │ │ └── route.ts
│ │ ├── chat-with-gemini-streaming
│ │ │ └── route.ts
│ │ ├── chat-with-gemini
│ │ │ └── route.ts
│ │ ├── chat-with-openai-streaming-helicone
│ │ │ └── route.ts
│ │ ├── chat-with-openai-streaming-langchain
│ │ │ └── route.ts
│ │ ├── chat-with-openai-streaming
│ │ │ └── route.ts
│ │ ├── cover-image-and-subtitle
│ │ │ └── route.ts
│ │ ├── create-stack-boilerplate
│ │ │ ├── create-stack.ts
│ │ │ ├── get-file-from-github.ts
│ │ │ ├── push-multiple-files-to-branch.ts
│ │ │ └── route.ts
│ │ ├── elevenlabs-tts
│ │ │ └── route.ts
│ │ ├── get-image-description-openai
│ │ │ └── route.ts
│ │ ├── image-sharpener
│ │ │ └── route.ts
│ │ ├── image-to-music
│ │ │ └── route.ts
│ │ ├── rag-pdf-with-langchain
│ │ │ └── route.ts
│ │ ├── stable-video-diffusion
│ │ │ └── route.ts
│ │ ├── text-to-qr
│ │ │ └── route.ts
│ │ └── use-openai-assistant
│ │ │ └── route.ts
│ └── utils
│ │ └── getAWSPresignedUrl
│ │ └── route.ts
├── components
│ ├── shared
│ │ ├── ContactButton.tsx
│ │ └── clipboard.tsx
│ └── stacks
│ │ ├── boilerplate-basic.tsx
│ │ ├── chat-gemini-streaming-langchain.tsx
│ │ ├── chat-with-gemini-langchain.tsx
│ │ ├── chat-with-gemini-streaming.tsx
│ │ ├── chat-with-gemini.tsx
│ │ ├── chat-with-openai-streaming-helicone.tsx
│ │ ├── chat-with-openai-streaming-langchain.tsx
│ │ ├── chat-with-openai-streaming.tsx
│ │ ├── cover-image-and-subtitle.tsx
│ │ ├── create-ai-canvas.tsx
│ │ ├── create-stack-boilerplate.tsx
│ │ ├── creation
│ │ ├── Inputs.tsx
│ │ ├── content.tsx
│ │ ├── input-with-button.tsx
│ │ ├── main-content.tsx
│ │ └── outputs.tsx
│ │ ├── elevenlabs-tts.tsx
│ │ ├── get-image-description-openai.tsx
│ │ ├── image-sharpener.tsx
│ │ ├── image-to-music.tsx
│ │ ├── instant-video-to-image.tsx
│ │ ├── rag-pdf-with-langchain.tsx
│ │ ├── stable-video-diffusion.tsx
│ │ ├── text-to-qr.tsx
│ │ ├── use-openai-assistant.tsx
│ │ └── utils
│ │ ├── actions.ts
│ │ ├── search-stacks.tsx
│ │ ├── signIn.tsx
│ │ ├── signOut.tsx
│ │ └── stack-db.ts
├── favicon.ico
├── globals.css
├── layout.tsx
└── stacks
│ ├── [slug]
│ └── page.tsx
│ └── page.tsx
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── apocalyptic_car.png
├── boat_example.webp
├── caesar.jpeg
├── next.svg
├── placeholder.png
├── stack-pictures
│ ├── boilerplate-basic.png
│ ├── chat-gemini-streaming-langchain.png
│ ├── chat-with-gemini-langchain.png
│ ├── chat-with-gemini-streaming.png
│ ├── chat-with-gemini.png
│ ├── chat-with-openai-streaming-helicone.png
│ ├── chat-with-openai-streaming-langchain.png
│ ├── chat-with-openai-streaming.png
│ ├── cover-image-and-subtitle.png
│ ├── create-ai-canvas.png
│ ├── create-stack-boilerplate.png
│ ├── elevenlabs-tts.png
│ ├── generate-a-cover-image-and-subtitle-on-uploading-a-video.png
│ ├── get-image-description-openai.png
│ ├── image-sharpener.png
│ ├── image-to-music.png
│ ├── instant-video-to-image.png
│ ├── rag-pdf-with-langchain.png
│ ├── stable-video-diffusion.png
│ ├── stack-example.png
│ ├── stackwise-onboarding.png
│ ├── text-to-qr.png
│ └── use-openai-assistant.png
├── stacks
│ ├── boilerplate-basic.tsx
│ ├── chat-gemini-streaming-langchain.tsx
│ ├── chat-with-gemini-langchain.tsx
│ ├── chat-with-gemini-streaming.tsx
│ ├── chat-with-gemini.tsx
│ ├── chat-with-openai-streaming-helicone.tsx
│ ├── chat-with-openai-streaming-langchain.tsx
│ ├── chat-with-openai-streaming.tsx
│ ├── cover-image-and-subtitle.tsx
│ ├── create-ai-canvas.tsx
│ ├── create-stack-boilerplate.tsx
│ ├── creation
│ │ ├── Inputs.tsx
│ │ ├── content.tsx
│ │ ├── input-with-button.tsx
│ │ ├── main-content.tsx
│ │ └── outputs.tsx
│ ├── elevenlabs-tts.tsx
│ ├── get-image-description-openai.tsx
│ ├── image-sharpener.tsx
│ ├── image-to-music.tsx
│ ├── instant-video-to-image.tsx
│ ├── rag-pdf-with-langchain.tsx
│ ├── stable-video-diffusion.tsx
│ ├── stacks
│ │ ├── basic-openai
│ │ │ └── route.ts
│ │ ├── boilerplate-basic
│ │ │ └── route.ts
│ │ ├── chat-gemini-streaming-langchain
│ │ │ └── route.ts
│ │ ├── chat-with-gemini-langchain
│ │ │ └── route.ts
│ │ ├── chat-with-gemini-streaming
│ │ │ └── route.ts
│ │ ├── chat-with-gemini
│ │ │ └── route.ts
│ │ ├── chat-with-openai-streaming-helicone
│ │ │ └── route.ts
│ │ ├── chat-with-openai-streaming-langchain
│ │ │ └── route.ts
│ │ ├── chat-with-openai-streaming
│ │ │ └── route.ts
│ │ ├── cover-image-and-subtitle
│ │ │ └── route.ts
│ │ ├── create-stack-boilerplate
│ │ │ ├── create-stack.ts
│ │ │ ├── get-file-from-github.ts
│ │ │ ├── push-multiple-files-to-branch.ts
│ │ │ └── route.ts
│ │ ├── elevenlabs-tts
│ │ │ └── route.ts
│ │ ├── get-image-description-openai
│ │ │ └── route.ts
│ │ ├── image-sharpener
│ │ │ └── route.ts
│ │ ├── image-to-music
│ │ │ └── route.ts
│ │ ├── rag-pdf-with-langchain
│ │ │ └── route.ts
│ │ ├── stable-video-diffusion
│ │ │ └── route.ts
│ │ ├── text-to-qr
│ │ │ └── route.ts
│ │ └── use-openai-assistant
│ │ │ └── route.ts
│ ├── text-to-qr.tsx
│ ├── use-openai-assistant.tsx
│ └── utils
│ │ ├── actions.ts
│ │ ├── getAWSPresignedUrl
│ │ └── route.ts
│ │ ├── search-stacks.tsx
│ │ ├── signIn.tsx
│ │ ├── signOut.tsx
│ │ └── stack-db.ts
├── stacks_homepage.png
└── stackwise_logo.png
├── scripts
├── .gitignore
├── sync-stacks.ts
└── tsconfig.json
├── tailwind.config.ts
├── tooling
├── eslint-config
│ ├── base.js
│ ├── nextjs.js
│ ├── package.json
│ ├── react.js
│ └── tsconfig.json
├── github
│ ├── package.json
│ └── setup
│ │ └── action.yml
├── prettier-config
│ ├── index.mjs
│ ├── package.json
│ └── tsconfig.json
├── tailwind-config
│ ├── index.ts
│ ├── node_modules
│ │ ├── .bin
│ │ │ ├── tailwind
│ │ │ └── tailwindcss
│ │ └── tailwindcss
│ │ │ ├── CHANGELOG.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── base.css
│ │ │ ├── colors.d.ts
│ │ │ ├── colors.js
│ │ │ ├── components.css
│ │ │ ├── defaultConfig.d.ts
│ │ │ ├── defaultConfig.js
│ │ │ ├── defaultTheme.d.ts
│ │ │ ├── defaultTheme.js
│ │ │ ├── lib
│ │ │ ├── cli-peer-dependencies.js
│ │ │ ├── cli.js
│ │ │ ├── cli
│ │ │ │ ├── build
│ │ │ │ │ ├── deps.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── plugin.js
│ │ │ │ │ ├── utils.js
│ │ │ │ │ └── watching.js
│ │ │ │ ├── help
│ │ │ │ │ └── index.js
│ │ │ │ ├── index.js
│ │ │ │ └── init
│ │ │ │ │ └── index.js
│ │ │ ├── corePluginList.js
│ │ │ ├── corePlugins.js
│ │ │ ├── css
│ │ │ │ ├── LICENSE
│ │ │ │ └── preflight.css
│ │ │ ├── featureFlags.js
│ │ │ ├── index.js
│ │ │ ├── lib
│ │ │ │ ├── cacheInvalidation.js
│ │ │ │ ├── collapseAdjacentRules.js
│ │ │ │ ├── collapseDuplicateDeclarations.js
│ │ │ │ ├── content.js
│ │ │ │ ├── defaultExtractor.js
│ │ │ │ ├── detectNesting.js
│ │ │ │ ├── evaluateTailwindFunctions.js
│ │ │ │ ├── expandApplyAtRules.js
│ │ │ │ ├── expandTailwindAtRules.js
│ │ │ │ ├── findAtConfigPath.js
│ │ │ │ ├── generateRules.js
│ │ │ │ ├── getModuleDependencies.js
│ │ │ │ ├── load-config.js
│ │ │ │ ├── normalizeTailwindDirectives.js
│ │ │ │ ├── offsets.js
│ │ │ │ ├── partitionApplyAtRules.js
│ │ │ │ ├── regex.js
│ │ │ │ ├── remap-bitfield.js
│ │ │ │ ├── resolveDefaultsAtRules.js
│ │ │ │ ├── setupContextUtils.js
│ │ │ │ ├── setupTrackingContext.js
│ │ │ │ ├── sharedState.js
│ │ │ │ └── substituteScreenAtRules.js
│ │ │ ├── oxide
│ │ │ │ ├── cli.js
│ │ │ │ ├── cli
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── deps.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── plugin.js
│ │ │ │ │ │ ├── utils.js
│ │ │ │ │ │ └── watching.js
│ │ │ │ │ ├── help
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── init
│ │ │ │ │ │ └── index.js
│ │ │ │ └── postcss-plugin.js
│ │ │ ├── plugin.js
│ │ │ ├── postcss-plugins
│ │ │ │ └── nesting
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── plugin.js
│ │ │ ├── processTailwindFeatures.js
│ │ │ ├── public
│ │ │ │ ├── colors.js
│ │ │ │ ├── create-plugin.js
│ │ │ │ ├── default-config.js
│ │ │ │ ├── default-theme.js
│ │ │ │ ├── load-config.js
│ │ │ │ └── resolve-config.js
│ │ │ ├── util
│ │ │ │ ├── applyImportantSelector.js
│ │ │ │ ├── bigSign.js
│ │ │ │ ├── buildMediaQuery.js
│ │ │ │ ├── cloneDeep.js
│ │ │ │ ├── cloneNodes.js
│ │ │ │ ├── color.js
│ │ │ │ ├── colorNames.js
│ │ │ │ ├── configurePlugins.js
│ │ │ │ ├── createPlugin.js
│ │ │ │ ├── createUtilityPlugin.js
│ │ │ │ ├── dataTypes.js
│ │ │ │ ├── defaults.js
│ │ │ │ ├── escapeClassName.js
│ │ │ │ ├── escapeCommas.js
│ │ │ │ ├── flattenColorPalette.js
│ │ │ │ ├── formatVariantSelector.js
│ │ │ │ ├── getAllConfigs.js
│ │ │ │ ├── hashConfig.js
│ │ │ │ ├── isKeyframeRule.js
│ │ │ │ ├── isPlainObject.js
│ │ │ │ ├── isSyntacticallyValidPropertyValue.js
│ │ │ │ ├── log.js
│ │ │ │ ├── nameClass.js
│ │ │ │ ├── negateValue.js
│ │ │ │ ├── normalizeConfig.js
│ │ │ │ ├── normalizeScreens.js
│ │ │ │ ├── parseAnimationValue.js
│ │ │ │ ├── parseBoxShadowValue.js
│ │ │ │ ├── parseDependency.js
│ │ │ │ ├── parseGlob.js
│ │ │ │ ├── parseObjectStyles.js
│ │ │ │ ├── pluginUtils.js
│ │ │ │ ├── prefixSelector.js
│ │ │ │ ├── pseudoElements.js
│ │ │ │ ├── removeAlphaVariables.js
│ │ │ │ ├── resolveConfig.js
│ │ │ │ ├── resolveConfigPath.js
│ │ │ │ ├── responsive.js
│ │ │ │ ├── splitAtTopLevelOnly.js
│ │ │ │ ├── tap.js
│ │ │ │ ├── toColorValue.js
│ │ │ │ ├── toPath.js
│ │ │ │ ├── transformThemeValue.js
│ │ │ │ ├── validateConfig.js
│ │ │ │ ├── validateFormalSyntax.js
│ │ │ │ └── withAlphaVariable.js
│ │ │ └── value-parser
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── index.d.js
│ │ │ │ ├── index.js
│ │ │ │ ├── parse.js
│ │ │ │ ├── stringify.js
│ │ │ │ ├── unit.js
│ │ │ │ └── walk.js
│ │ │ ├── loadConfig.d.ts
│ │ │ ├── loadConfig.js
│ │ │ ├── nesting
│ │ │ ├── index.d.ts
│ │ │ └── index.js
│ │ │ ├── package.json
│ │ │ ├── peers
│ │ │ └── index.js
│ │ │ ├── plugin.d.ts
│ │ │ ├── plugin.js
│ │ │ ├── prettier.config.js
│ │ │ ├── resolveConfig.d.ts
│ │ │ ├── resolveConfig.js
│ │ │ ├── screens.css
│ │ │ ├── scripts
│ │ │ ├── create-plugin-list.js
│ │ │ ├── generate-types.js
│ │ │ ├── release-channel.js
│ │ │ ├── release-notes.js
│ │ │ ├── swap-engines.js
│ │ │ └── type-utils.js
│ │ │ ├── src
│ │ │ ├── cli-peer-dependencies.js
│ │ │ ├── cli.js
│ │ │ ├── cli
│ │ │ │ ├── build
│ │ │ │ │ ├── deps.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── plugin.js
│ │ │ │ │ ├── utils.js
│ │ │ │ │ └── watching.js
│ │ │ │ ├── help
│ │ │ │ │ └── index.js
│ │ │ │ ├── index.js
│ │ │ │ └── init
│ │ │ │ │ └── index.js
│ │ │ ├── corePluginList.js
│ │ │ ├── corePlugins.js
│ │ │ ├── css
│ │ │ │ ├── LICENSE
│ │ │ │ └── preflight.css
│ │ │ ├── featureFlags.js
│ │ │ ├── index.js
│ │ │ ├── lib
│ │ │ │ ├── cacheInvalidation.js
│ │ │ │ ├── collapseAdjacentRules.js
│ │ │ │ ├── collapseDuplicateDeclarations.js
│ │ │ │ ├── content.js
│ │ │ │ ├── defaultExtractor.js
│ │ │ │ ├── detectNesting.js
│ │ │ │ ├── evaluateTailwindFunctions.js
│ │ │ │ ├── expandApplyAtRules.js
│ │ │ │ ├── expandTailwindAtRules.js
│ │ │ │ ├── findAtConfigPath.js
│ │ │ │ ├── generateRules.js
│ │ │ │ ├── getModuleDependencies.js
│ │ │ │ ├── load-config.ts
│ │ │ │ ├── normalizeTailwindDirectives.js
│ │ │ │ ├── offsets.js
│ │ │ │ ├── partitionApplyAtRules.js
│ │ │ │ ├── regex.js
│ │ │ │ ├── remap-bitfield.js
│ │ │ │ ├── resolveDefaultsAtRules.js
│ │ │ │ ├── setupContextUtils.js
│ │ │ │ ├── setupTrackingContext.js
│ │ │ │ ├── sharedState.js
│ │ │ │ └── substituteScreenAtRules.js
│ │ │ ├── oxide
│ │ │ │ ├── cli.ts
│ │ │ │ ├── cli
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── deps.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── plugin.ts
│ │ │ │ │ │ ├── utils.ts
│ │ │ │ │ │ └── watching.ts
│ │ │ │ │ ├── help
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── init
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── postcss-plugin.ts
│ │ │ ├── plugin.js
│ │ │ ├── postcss-plugins
│ │ │ │ └── nesting
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── plugin.js
│ │ │ ├── processTailwindFeatures.js
│ │ │ ├── public
│ │ │ │ ├── colors.js
│ │ │ │ ├── create-plugin.js
│ │ │ │ ├── default-config.js
│ │ │ │ ├── default-theme.js
│ │ │ │ ├── load-config.js
│ │ │ │ └── resolve-config.js
│ │ │ ├── util
│ │ │ │ ├── applyImportantSelector.js
│ │ │ │ ├── bigSign.js
│ │ │ │ ├── buildMediaQuery.js
│ │ │ │ ├── cloneDeep.js
│ │ │ │ ├── cloneNodes.js
│ │ │ │ ├── color.js
│ │ │ │ ├── colorNames.js
│ │ │ │ ├── configurePlugins.js
│ │ │ │ ├── createPlugin.js
│ │ │ │ ├── createUtilityPlugin.js
│ │ │ │ ├── dataTypes.js
│ │ │ │ ├── defaults.js
│ │ │ │ ├── escapeClassName.js
│ │ │ │ ├── escapeCommas.js
│ │ │ │ ├── flattenColorPalette.js
│ │ │ │ ├── formatVariantSelector.js
│ │ │ │ ├── getAllConfigs.js
│ │ │ │ ├── hashConfig.js
│ │ │ │ ├── isKeyframeRule.js
│ │ │ │ ├── isPlainObject.js
│ │ │ │ ├── isSyntacticallyValidPropertyValue.js
│ │ │ │ ├── log.js
│ │ │ │ ├── nameClass.js
│ │ │ │ ├── negateValue.js
│ │ │ │ ├── normalizeConfig.js
│ │ │ │ ├── normalizeScreens.js
│ │ │ │ ├── parseAnimationValue.js
│ │ │ │ ├── parseBoxShadowValue.js
│ │ │ │ ├── parseDependency.js
│ │ │ │ ├── parseGlob.js
│ │ │ │ ├── parseObjectStyles.js
│ │ │ │ ├── pluginUtils.js
│ │ │ │ ├── prefixSelector.js
│ │ │ │ ├── pseudoElements.js
│ │ │ │ ├── removeAlphaVariables.js
│ │ │ │ ├── resolveConfig.js
│ │ │ │ ├── resolveConfigPath.js
│ │ │ │ ├── responsive.js
│ │ │ │ ├── splitAtTopLevelOnly.js
│ │ │ │ ├── tap.js
│ │ │ │ ├── toColorValue.js
│ │ │ │ ├── toPath.js
│ │ │ │ ├── transformThemeValue.js
│ │ │ │ ├── validateConfig.js
│ │ │ │ ├── validateFormalSyntax.js
│ │ │ │ └── withAlphaVariable.js
│ │ │ └── value-parser
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── parse.js
│ │ │ │ ├── stringify.js
│ │ │ │ ├── unit.js
│ │ │ │ └── walk.js
│ │ │ ├── stubs
│ │ │ ├── .npmignore
│ │ │ ├── .prettierrc.json
│ │ │ ├── config.full.js
│ │ │ ├── config.simple.js
│ │ │ ├── postcss.config.cjs
│ │ │ ├── postcss.config.js
│ │ │ ├── tailwind.config.cjs
│ │ │ ├── tailwind.config.js
│ │ │ └── tailwind.config.ts
│ │ │ ├── tailwind.css
│ │ │ ├── types
│ │ │ ├── config.d.ts
│ │ │ ├── generated
│ │ │ │ ├── .gitkeep
│ │ │ │ ├── colors.d.ts
│ │ │ │ ├── corePluginList.d.ts
│ │ │ │ └── default-theme.d.ts
│ │ │ └── index.d.ts
│ │ │ ├── utilities.css
│ │ │ └── variants.css
│ ├── package.json
│ └── tsconfig.json
└── tsconfig
│ ├── base.json
│ └── package.json
└── tsconfig.json
/.env.example:
--------------------------------------------------------------------------------
1 | # Dependant on what stack you want to run
2 |
3 | OPENAI_API_KEY=sk-
4 | HELICONE_API_KEY=sk-
5 | PINECONE_API_KEY=
6 | PINECONE_ENVIRONMENT=
7 | # SUPABASE_URL=
8 | # SUPABASE_KEY=
9 | GEMINI_API_KEY=
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: TypeScript Build and Test
2 |
3 | on:
4 | push:
5 | branches: [main, "ci-test*"]
6 | pull_request_target:
7 | branches: [main, "ci-test*"]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout Repository
15 | uses: actions/checkout@v2
16 |
17 | - name: Change to 'stacks' directory
18 | run: cd stacks
19 |
20 | - name: Remove node_modules
21 | run: rm -rf node_modules
22 |
23 | - name: Install System Dependencies
24 | run: |
25 | sudo apt-get update
26 | sudo apt-get install -y build-essential libxtst-dev
27 |
28 | - name: Update Node.js and npm
29 | run: |
30 | npm install -g npm@latest
31 |
32 | - name: Update robotjs
33 | run: |
34 | npm install robotjs@latest
35 |
36 | - name: Setup Node.js
37 | uses: actions/setup-node@v2
38 | with:
39 | node-version: "18" # You can specify your Node.js version here
40 |
41 | - name: Install Dependencies
42 | run: npm install
43 |
44 | - name: Fetch Latest Changes
45 | run: git fetch
46 |
47 | - name: Run Jest on Modified Folder
48 | run: npx jest --onlyChanged
49 |
--------------------------------------------------------------------------------
/.github/workflows/pullrequest_validation.yml:
--------------------------------------------------------------------------------
1 | name: Validate Pull Request
2 |
3 | on:
4 | pull_request:
5 | types:
6 | - opened
7 | - synchronize
8 |
9 | jobs:
10 | check-format:
11 | name: Validate Stack PR
12 |
13 | # Only run if the PR branch starts with `stack/`
14 | if: startsWith(github.head_ref, 'stack/')
15 |
16 | runs-on: ubuntu-latest # can also change to: windows-latest || macos-latest
17 |
18 | steps:
19 | - uses: actions/checkout@v4
20 | with:
21 | fetch-depth: 0 # OR "2" -> To retrieve the preceding commit.
22 |
23 | - name: Get all changed files
24 | id: changed-files
25 | uses: tj-actions/changed-files@v40
26 |
27 | - name: List all changed files
28 | run: |
29 | for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
30 | echo "$file was changed"
31 | done
32 |
33 | - name: Fail if unexpected files were changed
34 | run: |
35 | for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
36 | if [[ ! "$file" =~ ^(stacks/[^/]*/index.test.ts|stacks/[^/]*/index.ts|stacks/[^/]*/index.test.txt)$ ]]; then
37 | echo "😡 File '$file' was changed. This is not allowed in a stack Pull Request."
38 | echo ""
39 | echo "You're only allowed to change the following:"
40 | echo " - stacks/*/index.ts"
41 | echo " - stacks/*/index.test.ts"
42 | echo " - stacks/*/index.test.txt"
43 | exit 1
44 | fi
45 | done
46 |
47 | - name: Fail if more than one (1) stack was made
48 | run: |
49 | if ((${{ steps.changed-files.outputs.all_changed_files_count }} > 3)); then
50 | echo "😡 Detected more than 1 stack. Please make only 1 stack per pull request."
51 | exit 1
52 | fi
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | .vscode
6 | /.pnp
7 | .pnp.js
8 | .yarn/install-state.gz
9 |
10 | # testing
11 | /coverage
12 |
13 | # next.js
14 | /.next/
15 | /out/
16 |
17 | # production
18 | /build
19 |
20 | # misc
21 | .DS_Store
22 | *.pem
23 |
24 | # debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | # local env files
30 | .env*.local
31 |
32 | # vercel
33 | .vercel
34 |
35 | # typescript
36 | *.tsbuildinfo
37 | next-env.d.ts
38 |
39 | .env
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Stackwise, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The open source AI app collection.
2 |
3 | [](https://discord.gg/KfUxa8h3s6)
4 | [](https://twitter.com/stackwiseai)
5 | [](https://github.com/stackwiseai/stackwise/stargazers)
6 | [](https://opensource.org/licenses/MIT)
7 |
8 | ### [Visit the Stackwise collection](https://stackwise.ai/stacks)
9 |
10 | 
11 |
12 | ### Join The Community
13 |
14 | [](https://discord.gg/KfUxa8h3s6)
15 |
16 | We welcome contributions, feedback, and suggestions to further enhance Stackwise. If you made it here you're at the very least intrigued and we'd love to have you :)
17 |
18 | ---
19 |
20 | This project is licensed under the [MIT License](LICENSE).
21 |
--------------------------------------------------------------------------------
/app/api/stacks/basic-openai/route.ts:
--------------------------------------------------------------------------------
1 | import OpenAI from 'openai';
2 |
3 | const openai = new OpenAI({
4 | apiKey: process.env.OPENAI_API_KEY,
5 | });
6 |
7 | export async function POST(req: Request) {
8 | const { messages } = await req.json();
9 | const response = await openai.chat.completions.create({
10 | model: 'gpt-3.5-turbo',
11 | messages: [{ role: 'user', content: messages }],
12 | });
13 | const content = response.choices[0].message.content;
14 | return new Response(JSON.stringify({ content }));
15 | }
16 |
--------------------------------------------------------------------------------
/app/api/stacks/boilerplate-basic/route.ts:
--------------------------------------------------------------------------------
1 | export async function POST(req: Request) {
2 | const { input } = await req.json();
3 | return new Response(
4 | JSON.stringify({ output: `You sent this message to the server: ${input}` }),
5 | );
6 | }
7 |
--------------------------------------------------------------------------------
/app/api/stacks/chat-gemini-streaming-langchain/route.ts:
--------------------------------------------------------------------------------
1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
2 |
3 | export async function POST(req: Request) {
4 | const chat = new ChatGoogleGenerativeAI();
5 | const { messages } = await req.json();
6 |
7 | try {
8 | const textResponse = await chat.invoke([['human', messages]]);
9 | const stream = await chat.stream([
10 | ['human', 'Tell me a joke about bears.'],
11 | ]);
12 |
13 | for await (const chunk of stream) {
14 | console.log(chunk);
15 | }
16 | const output = textResponse.content; // assuming the text you want is in `content`
17 |
18 | const responseJson = JSON.stringify({ output });
19 |
20 | return new Response(responseJson, {
21 | headers: { 'Content-Type': 'application/json' },
22 | });
23 | } catch (error) {
24 | console.error(error);
25 | return new Response(JSON.stringify({ error: 'An error occurred' }), {
26 | status: 500,
27 | headers: { 'Content-Type': 'application/json' },
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/api/stacks/chat-with-gemini-langchain/route.ts:
--------------------------------------------------------------------------------
1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
2 |
3 | export async function POST(req: Request) {
4 | const llm = new ChatGoogleGenerativeAI();
5 | const { messages } = await req.json();
6 |
7 | try {
8 | const textResponse = await llm.invoke([['human', messages]]);
9 | const output = textResponse.content; // assuming the text you want is in `content`
10 |
11 | const responseJson = JSON.stringify({ output });
12 |
13 | return new Response(responseJson, {
14 | headers: { 'Content-Type': 'application/json' },
15 | });
16 | } catch (error) {
17 | console.error(error);
18 | return new Response(JSON.stringify({ error: 'An error occurred' }), {
19 | status: 500,
20 | headers: { 'Content-Type': 'application/json' },
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/api/stacks/chat-with-gemini/route.ts:
--------------------------------------------------------------------------------
1 | import { StreamingTextResponse } from 'ai';
2 |
3 | export async function POST(req: Request) {
4 | const { GoogleGenerativeAI } = require('@google/generative-ai');
5 | const { messages } = await req.json();
6 |
7 | const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
8 | const model = genAI.getGenerativeModel({ model: 'gemini-pro' });
9 |
10 | try {
11 | const result = await model.generateContent(messages);
12 | const response = await result.response;
13 | const text = await response.text();
14 | return new StreamingTextResponse(text);
15 | } catch (error) {
16 | // Handle the error here
17 | console.error('Error occurred:', error);
18 | return new StreamingTextResponse(error);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/api/stacks/chat-with-openai-streaming-helicone/route.ts:
--------------------------------------------------------------------------------
1 | import { OpenAIStream, StreamingTextResponse } from 'ai';
2 | import OpenAI from 'openai';
3 |
4 | const openai = new OpenAI({
5 | apiKey: process.env.OPENAI_API_KEY,
6 | baseURL: 'https://oai.hconeai.com/v1',
7 | defaultHeaders: {
8 | 'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`,
9 | },
10 | });
11 | export const runtime = 'edge';
12 | export async function POST(req: Request) {
13 | const { messages } = await req.json();
14 | const response = await openai.chat.completions.create({
15 | model: 'gpt-3.5-turbo',
16 | stream: true,
17 | messages: [{ role: 'user', content: messages }],
18 | });
19 | const stream = OpenAIStream(response);
20 | return new StreamingTextResponse(stream);
21 | }
22 |
--------------------------------------------------------------------------------
/app/api/stacks/chat-with-openai-streaming-langchain/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { Message as VercelChatMessage, StreamingTextResponse } from "ai";
3 |
4 | import { ChatOpenAI } from "langchain/chat_models/openai";
5 | import { BytesOutputParser } from "langchain/schema/output_parser";
6 | import { PromptTemplate } from "langchain/prompts";
7 |
8 | export const runtime = "edge";
9 |
10 | const formatMessage = (message: VercelChatMessage) => {
11 | return `${message.role}: ${message.content}`;
12 | };
13 |
14 | const TEMPLATE = `
15 | Current conversation:
16 | {chat_history}
17 |
18 | User: {input}
19 | AI:`;
20 |
21 | export async function POST(req: NextRequest) {
22 | try {
23 | const body = await req.json();
24 | const messages = body.messages ?? [];
25 | const formattedPreviousMessages = messages.slice(0, -1).map(formatMessage);
26 | const currentMessageContent = messages[messages.length - 1].content;
27 | const prompt = PromptTemplate.fromTemplate(TEMPLATE);
28 |
29 |
30 | const model = new ChatOpenAI({
31 | temperature: 0.8,
32 | });
33 |
34 | const outputParser = new BytesOutputParser();
35 | const chain = prompt.pipe(model).pipe(outputParser);
36 |
37 | const stream = await chain.stream({
38 | chat_history: formattedPreviousMessages.join("\n"),
39 | input: currentMessageContent,
40 | });
41 |
42 | return new StreamingTextResponse(stream);
43 | } catch (e: any) {
44 | return NextResponse.json({ error: e.message }, { status: 500 });
45 | }
46 | }
--------------------------------------------------------------------------------
/app/api/stacks/chat-with-openai-streaming/route.ts:
--------------------------------------------------------------------------------
1 | import { OpenAIStream, StreamingTextResponse } from 'ai';
2 | import OpenAI from 'openai';
3 |
4 | const openai = new OpenAI({
5 | apiKey: process.env.OPENAI_API_KEY,
6 | });
7 | export const runtime = 'edge';
8 | export async function POST(req: Request) {
9 | const { messages } = await req.json();
10 | const response = await openai.chat.completions.create({
11 | model: 'gpt-3.5-turbo',
12 | stream: true,
13 | messages: [{ role: 'user', content: messages }],
14 | });
15 | const stream = OpenAIStream(response);
16 | return new StreamingTextResponse(stream);
17 | }
18 |
--------------------------------------------------------------------------------
/app/api/stacks/create-stack-boilerplate/get-file-from-github.ts:
--------------------------------------------------------------------------------
1 | export default async function getFileFromGithub(path, token) {
2 | const owner = 'stackwiseai';
3 | const repo = 'stackwise';
4 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository
5 |
6 | const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=main`;
7 | console.log(url, 'url');
8 | const response = await fetch(url, {
9 | headers: {
10 | Authorization: `token ${token}`,
11 | },
12 | });
13 | return response.json();
14 | }
15 |
--------------------------------------------------------------------------------
/app/api/stacks/create-stack-boilerplate/route.ts:
--------------------------------------------------------------------------------
1 | import { Octokit } from '@octokit/rest';
2 |
3 | import createStack from './create-stack';
4 |
5 | const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
6 |
7 | const vercelToken = process.env.VERCEL_TOKEN;
8 | const teamId = process.env.TEAM_ID;
9 | const repoId = process.env.REPO_ID;
10 |
11 | const owner = 'stackwiseai';
12 | const repo = 'stackwise';
13 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository
14 | export const fetchCache = 'force-no-store'; // TODO: remove this line to enable caching but without making the app completely static
15 | export const revalidate = 0;
16 | export async function POST(req: Request) {
17 | const data = await req.json();
18 | // get the token from header and strip the Bearer
19 | try {
20 | if (req.headers) {
21 | const header = req.headers.get('Authorization');
22 | if (header) {
23 | const token = header.split(' ')[1];
24 | const prLink = await createStack(data, token);
25 | return new Response(JSON.stringify({prLink}), {
26 | status: 200,
27 | headers: {
28 | 'Content-Type': 'application/json',
29 | },
30 | });
31 | } else {
32 | throw new Error('No token provided');
33 |
34 | }} else {
35 | throw new Error('No headers provided');
36 | }
37 | } catch (error) {
38 | console.error('Error during data insertion:', error);
39 | return new Response(JSON.stringify({ message: error.message }), {
40 | status: 500,
41 | headers: {
42 | 'Content-Type': 'application/json',
43 | },
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/api/stacks/get-image-description-openai/route.ts:
--------------------------------------------------------------------------------
1 | import { OpenAIStream, StreamingTextResponse } from 'ai';
2 | import OpenAI from 'openai';
3 |
4 | // Create an OpenAI API client (that's edge friendly!)
5 | const openai = new OpenAI({
6 | apiKey: process.env.OPENAI_API_KEY || '',
7 | });
8 |
9 | // IMPORTANT! Set the runtime to edge
10 | export const runtime = 'edge';
11 |
12 | export async function POST(req: Request) {
13 | // 'data' contains the additional data that you have sent:
14 | const { messages, data } = await req.json();
15 |
16 | const initialMessages = messages.slice(0, -1);
17 | const currentMessage = messages[messages.length - 1];
18 |
19 | // Ask OpenAI for a streaming chat completion given the prompt
20 | const response = await openai.chat.completions.create({
21 | model: 'gpt-4-vision-preview',
22 | stream: true,
23 | max_tokens: 150,
24 | messages: [
25 | ...initialMessages,
26 | {
27 | ...currentMessage,
28 | content: [
29 | { type: 'text', text: currentMessage.content },
30 |
31 | // forward the image information to OpenAI:
32 | {
33 | type: 'image_url',
34 | image_url: data.imageUrl,
35 | },
36 | ],
37 | },
38 | ],
39 | });
40 |
41 | // Convert the response into a friendly text-stream
42 | const stream = OpenAIStream(response);
43 | // Respond with the stream
44 | return new StreamingTextResponse(stream);
45 | }
46 |
--------------------------------------------------------------------------------
/app/api/stacks/image-sharpener/route.ts:
--------------------------------------------------------------------------------
1 | import Replicate from 'replicate';
2 |
3 | const replicate = new Replicate({
4 | auth: process.env.REPLICATE_API_TOKEN!,
5 | });
6 |
7 | export const maxDuration = 300;
8 |
9 | export async function POST(request: Request) {
10 | const form = await request.formData();
11 | const imgFile = form.get('img') as Blob;
12 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer());
13 | const imgBase64 = imgBuffer.toString('base64');
14 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`;
15 |
16 | try {
17 | const esrganVersion =
18 | 'nightmareai/real-esrgan:42fed1c4974146d4d2414e2be2c5277c7fcf05fcc3a73abf41610695738c1d7b';
19 | const esrgan = await replicate.run(esrganVersion, {
20 | input: {
21 | image: imgUri,
22 | face_enhance: true,
23 | },
24 | });
25 |
26 | return new Response(JSON.stringify(esrgan), {
27 | status: 200,
28 | headers: { 'Content-Type': 'application/json' },
29 | });
30 | } catch (error) {
31 | console.log(error);
32 | return new Response(JSON.stringify({ error }), {
33 | status: 500,
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/api/stacks/stable-video-diffusion/route.ts:
--------------------------------------------------------------------------------
1 | import * as fal from '@fal-ai/serverless-client';
2 |
3 | fal.config({
4 | credentials: `${process.env.FAL_KEY_ID}:${process.env.FAL_KEY_SECRET}`,
5 | });
6 |
7 | export const maxDuration = 300;
8 |
9 | export async function POST(request: Request) {
10 | let resp = null;
11 |
12 | const form = await request.formData();
13 | const imgFile = form.get('img') as Blob;
14 | const maskFile = form.get('mask') as Blob;
15 | const degreeOfMotion = form.get('degreeOfMotion') as string;
16 |
17 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer());
18 | const maskBuffer = Buffer.from(await maskFile.arrayBuffer());
19 |
20 | const imgBase64 = imgBuffer.toString('base64');
21 | const maskBase64 = maskBuffer.toString('base64');
22 |
23 | // Generate a full URI
24 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`;
25 | const maskUri = `data:${maskFile.type};base64,${maskBase64}`;
26 |
27 | const payload = {
28 | subscriptionId: '110602490-svd',
29 | input: {
30 | image_url: imgUri,
31 | mask_image_url: maskUri,
32 | motion_bucket_id: Number(degreeOfMotion),
33 | cond_aug: 0.02,
34 | steps: 100,
35 | },
36 | pollInterval: 500,
37 | logs: true,
38 | };
39 |
40 | try {
41 | const result: any = await fal.subscribe(payload.subscriptionId, payload);
42 |
43 | resp = result;
44 | } catch (error) {
45 | console.log(error);
46 | return new Response(JSON.stringify({ error }), {
47 | status: 500,
48 | });
49 | }
50 |
51 | return new Response(JSON.stringify(resp), {
52 | status: 200,
53 | headers: { 'Content-Type': 'application/json' },
54 | });
55 | }
56 |
--------------------------------------------------------------------------------
/app/api/stacks/text-to-qr/route.ts:
--------------------------------------------------------------------------------
1 | import Replicate from 'replicate';
2 |
3 | const replicate = new Replicate({
4 | auth: process.env.REPLICATE_API_TOKEN!,
5 | });
6 |
7 | export const maxDuration = 300;
8 |
9 | export async function POST(req: Request) {
10 | const { qrPrompt, url } = await req.json();
11 |
12 | try {
13 | const controlNetVersion =
14 | 'zylim0702/qr_code_controlnet:628e604e13cf63d8ec58bd4d238474e8986b054bc5e1326e50995fdbc851c557';
15 | const qrCode = await replicate.run(controlNetVersion, {
16 | input: {
17 | url: url,
18 | prompt: qrPrompt,
19 | qr_conditioning_scale: 1.3,
20 | },
21 | });
22 |
23 | return new Response(
24 | JSON.stringify({
25 | img: qrCode,
26 | }),
27 | {
28 | status: 200,
29 | headers: { 'Content-Type': 'application/json' },
30 | },
31 | );
32 | } catch (error) {
33 | console.log(error);
34 | return new Response(JSON.stringify({ error }), {
35 | status: 500,
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/api/utils/getAWSPresignedUrl/route.ts:
--------------------------------------------------------------------------------
1 | import AWS from 'aws-sdk';
2 |
3 | AWS.config.update({
4 | region: process.env.AWS_REGION,
5 | accessKeyId: process.env.AWS_ACCESS_KEY_ID,
6 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
7 | });
8 |
9 | export async function POST(req: Request) {
10 | try {
11 | const body = await req.json();
12 | const s3 = new AWS.S3();
13 | const { fileName, fileType } = body;
14 | const params = {
15 | Bucket: 'cover-image-and-subtitle-stack',
16 | Key: fileName,
17 | Expires: 60, // URL expiration time in seconds
18 | ContentType: fileType,
19 | };
20 |
21 | try {
22 | const presignedUrl = await s3.getSignedUrlPromise('putObject', params);
23 | return new Response(JSON.stringify({ url: presignedUrl }), {
24 | status: 200,
25 | });
26 | } catch (error) {
27 | return new Response(
28 | JSON.stringify({ error: 'Error creating presigned URL' }),
29 | { status: 500 },
30 | );
31 | }
32 | } catch (error) {
33 | return new Response(JSON.stringify({ error: 'Bad Request' }), {
34 | status: 400,
35 | });
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/components/shared/ContactButton.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useState } from 'react';
4 | import tw from 'tailwind-styled-components';
5 |
6 | const glowingShadowStyle = {
7 | boxShadow: `0 0 10px rgba(0, 0, 0, 0.6),
8 | 0 0 20px rgba(0, 0, 0, 0.4),
9 | 0 0 30px rgba(0, 0, 0, 0.2)`,
10 | };
11 |
12 | const glowingShadowHoverStyle = {
13 | boxShadow: `0 0 10px rgba(0, 0, 0, 0.7),
14 | 0 0 20px rgba(0, 0, 0, 0.5),
15 | 0 0 30px rgba(0, 0, 0, 0.3),
16 | 0 0 40px rgba(0, 0, 0, 0.1)`,
17 | };
18 |
19 | const ContactButton: React.FC = () => {
20 | const [isHovered, setIsHovered] = useState(false);
21 |
22 | return (
23 |
30 | );
31 | };
32 |
33 | export default ContactButton;
34 |
35 | const Button = tw.button`
36 | bg-black
37 | text-white
38 | font-bold
39 | py-2
40 | px-4
41 | rounded-full
42 | absolute
43 | top-4
44 | right-4
45 | transition duration-300 ease-in-out
46 | `;
47 |
--------------------------------------------------------------------------------
/app/components/shared/clipboard.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import React, { useState } from 'react';
4 | import { FaCheckCircle, FaClipboard } from 'react-icons/fa'; // Importing icons
5 |
6 | interface ClipboardComponentProps {
7 | code: string;
8 | title?: any;
9 | }
10 |
11 | const ClipboardComponent: React.FC = ({
12 | code,
13 | title,
14 | }) => {
15 | const [icon, setIcon] = useState(); // Clipboard icon in black
16 |
17 | const handleClick = async () => {
18 | try {
19 | await navigator.clipboard.writeText(code);
20 | console.log('Text copied to clipboard');
21 | setIcon();
22 | setTimeout(() => {
23 | setIcon();
24 | }, 3000);
25 | } catch (err) {
26 | console.error('Failed to copy: ', err);
27 | }
28 | };
29 |
30 | return (
31 |
38 | );
39 | };
40 |
41 | export default ClipboardComponent;
42 |
--------------------------------------------------------------------------------
/app/components/stacks/creation/Inputs.tsx:
--------------------------------------------------------------------------------
1 | import parse from 'html-react-parser';
2 | import tw from 'tailwind-styled-components';
3 |
4 | interface InputsProps {
5 | formAction: (payload: FormData) => void;
6 | state: string;
7 | }
8 |
9 | const Inputs: React.FC = ({ formAction, state }) => {
10 | return (
11 |
15 | );
16 | };
17 |
18 | export default Inputs;
19 |
20 | const Form = tw.form`
21 | flex
22 | flex-col
23 | space-y-2
24 | w-1/2
25 | `;
26 |
--------------------------------------------------------------------------------
/app/components/stacks/creation/content.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useState } from 'react';
4 | import { useFormState } from 'react-dom';
5 | import tw from 'tailwind-styled-components';
6 |
7 | import { callStack, parseFormData } from '../utils/actions';
8 | import InputWithButton from './input-with-button';
9 | import Inputs from './Inputs';
10 | import Outputs from './outputs';
11 |
12 | const Content = ({ stackDB }) => {
13 | const [outputState, functionAction] = useFormState(parseFormData, null);
14 | const [stackIO, createStack] = useFormState(callStack, {
15 | input: '',
16 | output: '',
17 | });
18 | const [brief, setBrief] = useState('');
19 |
20 | return (
21 | <>
22 |
27 | {brief ? `"${brief}"` : ''}
28 |
29 | {stackIO.input && (
30 | <>
31 |
35 |
39 | >
40 | )}
41 |
42 | {stackIO.input && Deploy}
43 | >
44 | );
45 | };
46 |
47 | const Brief = tw.div`
48 | font-bold
49 | text-lg
50 | mb-2
51 | h-8
52 | `;
53 |
54 | const Container = tw.div`
55 | flex
56 | justify-center
57 | items-center
58 | w-2/3
59 | space-x-6
60 | `;
61 |
62 | const DeployButton = tw.button`
63 | text-white
64 | bg-black
65 | font-bold
66 | py-3
67 | px-6
68 | rounded
69 | mt-4
70 | `;
71 |
72 | export default Content;
73 |
--------------------------------------------------------------------------------
/app/components/stacks/creation/main-content.tsx:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | import tw from 'tailwind-styled-components';
4 |
5 | import Content from './content';
6 |
7 | export default async function MainContent({ stackDB }) {
8 | return (
9 |
10 |
11 |
12 |

13 |
14 | The open source AI app collection.
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
23 | const Container = tw.div`
24 | flex
25 | flex-col
26 | justify-end
27 | //pt-60
28 | pt-24
29 | pb-5
30 | //pb-10
31 | `;
32 |
33 | const TitleContainer = tw.div`
34 | text-center
35 | `;
36 |
37 | const Subtitle = tw.p`
38 | text-lg
39 | `;
40 |
41 | const MainWrapper = tw.div`
42 | w-full
43 | flex
44 | flex-col
45 | justify-center
46 | items-center
47 | `;
48 |
--------------------------------------------------------------------------------
/app/components/stacks/creation/outputs.tsx:
--------------------------------------------------------------------------------
1 | import tw from 'tailwind-styled-components';
2 |
3 | interface InputsProps {
4 | state: string;
5 | value: any;
6 | }
7 |
8 | const Inputs: React.FC = ({ state, value }) => {
9 | const renderContent = () => {
10 | // Split the string by your placeholder pattern
11 | const parts = state.split(/({[^}]+})/).filter(Boolean);
12 |
13 | return parts.map((part, index) => {
14 | if (part.startsWith('{') && part.endsWith('}')) {
15 | // Extract and evaluate the expression
16 | const expression = part.slice(1, -1);
17 |
18 | // Check if the expression is trying to access a property of 'value'
19 | if (expression.startsWith('value.')) {
20 | const property = expression.slice(6);
21 |
22 | // Check if 'value' is an object and the property is not null/undefined
23 | if (value && typeof value === 'object' && value[property] != null) {
24 | return value[property].toString();
25 | }
26 | return ''; // Return an empty string if the property is null/undefined
27 | }
28 |
29 | // Handle the direct 'value' expression
30 | if (expression === 'value') {
31 | return value != null ? value.toString() : '';
32 | }
33 |
34 | return ''; // If the expression cannot be evaluated, return an empty string
35 | } else {
36 | // If part is not an expression, return it as is
37 | return part;
38 | }
39 | });
40 | };
41 |
42 | return (
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default Inputs;
50 |
51 | const Outputs = tw.form`
52 | w-1/2
53 | flex
54 | justify-center
55 | items-center
56 | `;
57 |
--------------------------------------------------------------------------------
/app/components/stacks/utils/actions.ts:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | const MAILCHIMP_URL =
4 | 'https://us17.api.mailchimp.com/3.0/lists/77b1abf780/members/';
5 | const MAILCHIMP_API_KEY = process.env.MAILCHIMP_API_KEY;
6 |
7 | export const subscribeEmail = async (prevState, formData) => {
8 | console.log(prevState, formData);
9 | const email = formData.get('email') as string;
10 |
11 | const data = {
12 | email_address: email,
13 | status: 'subscribed', // or 'pending' for double opt-in
14 | };
15 |
16 | try {
17 | const response = await fetch(MAILCHIMP_URL, {
18 | method: 'POST',
19 | headers: {
20 | Authorization: `Basic ${btoa(`anystring:${MAILCHIMP_API_KEY}`)}`,
21 | 'Content-Type': 'application/json',
22 | },
23 | body: JSON.stringify(data),
24 | });
25 | if (response.ok) {
26 | console.log('Subscription successful');
27 | return { status: 'success' };
28 | } else {
29 | const errorData = await response.json();
30 | console.error('Subscription error:', errorData);
31 | return { status: 'error', error: errorData };
32 | }
33 | } catch (error) {
34 | console.error('Error:', error);
35 | }
36 | };
37 |
38 | // import { stack } from 'stackwise';
39 |
40 | export const callStack = async (prevState: any, formData: FormData) => {
41 | const userRequest = formData.get('stack') as string;
42 | // const message = await stack(userRequest);
43 | const message = 'remove';
44 |
45 | return message;
46 | };
47 |
48 | export const parseFormData = async (prevState: any, formData: FormData) => {
49 | const num1 = Number(formData.get('num1'));
50 | const num2 = Number(formData.get('num2'));
51 |
52 | return await multiplyNumbers(num1, num2);
53 | };
54 |
55 | /**
56 | * Brief: Multiply two numbers together
57 | */
58 | async function multiplyNumbers(num1: number, num2: number): Promise {
59 | return num1 * num2;
60 | }
61 |
--------------------------------------------------------------------------------
/app/components/stacks/utils/signIn.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { supabaseClient } from './stack-db';
4 |
5 | export default function signIn() {
6 | const baseUrl =
7 | process.env.NODE_ENV === 'production'
8 | ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` // Use Vercel's environment variable in production
9 | : 'http://localhost:3000'; // Default to localhost in development
10 |
11 | async function signInWithGithub() {
12 | const { data, error } = await supabaseClient.auth.signInWithOAuth({
13 | provider: 'github',
14 | options: {
15 | scopes: 'public_repo',
16 | redirectTo: `${baseUrl}/stacks/create-stack-boilerplate`,
17 | },
18 | });
19 | }
20 | return (
21 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/app/components/stacks/utils/signOut.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { supabaseClient } from "./stack-db";
4 |
5 |
6 |
7 | export default function signOut() {
8 | async function signOut() {
9 |
10 | const { error } = await supabaseClient.auth.signOut()
11 | }
12 | return ;
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/app/components/stacks/utils/stack-db.ts:
--------------------------------------------------------------------------------
1 | import { createBrowserClient } from '@supabase/ssr';
2 | import { createClient } from '@supabase/supabase-js';
3 |
4 | type Status = 'published' | 'starred' | 'expansion';
5 | export const supabaseClient = createBrowserClient(
6 | process.env.NEXT_PUBLIC_SUPABASE_URL!,
7 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
8 | )
9 | export async function getSupabaseClient() {
10 | return createClient(
11 | process.env.NEXT_PUBLIC_SUPABASE_URL || '',
12 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '',
13 | );
14 | }
15 |
16 | export async function getStackDB() {
17 | const supabase = createClient(
18 | process.env.NEXT_PUBLIC_SUPABASE_URL || '',
19 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '',
20 | );
21 | const { data: projectsArray, error } = await supabase
22 | .from('stack') // Replace with your actual table name
23 | .select('*');
24 |
25 | if (error) {
26 | console.error('Error fetching data:', error);
27 | return null;
28 | }
29 |
30 | const projectsObject: Record = {};
31 | if (projectsArray) {
32 | projectsArray.forEach((project) => {
33 | projectsObject[project.id] = {
34 | name: project.name,
35 | description: project.description,
36 | tags: project.tags,
37 | };
38 | });
39 | }
40 |
41 | return projectsObject;
42 | }
43 |
44 | export interface StackDescription {
45 | name: string;
46 | description: string;
47 | tags: Status[];
48 | }
49 |
50 | export const statusesToDisplay: Status[] = ['published'];
51 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/app/favicon.ico
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | .common-styled input {
6 | @apply w-full
7 | rounded-md
8 | border
9 | border-gray-300
10 | p-3
11 | transition
12 | duration-200
13 | focus:border-blue-500
14 | focus:outline-none;
15 | }
16 |
17 | .common-styled button,
18 | .common-styled [type='button'],
19 | .common-styled [type='reset'],
20 | .common-styled [type='submit'] {
21 | @apply rounded
22 | bg-blue-500
23 | px-4
24 | py-3
25 | font-bold
26 | text-white
27 | hover:bg-blue-700
28 | disabled:bg-slate-500;
29 | }
30 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next';
2 | import { Mulish } from 'next/font/google';
3 | import { Analytics } from '@vercel/analytics/react';
4 |
5 | import './globals.css';
6 |
7 | const inter = Mulish({ subsets: ['latin'] });
8 |
9 | export const metadata: Metadata = {
10 | title: 'Stackwise UI',
11 | description: 'Explain what you want to do you, and AI builds it.',
12 | };
13 |
14 | export default function RootLayout({
15 | children,
16 | }: {
17 | children: React.ReactNode;
18 | }) {
19 | return (
20 |
21 |
22 | {children}
23 |
24 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 |
3 | const nextConfig = {
4 | async redirects() {
5 | return [
6 | {
7 | source: '/',
8 | destination: 'https://github.com/stackwiseai/stackwise',
9 | permanent: true,
10 | },
11 | {
12 | source: '/stack',
13 | destination: '/stacks',
14 | permanent: true,
15 | },
16 | // these are the old uuid-slugged links which were published
17 | // these redirects keep the old links working and we can still use the new slugs
18 | {
19 | source: '/stacks/gbkm2sk',
20 | destination: '/stacks/chat-with-openai-streaming',
21 | permanent: true,
22 | },
23 | {
24 | source: '/stacks/aekmwsk',
25 | destination: '/stacks/elevenlabs-tts',
26 | permanent: true,
27 | },
28 | {
29 | source: '/stacks/fedcba5',
30 | destination: '/stacks/get-image-description-openai',
31 | permanent: true,
32 | },
33 | {
34 | source: '/stacks/abc1234',
35 | destination: '/stacks/use-openai-assistant',
36 | permanent: true,
37 | },
38 | {
39 | source: '/stacks/blkfsSK',
40 | destination: '/stacks/create-ai-canvas',
41 | permanent: true,
42 | },
43 | {
44 | source: '/stacks/ayqflsq',
45 | destination: '/stacks/chat-with-openai-streaming-helicone',
46 | permanent: true,
47 | },
48 | {
49 | source: '/stacks/e4w5wrc',
50 | destination: '/stacks/stable-video-diffusion',
51 | permanent: true,
52 | },
53 | {
54 | source: '/stacks/f2w5orq',
55 | destination: '/stacks/basic-gemini-vision',
56 | permanent: true,
57 | },
58 | ];
59 | },
60 | };
61 |
62 | module.exports = nextConfig;
63 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/public/apocalyptic_car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/apocalyptic_car.png
--------------------------------------------------------------------------------
/public/boat_example.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/boat_example.webp
--------------------------------------------------------------------------------
/public/caesar.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/caesar.jpeg
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/placeholder.png
--------------------------------------------------------------------------------
/public/stack-pictures/boilerplate-basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/boilerplate-basic.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-gemini-streaming-langchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-gemini-streaming-langchain.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-with-gemini-langchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-gemini-langchain.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-with-gemini-streaming.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-gemini-streaming.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-with-gemini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-gemini.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-with-openai-streaming-helicone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-openai-streaming-helicone.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-with-openai-streaming-langchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-openai-streaming-langchain.png
--------------------------------------------------------------------------------
/public/stack-pictures/chat-with-openai-streaming.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-openai-streaming.png
--------------------------------------------------------------------------------
/public/stack-pictures/cover-image-and-subtitle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/cover-image-and-subtitle.png
--------------------------------------------------------------------------------
/public/stack-pictures/create-ai-canvas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/create-ai-canvas.png
--------------------------------------------------------------------------------
/public/stack-pictures/create-stack-boilerplate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/create-stack-boilerplate.png
--------------------------------------------------------------------------------
/public/stack-pictures/elevenlabs-tts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/elevenlabs-tts.png
--------------------------------------------------------------------------------
/public/stack-pictures/generate-a-cover-image-and-subtitle-on-uploading-a-video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/generate-a-cover-image-and-subtitle-on-uploading-a-video.png
--------------------------------------------------------------------------------
/public/stack-pictures/get-image-description-openai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/get-image-description-openai.png
--------------------------------------------------------------------------------
/public/stack-pictures/image-sharpener.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/image-sharpener.png
--------------------------------------------------------------------------------
/public/stack-pictures/image-to-music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/image-to-music.png
--------------------------------------------------------------------------------
/public/stack-pictures/instant-video-to-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/instant-video-to-image.png
--------------------------------------------------------------------------------
/public/stack-pictures/rag-pdf-with-langchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/rag-pdf-with-langchain.png
--------------------------------------------------------------------------------
/public/stack-pictures/stable-video-diffusion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/stable-video-diffusion.png
--------------------------------------------------------------------------------
/public/stack-pictures/stack-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/stack-example.png
--------------------------------------------------------------------------------
/public/stack-pictures/stackwise-onboarding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/stackwise-onboarding.png
--------------------------------------------------------------------------------
/public/stack-pictures/text-to-qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/text-to-qr.png
--------------------------------------------------------------------------------
/public/stack-pictures/use-openai-assistant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/use-openai-assistant.png
--------------------------------------------------------------------------------
/public/stacks/creation/Inputs.tsx:
--------------------------------------------------------------------------------
1 | import parse from 'html-react-parser';
2 | import tw from 'tailwind-styled-components';
3 |
4 | interface InputsProps {
5 | formAction: (payload: FormData) => void;
6 | state: string;
7 | }
8 |
9 | const Inputs: React.FC = ({ formAction, state }) => {
10 | return (
11 |
15 | );
16 | };
17 |
18 | export default Inputs;
19 |
20 | const Form = tw.form`
21 | flex
22 | flex-col
23 | space-y-2
24 | w-1/2
25 | `;
26 |
--------------------------------------------------------------------------------
/public/stacks/creation/content.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useState } from 'react';
4 | import { useFormState } from 'react-dom';
5 | import tw from 'tailwind-styled-components';
6 |
7 | import { callStack, parseFormData } from '../utils/actions';
8 | import InputWithButton from './input-with-button';
9 | import Inputs from './Inputs';
10 | import Outputs from './outputs';
11 |
12 | const Content = ({ stackDB }) => {
13 | const [outputState, functionAction] = useFormState(parseFormData, null);
14 | const [stackIO, createStack] = useFormState(callStack, {
15 | input: '',
16 | output: '',
17 | });
18 | const [brief, setBrief] = useState('');
19 |
20 | return (
21 | <>
22 |
27 | {brief ? `"${brief}"` : ''}
28 |
29 | {stackIO.input && (
30 | <>
31 |
35 |
39 | >
40 | )}
41 |
42 | {stackIO.input && Deploy}
43 | >
44 | );
45 | };
46 |
47 | const Brief = tw.div`
48 | font-bold
49 | text-lg
50 | mb-2
51 | h-8
52 | `;
53 |
54 | const Container = tw.div`
55 | flex
56 | justify-center
57 | items-center
58 | w-2/3
59 | space-x-6
60 | `;
61 |
62 | const DeployButton = tw.button`
63 | text-white
64 | bg-black
65 | font-bold
66 | py-3
67 | px-6
68 | rounded
69 | mt-4
70 | `;
71 |
72 | export default Content;
73 |
--------------------------------------------------------------------------------
/public/stacks/creation/main-content.tsx:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | import tw from 'tailwind-styled-components';
4 |
5 | import Content from './content';
6 |
7 | export default async function MainContent({ stackDB }) {
8 | return (
9 |
10 |
11 |
12 |

13 |
14 | The open source AI app collection.
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
23 | const Container = tw.div`
24 | flex
25 | flex-col
26 | justify-end
27 | //pt-60
28 | pt-24
29 | pb-5
30 | //pb-10
31 | `;
32 |
33 | const TitleContainer = tw.div`
34 | text-center
35 | `;
36 |
37 | const Subtitle = tw.p`
38 | text-lg
39 | `;
40 |
41 | const MainWrapper = tw.div`
42 | w-full
43 | flex
44 | flex-col
45 | justify-center
46 | items-center
47 | `;
48 |
--------------------------------------------------------------------------------
/public/stacks/creation/outputs.tsx:
--------------------------------------------------------------------------------
1 | import tw from 'tailwind-styled-components';
2 |
3 | interface InputsProps {
4 | state: string;
5 | value: any;
6 | }
7 |
8 | const Inputs: React.FC = ({ state, value }) => {
9 | const renderContent = () => {
10 | // Split the string by your placeholder pattern
11 | const parts = state.split(/({[^}]+})/).filter(Boolean);
12 |
13 | return parts.map((part, index) => {
14 | if (part.startsWith('{') && part.endsWith('}')) {
15 | // Extract and evaluate the expression
16 | const expression = part.slice(1, -1);
17 |
18 | // Check if the expression is trying to access a property of 'value'
19 | if (expression.startsWith('value.')) {
20 | const property = expression.slice(6);
21 |
22 | // Check if 'value' is an object and the property is not null/undefined
23 | if (value && typeof value === 'object' && value[property] != null) {
24 | return value[property].toString();
25 | }
26 | return ''; // Return an empty string if the property is null/undefined
27 | }
28 |
29 | // Handle the direct 'value' expression
30 | if (expression === 'value') {
31 | return value != null ? value.toString() : '';
32 | }
33 |
34 | return ''; // If the expression cannot be evaluated, return an empty string
35 | } else {
36 | // If part is not an expression, return it as is
37 | return part;
38 | }
39 | });
40 | };
41 |
42 | return (
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default Inputs;
50 |
51 | const Outputs = tw.form`
52 | w-1/2
53 | flex
54 | justify-center
55 | items-center
56 | `;
57 |
--------------------------------------------------------------------------------
/public/stacks/stacks/basic-openai/route.ts:
--------------------------------------------------------------------------------
1 | import OpenAI from 'openai';
2 |
3 | const openai = new OpenAI({
4 | apiKey: process.env.OPENAI_API_KEY,
5 | });
6 |
7 | export async function POST(req: Request) {
8 | const { messages } = await req.json();
9 | const response = await openai.chat.completions.create({
10 | model: 'gpt-3.5-turbo',
11 | messages: [{ role: 'user', content: messages }],
12 | });
13 | const content = response.choices[0].message.content;
14 | return new Response(JSON.stringify({ content }));
15 | }
16 |
--------------------------------------------------------------------------------
/public/stacks/stacks/boilerplate-basic/route.ts:
--------------------------------------------------------------------------------
1 | export async function POST(req: Request) {
2 | const { input } = await req.json();
3 | return new Response(
4 | JSON.stringify({ output: `You sent this message to the server: ${input}` }),
5 | );
6 | }
7 |
--------------------------------------------------------------------------------
/public/stacks/stacks/chat-gemini-streaming-langchain/route.ts:
--------------------------------------------------------------------------------
1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
2 |
3 | export async function POST(req: Request) {
4 | const chat = new ChatGoogleGenerativeAI();
5 | const { messages } = await req.json();
6 |
7 | try {
8 | const textResponse = await chat.invoke([['human', messages]]);
9 | const stream = await chat.stream([
10 | ['human', 'Tell me a joke about bears.'],
11 | ]);
12 |
13 | for await (const chunk of stream) {
14 | console.log(chunk);
15 | }
16 | const output = textResponse.content; // assuming the text you want is in `content`
17 |
18 | const responseJson = JSON.stringify({ output });
19 |
20 | return new Response(responseJson, {
21 | headers: { 'Content-Type': 'application/json' },
22 | });
23 | } catch (error) {
24 | console.error(error);
25 | return new Response(JSON.stringify({ error: 'An error occurred' }), {
26 | status: 500,
27 | headers: { 'Content-Type': 'application/json' },
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/public/stacks/stacks/chat-with-gemini-langchain/route.ts:
--------------------------------------------------------------------------------
1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
2 |
3 | export async function POST(req: Request) {
4 | const llm = new ChatGoogleGenerativeAI();
5 | const { messages } = await req.json();
6 |
7 | try {
8 | const textResponse = await llm.invoke([['human', messages]]);
9 | const output = textResponse.content; // assuming the text you want is in `content`
10 |
11 | const responseJson = JSON.stringify({ output });
12 |
13 | return new Response(responseJson, {
14 | headers: { 'Content-Type': 'application/json' },
15 | });
16 | } catch (error) {
17 | console.error(error);
18 | return new Response(JSON.stringify({ error: 'An error occurred' }), {
19 | status: 500,
20 | headers: { 'Content-Type': 'application/json' },
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/public/stacks/stacks/chat-with-gemini/route.ts:
--------------------------------------------------------------------------------
1 | import { StreamingTextResponse } from 'ai';
2 |
3 | export async function POST(req: Request) {
4 | const { GoogleGenerativeAI } = require('@google/generative-ai');
5 | const { messages } = await req.json();
6 |
7 | const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
8 | const model = genAI.getGenerativeModel({ model: 'gemini-pro' });
9 |
10 | try {
11 | const result = await model.generateContent(messages);
12 | const response = await result.response;
13 | const text = await response.text();
14 | return new StreamingTextResponse(text);
15 | } catch (error) {
16 | // Handle the error here
17 | console.error('Error occurred:', error);
18 | return new StreamingTextResponse(error);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/public/stacks/stacks/chat-with-openai-streaming-helicone/route.ts:
--------------------------------------------------------------------------------
1 | import { OpenAIStream, StreamingTextResponse } from 'ai';
2 | import OpenAI from 'openai';
3 |
4 | const openai = new OpenAI({
5 | apiKey: process.env.OPENAI_API_KEY,
6 | baseURL: 'https://oai.hconeai.com/v1',
7 | defaultHeaders: {
8 | 'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`,
9 | },
10 | });
11 | export const runtime = 'edge';
12 | export async function POST(req: Request) {
13 | const { messages } = await req.json();
14 | const response = await openai.chat.completions.create({
15 | model: 'gpt-3.5-turbo',
16 | stream: true,
17 | messages: [{ role: 'user', content: messages }],
18 | });
19 | const stream = OpenAIStream(response);
20 | return new StreamingTextResponse(stream);
21 | }
22 |
--------------------------------------------------------------------------------
/public/stacks/stacks/chat-with-openai-streaming-langchain/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { Message as VercelChatMessage, StreamingTextResponse } from "ai";
3 |
4 | import { ChatOpenAI } from "langchain/chat_models/openai";
5 | import { BytesOutputParser } from "langchain/schema/output_parser";
6 | import { PromptTemplate } from "langchain/prompts";
7 |
8 | export const runtime = "edge";
9 |
10 | const formatMessage = (message: VercelChatMessage) => {
11 | return `${message.role}: ${message.content}`;
12 | };
13 |
14 | const TEMPLATE = `
15 | Current conversation:
16 | {chat_history}
17 |
18 | User: {input}
19 | AI:`;
20 |
21 | export async function POST(req: NextRequest) {
22 | try {
23 | const body = await req.json();
24 | const messages = body.messages ?? [];
25 | const formattedPreviousMessages = messages.slice(0, -1).map(formatMessage);
26 | const currentMessageContent = messages[messages.length - 1].content;
27 | const prompt = PromptTemplate.fromTemplate(TEMPLATE);
28 |
29 |
30 | const model = new ChatOpenAI({
31 | temperature: 0.8,
32 | });
33 |
34 | const outputParser = new BytesOutputParser();
35 | const chain = prompt.pipe(model).pipe(outputParser);
36 |
37 | const stream = await chain.stream({
38 | chat_history: formattedPreviousMessages.join("\n"),
39 | input: currentMessageContent,
40 | });
41 |
42 | return new StreamingTextResponse(stream);
43 | } catch (e: any) {
44 | return NextResponse.json({ error: e.message }, { status: 500 });
45 | }
46 | }
--------------------------------------------------------------------------------
/public/stacks/stacks/chat-with-openai-streaming/route.ts:
--------------------------------------------------------------------------------
1 | import { OpenAIStream, StreamingTextResponse } from 'ai';
2 | import OpenAI from 'openai';
3 |
4 | const openai = new OpenAI({
5 | apiKey: process.env.OPENAI_API_KEY,
6 | });
7 | export const runtime = 'edge';
8 | export async function POST(req: Request) {
9 | const { messages } = await req.json();
10 | const response = await openai.chat.completions.create({
11 | model: 'gpt-3.5-turbo',
12 | stream: true,
13 | messages: [{ role: 'user', content: messages }],
14 | });
15 | const stream = OpenAIStream(response);
16 | return new StreamingTextResponse(stream);
17 | }
18 |
--------------------------------------------------------------------------------
/public/stacks/stacks/create-stack-boilerplate/get-file-from-github.ts:
--------------------------------------------------------------------------------
1 | export default async function getFileFromGithub(path, token) {
2 | const owner = 'stackwiseai';
3 | const repo = 'stackwise';
4 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository
5 |
6 | const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=main`;
7 | console.log(url, 'url');
8 | const response = await fetch(url, {
9 | headers: {
10 | Authorization: `token ${token}`,
11 | },
12 | });
13 | return response.json();
14 | }
15 |
--------------------------------------------------------------------------------
/public/stacks/stacks/create-stack-boilerplate/route.ts:
--------------------------------------------------------------------------------
1 | import { Octokit } from '@octokit/rest';
2 |
3 | import createStack from './create-stack';
4 |
5 | const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
6 |
7 | const vercelToken = process.env.VERCEL_TOKEN;
8 | const teamId = process.env.TEAM_ID;
9 | const repoId = process.env.REPO_ID;
10 |
11 | const owner = 'stackwiseai';
12 | const repo = 'stackwise';
13 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository
14 | export const fetchCache = 'force-no-store'; // TODO: remove this line to enable caching but without making the app completely static
15 | export const revalidate = 0;
16 | export async function POST(req: Request) {
17 | const data = await req.json();
18 | // get the token from header and strip the Bearer
19 | try {
20 | if (req.headers) {
21 | const header = req.headers.get('Authorization');
22 | if (header) {
23 | const token = header.split(' ')[1];
24 | const prLink = await createStack(data, token);
25 | return new Response(JSON.stringify({prLink}), {
26 | status: 200,
27 | headers: {
28 | 'Content-Type': 'application/json',
29 | },
30 | });
31 | } else {
32 | throw new Error('No token provided');
33 |
34 | }} else {
35 | throw new Error('No headers provided');
36 | }
37 | } catch (error) {
38 | console.error('Error during data insertion:', error);
39 | return new Response(JSON.stringify({ message: error.message }), {
40 | status: 500,
41 | headers: {
42 | 'Content-Type': 'application/json',
43 | },
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/public/stacks/stacks/get-image-description-openai/route.ts:
--------------------------------------------------------------------------------
1 | import { OpenAIStream, StreamingTextResponse } from 'ai';
2 | import OpenAI from 'openai';
3 |
4 | // Create an OpenAI API client (that's edge friendly!)
5 | const openai = new OpenAI({
6 | apiKey: process.env.OPENAI_API_KEY || '',
7 | });
8 |
9 | // IMPORTANT! Set the runtime to edge
10 | export const runtime = 'edge';
11 |
12 | export async function POST(req: Request) {
13 | // 'data' contains the additional data that you have sent:
14 | const { messages, data } = await req.json();
15 |
16 | const initialMessages = messages.slice(0, -1);
17 | const currentMessage = messages[messages.length - 1];
18 |
19 | // Ask OpenAI for a streaming chat completion given the prompt
20 | const response = await openai.chat.completions.create({
21 | model: 'gpt-4-vision-preview',
22 | stream: true,
23 | max_tokens: 150,
24 | messages: [
25 | ...initialMessages,
26 | {
27 | ...currentMessage,
28 | content: [
29 | { type: 'text', text: currentMessage.content },
30 |
31 | // forward the image information to OpenAI:
32 | {
33 | type: 'image_url',
34 | image_url: data.imageUrl,
35 | },
36 | ],
37 | },
38 | ],
39 | });
40 |
41 | // Convert the response into a friendly text-stream
42 | const stream = OpenAIStream(response);
43 | // Respond with the stream
44 | return new StreamingTextResponse(stream);
45 | }
46 |
--------------------------------------------------------------------------------
/public/stacks/stacks/image-sharpener/route.ts:
--------------------------------------------------------------------------------
1 | import Replicate from 'replicate';
2 |
3 | const replicate = new Replicate({
4 | auth: process.env.REPLICATE_API_TOKEN!,
5 | });
6 |
7 | export const maxDuration = 300;
8 |
9 | export async function POST(request: Request) {
10 | const form = await request.formData();
11 | const imgFile = form.get('img') as Blob;
12 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer());
13 | const imgBase64 = imgBuffer.toString('base64');
14 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`;
15 |
16 | try {
17 | const esrganVersion =
18 | 'nightmareai/real-esrgan:42fed1c4974146d4d2414e2be2c5277c7fcf05fcc3a73abf41610695738c1d7b';
19 | const esrgan = await replicate.run(esrganVersion, {
20 | input: {
21 | image: imgUri,
22 | face_enhance: true,
23 | },
24 | });
25 |
26 | return new Response(JSON.stringify(esrgan), {
27 | status: 200,
28 | headers: { 'Content-Type': 'application/json' },
29 | });
30 | } catch (error) {
31 | console.log(error);
32 | return new Response(JSON.stringify({ error }), {
33 | status: 500,
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/public/stacks/stacks/stable-video-diffusion/route.ts:
--------------------------------------------------------------------------------
1 | import * as fal from '@fal-ai/serverless-client';
2 |
3 | fal.config({
4 | credentials: `${process.env.FAL_KEY_ID}:${process.env.FAL_KEY_SECRET}`,
5 | });
6 |
7 | export const maxDuration = 300;
8 |
9 | export async function POST(request: Request) {
10 | let resp = null;
11 |
12 | const form = await request.formData();
13 | const imgFile = form.get('img') as Blob;
14 | const maskFile = form.get('mask') as Blob;
15 | const degreeOfMotion = form.get('degreeOfMotion') as string;
16 |
17 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer());
18 | const maskBuffer = Buffer.from(await maskFile.arrayBuffer());
19 |
20 | const imgBase64 = imgBuffer.toString('base64');
21 | const maskBase64 = maskBuffer.toString('base64');
22 |
23 | // Generate a full URI
24 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`;
25 | const maskUri = `data:${maskFile.type};base64,${maskBase64}`;
26 |
27 | const payload = {
28 | subscriptionId: '110602490-svd',
29 | input: {
30 | image_url: imgUri,
31 | mask_image_url: maskUri,
32 | motion_bucket_id: Number(degreeOfMotion),
33 | cond_aug: 0.02,
34 | steps: 100,
35 | },
36 | pollInterval: 500,
37 | logs: true,
38 | };
39 |
40 | try {
41 | const result: any = await fal.subscribe(payload.subscriptionId, payload);
42 |
43 | resp = result;
44 | } catch (error) {
45 | console.log(error);
46 | return new Response(JSON.stringify({ error }), {
47 | status: 500,
48 | });
49 | }
50 |
51 | return new Response(JSON.stringify(resp), {
52 | status: 200,
53 | headers: { 'Content-Type': 'application/json' },
54 | });
55 | }
56 |
--------------------------------------------------------------------------------
/public/stacks/stacks/text-to-qr/route.ts:
--------------------------------------------------------------------------------
1 | import Replicate from 'replicate';
2 |
3 | const replicate = new Replicate({
4 | auth: process.env.REPLICATE_API_TOKEN!,
5 | });
6 |
7 | export const maxDuration = 300;
8 |
9 | export async function POST(req: Request) {
10 | const { qrPrompt, url } = await req.json();
11 |
12 | try {
13 | const controlNetVersion =
14 | 'zylim0702/qr_code_controlnet:628e604e13cf63d8ec58bd4d238474e8986b054bc5e1326e50995fdbc851c557';
15 | const qrCode = await replicate.run(controlNetVersion, {
16 | input: {
17 | url: url,
18 | prompt: qrPrompt,
19 | qr_conditioning_scale: 1.3,
20 | },
21 | });
22 |
23 | return new Response(
24 | JSON.stringify({
25 | img: qrCode,
26 | }),
27 | {
28 | status: 200,
29 | headers: { 'Content-Type': 'application/json' },
30 | },
31 | );
32 | } catch (error) {
33 | console.log(error);
34 | return new Response(JSON.stringify({ error }), {
35 | status: 500,
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/public/stacks/utils/actions.ts:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | const MAILCHIMP_URL =
4 | 'https://us17.api.mailchimp.com/3.0/lists/77b1abf780/members/';
5 | const MAILCHIMP_API_KEY = process.env.MAILCHIMP_API_KEY;
6 |
7 | export const subscribeEmail = async (prevState, formData) => {
8 | console.log(prevState, formData);
9 | const email = formData.get('email') as string;
10 |
11 | const data = {
12 | email_address: email,
13 | status: 'subscribed', // or 'pending' for double opt-in
14 | };
15 |
16 | try {
17 | const response = await fetch(MAILCHIMP_URL, {
18 | method: 'POST',
19 | headers: {
20 | Authorization: `Basic ${btoa(`anystring:${MAILCHIMP_API_KEY}`)}`,
21 | 'Content-Type': 'application/json',
22 | },
23 | body: JSON.stringify(data),
24 | });
25 | if (response.ok) {
26 | console.log('Subscription successful');
27 | return { status: 'success' };
28 | } else {
29 | const errorData = await response.json();
30 | console.error('Subscription error:', errorData);
31 | return { status: 'error', error: errorData };
32 | }
33 | } catch (error) {
34 | console.error('Error:', error);
35 | }
36 | };
37 |
38 | // import { stack } from 'stackwise';
39 |
40 | export const callStack = async (prevState: any, formData: FormData) => {
41 | const userRequest = formData.get('stack') as string;
42 | // const message = await stack(userRequest);
43 | const message = 'remove';
44 |
45 | return message;
46 | };
47 |
48 | export const parseFormData = async (prevState: any, formData: FormData) => {
49 | const num1 = Number(formData.get('num1'));
50 | const num2 = Number(formData.get('num2'));
51 |
52 | return await multiplyNumbers(num1, num2);
53 | };
54 |
55 | /**
56 | * Brief: Multiply two numbers together
57 | */
58 | async function multiplyNumbers(num1: number, num2: number): Promise {
59 | return num1 * num2;
60 | }
61 |
--------------------------------------------------------------------------------
/public/stacks/utils/getAWSPresignedUrl/route.ts:
--------------------------------------------------------------------------------
1 | import AWS from 'aws-sdk';
2 |
3 | AWS.config.update({
4 | region: process.env.AWS_REGION,
5 | accessKeyId: process.env.AWS_ACCESS_KEY_ID,
6 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
7 | });
8 |
9 | export async function POST(req: Request) {
10 | try {
11 | const body = await req.json();
12 | const s3 = new AWS.S3();
13 | const { fileName, fileType } = body;
14 | const params = {
15 | Bucket: 'cover-image-and-subtitle-stack',
16 | Key: fileName,
17 | Expires: 60, // URL expiration time in seconds
18 | ContentType: fileType,
19 | };
20 |
21 | try {
22 | const presignedUrl = await s3.getSignedUrlPromise('putObject', params);
23 | return new Response(JSON.stringify({ url: presignedUrl }), {
24 | status: 200,
25 | });
26 | } catch (error) {
27 | return new Response(
28 | JSON.stringify({ error: 'Error creating presigned URL' }),
29 | { status: 500 },
30 | );
31 | }
32 | } catch (error) {
33 | return new Response(JSON.stringify({ error: 'Bad Request' }), {
34 | status: 400,
35 | });
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/public/stacks/utils/signIn.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { supabaseClient } from './stack-db';
4 |
5 | export default function signIn() {
6 | const baseUrl =
7 | process.env.NODE_ENV === 'production'
8 | ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` // Use Vercel's environment variable in production
9 | : 'http://localhost:3000'; // Default to localhost in development
10 |
11 | async function signInWithGithub() {
12 | const { data, error } = await supabaseClient.auth.signInWithOAuth({
13 | provider: 'github',
14 | options: {
15 | scopes: 'public_repo',
16 | redirectTo: `${baseUrl}/stacks/create-stack-boilerplate`,
17 | },
18 | });
19 | }
20 | return (
21 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/public/stacks/utils/signOut.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { supabaseClient } from "./stack-db";
4 |
5 |
6 |
7 | export default function signOut() {
8 | async function signOut() {
9 |
10 | const { error } = await supabaseClient.auth.signOut()
11 | }
12 | return ;
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/public/stacks/utils/stack-db.ts:
--------------------------------------------------------------------------------
1 | import { createBrowserClient } from '@supabase/ssr';
2 | import { createClient } from '@supabase/supabase-js';
3 |
4 | type Status = 'published' | 'starred' | 'expansion';
5 | export const supabaseClient = createBrowserClient(
6 | process.env.NEXT_PUBLIC_SUPABASE_URL!,
7 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
8 | )
9 | export async function getSupabaseClient() {
10 | return createClient(
11 | process.env.NEXT_PUBLIC_SUPABASE_URL || '',
12 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '',
13 | );
14 | }
15 |
16 | export async function getStackDB() {
17 | const supabase = createClient(
18 | process.env.NEXT_PUBLIC_SUPABASE_URL || '',
19 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '',
20 | );
21 | const { data: projectsArray, error } = await supabase
22 | .from('stack') // Replace with your actual table name
23 | .select('*');
24 |
25 | if (error) {
26 | console.error('Error fetching data:', error);
27 | return null;
28 | }
29 |
30 | const projectsObject: Record = {};
31 | if (projectsArray) {
32 | projectsArray.forEach((project) => {
33 | projectsObject[project.id] = {
34 | name: project.name,
35 | description: project.description,
36 | tags: project.tags,
37 | };
38 | });
39 | }
40 |
41 | return projectsObject;
42 | }
43 |
44 | export interface StackDescription {
45 | name: string;
46 | description: string;
47 | tags: Status[];
48 | }
49 |
50 | export const statusesToDisplay: Status[] = ['published'];
51 |
--------------------------------------------------------------------------------
/public/stacks_homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stacks_homepage.png
--------------------------------------------------------------------------------
/public/stackwise_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stackwise_logo.png
--------------------------------------------------------------------------------
/scripts/.gitignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/scripts/sync-stacks.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import * as fs from 'fs-extra';
3 |
4 | async function removeDirectory(dirPath: string): Promise {
5 | try {
6 | await fs.remove(dirPath);
7 | console.log(`Removed directory: ${dirPath}`);
8 | } catch (err) {
9 | console.error(`Error removing directory ${dirPath}:`, err);
10 | }
11 | }
12 |
13 | async function copyRecursively(src: string, dest: string): Promise {
14 | // Create destination folder if it doesn't exist
15 | await fs.ensureDir(dest);
16 |
17 | // Read the source directory
18 | const items = await fs.readdir(src);
19 |
20 | for (const item of items) {
21 | const srcPath = path.join(src, item);
22 | const destPath = path.join(dest, item);
23 |
24 | const stats = await fs.stat(srcPath);
25 |
26 | if (stats.isDirectory()) {
27 | // If it's a directory, call recursively
28 | await copyRecursively(srcPath, destPath);
29 | } else {
30 | // If it's a file, check if it exists in destination
31 | if (!(await fs.pathExists(destPath))) {
32 | // Copy file if it doesn't exist in destination
33 | await fs.copy(srcPath, destPath);
34 | }
35 | }
36 | }
37 | }
38 |
39 | async function main() {
40 | let destinationFolder = '../public/stacks';
41 |
42 | try {
43 | await removeDirectory(destinationFolder);
44 | console.log(`Folder ${destinationFolder} deleted`);
45 |
46 | // Usage example
47 | let sourceFolder = '../app/components/stacks';
48 | await copyRecursively(sourceFolder, destinationFolder);
49 | console.log('Copy completed.');
50 |
51 | sourceFolder = '../app/api';
52 | await copyRecursively(sourceFolder, destinationFolder);
53 | console.log('Copy completed.');
54 | } catch (err) {
55 | console.error('Error during operation:', err);
56 | }
57 | }
58 |
59 | main();
60 |
--------------------------------------------------------------------------------
/scripts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "moduleResolution": "node",
4 | "esModuleInterop": true,
5 | "allowSyntheticDefaultImports": true,
6 | "outDir": "./dist" // Output directory for compiled files
7 |
8 | // other necessary options
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'tailwindcss';
2 |
3 | import baseConfig from '@stackwise-tooling/tailwind-config';
4 |
5 | export default {
6 | darkMode: 'class',
7 | content: [
8 | './pages/**/*.{js,ts,jsx,tsx,mdx}',
9 | './components/**/*.{js,ts,jsx,tsx,mdx}',
10 | './app/**/*.{js,ts,jsx,tsx,mdx}',
11 | ],
12 | presets: [baseConfig],
13 | } satisfies Config;
14 |
--------------------------------------------------------------------------------
/tooling/eslint-config/base.js:
--------------------------------------------------------------------------------
1 | /** @type {import("eslint").Linter.Config} */
2 | const config = {
3 | extends: [
4 | 'turbo',
5 | 'eslint:recommended',
6 | 'plugin:@typescript-eslint/recommended',
7 | 'plugin:@typescript-eslint/recommended-type-checked',
8 | 'plugin:@typescript-eslint/stylistic-type-checked',
9 | 'prettier',
10 | ],
11 | env: {
12 | es2022: true,
13 | node: true,
14 | },
15 | parser: '@typescript-eslint/parser',
16 | parserOptions: {
17 | project: true,
18 | },
19 | plugins: ['@typescript-eslint', 'import', 'only-warn'],
20 | rules: {
21 | 'turbo/no-undeclared-env-vars': 'off',
22 | '@typescript-eslint/no-unused-vars': [
23 | 'error',
24 | { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
25 | ],
26 | '@typescript-eslint/consistent-type-imports': [
27 | 'warn',
28 | { prefer: 'type-imports', fixStyle: 'separate-type-imports' },
29 | ],
30 | '@typescript-eslint/no-misused-promises': [2, { checksVoidReturn: { attributes: false } }],
31 | 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
32 | },
33 | ignorePatterns: [
34 | '**/.eslintrc.cjs',
35 | '**/*.config.js',
36 | '**/*.config.cjs',
37 | '.next',
38 | '.turbo',
39 | 'pnpm-lock.yaml',
40 | ],
41 | reportUnusedDisableDirectives: true,
42 | };
43 |
44 | module.exports = config;
45 |
--------------------------------------------------------------------------------
/tooling/eslint-config/nextjs.js:
--------------------------------------------------------------------------------
1 | /** @type {import('eslint').Linter.Config} */
2 | const config = {
3 | extends: ['plugin:@next/next/recommended'],
4 | rules: {
5 | '@next/next/no-html-link-for-pages': 'off',
6 | },
7 | };
8 |
9 | module.exports = config;
10 |
--------------------------------------------------------------------------------
/tooling/eslint-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@stackwise-tooling/eslint-config",
3 | "version": "0.2.0",
4 | "private": true,
5 | "license": "MIT",
6 | "files": [
7 | "./base.js",
8 | "./nextjs.js",
9 | "./react.js"
10 | ],
11 | "scripts": {
12 | "clean": "rm -rf .turbo node_modules",
13 | "lint": "eslint .",
14 | "format": "prettier --check . --ignore-path ../../.gitignore",
15 | "typecheck": "tsc --noEmit"
16 | },
17 | "dependencies": {
18 | "@next/eslint-plugin-next": "^14.0.3",
19 | "@typescript-eslint/eslint-plugin": "^6.13.2",
20 | "@typescript-eslint/parser": "^6.13.2",
21 | "eslint-config-prettier": "^9.1.0",
22 | "eslint-config-turbo": "^1.10.16",
23 | "eslint-plugin-import": "^2.29.0",
24 | "eslint-plugin-jsx-a11y": "^6.8.0",
25 | "eslint-plugin-react": "^7.33.2",
26 | "eslint-plugin-react-hooks": "^4.6.0"
27 | },
28 | "devDependencies": {
29 | "@stackwise-tooling/prettier-config": "*",
30 | "@stackwise-tooling/tsconfig": "*",
31 | "@types/eslint": "^8.44.8",
32 | "eslint": "^8.55.0",
33 | "eslint-plugin-only-warn": "^1.1.0",
34 | "typescript": "^5.3.2"
35 | },
36 | "eslintConfig": {
37 | "root": true,
38 | "extends": [
39 | "./base.js"
40 | ]
41 | },
42 | "prettier": "@stackwise-tooling/prettier-config"
43 | }
44 |
--------------------------------------------------------------------------------
/tooling/eslint-config/react.js:
--------------------------------------------------------------------------------
1 | /** @type {import('eslint').Linter.Config} */
2 | const config = {
3 | extends: [
4 | 'plugin:react/recommended',
5 | 'plugin:react-hooks/recommended',
6 | 'plugin:jsx-a11y/recommended',
7 | ],
8 | rules: {
9 | 'react/prop-types': 'off',
10 | },
11 | globals: {
12 | React: 'writable',
13 | },
14 | settings: {
15 | react: {
16 | version: 'detect',
17 | },
18 | },
19 | env: {
20 | browser: true,
21 | },
22 | };
23 |
24 | module.exports = config;
25 |
--------------------------------------------------------------------------------
/tooling/eslint-config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@stackwise-tooling/tsconfig/base.json",
3 | "compilerOptions": {
4 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
5 | },
6 | "include": ["."],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/github/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@stackwise-tooling/github"
3 | }
4 |
--------------------------------------------------------------------------------
/tooling/github/setup/action.yml:
--------------------------------------------------------------------------------
1 | name: 'Setup and install'
2 | description: 'Common setup steps for Actions'
3 |
4 | runs:
5 | using: composite
6 | steps:
7 | - uses: actions/setup-node@v4
8 | with:
9 | node-version: 20
10 | cache: 'npm'
11 |
12 | - shell: bash
13 | run: npm install
14 |
15 | - shell: bash
16 | run: npm run build
17 |
--------------------------------------------------------------------------------
/tooling/prettier-config/index.mjs:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from 'url';
2 |
3 | /** @typedef {import("prettier").Config} PrettierConfig */
4 | /** @typedef {import("prettier-plugin-tailwindcss").PluginOptions} TailwindConfig */
5 | /** @typedef {import("@ianvs/prettier-plugin-sort-imports").PluginConfig} SortImportsConfig */
6 |
7 | /** @type { PrettierConfig | SortImportsConfig | TailwindConfig } */
8 | const config = {
9 | printWidth: 80,
10 | tabWidth: 2,
11 | singleQuote: true,
12 | trailingComma: 'all',
13 | arrowParens: 'always',
14 | semi: true,
15 | plugins: ['@ianvs/prettier-plugin-sort-imports', 'prettier-plugin-tailwindcss'],
16 | tailwindConfig: fileURLToPath(new URL('../../tooling/tailwind-config/index.ts', import.meta.url)),
17 | importOrder: [
18 | '^(react/(.*)$)|^(react$)|^(react-native(.*)$)',
19 | '^(next/(.*)$)|^(next$)',
20 | '^(expo(.*)$)|^(expo$)',
21 | '',
22 | '',
23 | '^@stackwise/(.*)$',
24 | '^@stackwise-tooling/(.*)$',
25 | '',
26 | '^~/',
27 | '^[../]',
28 | '^[./]',
29 | ],
30 | importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'],
31 | importOrderTypeScriptVersion: '4.4.0',
32 | };
33 |
34 | export default config;
35 |
--------------------------------------------------------------------------------
/tooling/prettier-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@stackwise-tooling/prettier-config",
3 | "private": true,
4 | "version": "0.1.0",
5 | "main": "index.mjs",
6 | "scripts": {
7 | "clean": "rm -rf .turbo node_modules",
8 | "format": "prettier --check . --ignore-path ../../.gitignore",
9 | "typecheck": "tsc --noEmit"
10 | },
11 | "dependencies": {
12 | "@ianvs/prettier-plugin-sort-imports": "^4.1.1",
13 | "prettier": "^3.1.0",
14 | "prettier-plugin-tailwindcss": "^0.5.7"
15 | },
16 | "devDependencies": {
17 | "@stackwise-tooling/tsconfig": "*",
18 | "typescript": "^5.3.2"
19 | },
20 | "prettier": "@stackwise-tooling/prettier-config"
21 | }
22 |
--------------------------------------------------------------------------------
/tooling/prettier-config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@stackwise-tooling/tsconfig/base.json",
3 | "compilerOptions": {
4 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
5 | },
6 | "include": ["."],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/index.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'tailwindcss';
2 |
3 | const config: Config = {
4 | content: [''],
5 | theme: {
6 | extend: {},
7 | },
8 | plugins: [],
9 | variants: {
10 | extend: {
11 | backgroundColor: ['disabled'],
12 | },
13 | },
14 | };
15 | export default config;
16 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/.bin/tailwind:
--------------------------------------------------------------------------------
1 | ../tailwindcss/lib/cli.js
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/.bin/tailwindcss:
--------------------------------------------------------------------------------
1 | ../tailwindcss/lib/cli.js
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Tailwind Labs, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/base.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/colors.d.ts:
--------------------------------------------------------------------------------
1 | import type { DefaultColors } from './types/generated/colors'
2 | declare const colors: DefaultColors
3 | export = colors
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/colors.js:
--------------------------------------------------------------------------------
1 | let colors = require('./lib/public/colors')
2 | module.exports = (colors.__esModule ? colors : { default: colors }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/components.css:
--------------------------------------------------------------------------------
1 | @tailwind components;
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/defaultConfig.d.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from './types/config'
2 | declare const config: Config
3 | export = config
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/defaultConfig.js:
--------------------------------------------------------------------------------
1 | let defaultConfig = require('./lib/public/default-config')
2 | module.exports = (defaultConfig.__esModule ? defaultConfig : { default: defaultConfig }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/defaultTheme.d.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from './types/config'
2 | import { DefaultTheme } from './types/generated/default-theme'
3 | declare const theme: Config['theme'] & DefaultTheme
4 | export = theme
5 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/defaultTheme.js:
--------------------------------------------------------------------------------
1 | let defaultTheme = require('./lib/public/default-theme')
2 | module.exports = (defaultTheme.__esModule ? defaultTheme : { default: defaultTheme }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/cli-peer-dependencies.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | function _export(target, all) {
6 | for(var name in all)Object.defineProperty(target, name, {
7 | enumerable: true,
8 | get: all[name]
9 | });
10 | }
11 | _export(exports, {
12 | lazyPostcss: function() {
13 | return lazyPostcss;
14 | },
15 | lazyPostcssImport: function() {
16 | return lazyPostcssImport;
17 | },
18 | lazyAutoprefixer: function() {
19 | return lazyAutoprefixer;
20 | },
21 | lazyCssnano: function() {
22 | return lazyCssnano;
23 | }
24 | });
25 | function lazyPostcss() {
26 | return require("postcss");
27 | }
28 | function lazyPostcssImport() {
29 | return require("postcss-import");
30 | }
31 | function lazyAutoprefixer() {
32 | return require("autoprefixer");
33 | }
34 | function lazyCssnano() {
35 | return require("cssnano");
36 | }
37 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | "use strict";
3 | if (false) {
4 | module.exports = require("./oxide/cli");
5 | } else {
6 | module.exports = require("./cli/index");
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/cli/build/deps.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | "use strict";
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | function _export(target, all) {
7 | for(var name in all)Object.defineProperty(target, name, {
8 | enumerable: true,
9 | get: all[name]
10 | });
11 | }
12 | _export(exports, {
13 | loadPostcss: function() {
14 | return loadPostcss;
15 | },
16 | loadPostcssImport: function() {
17 | return loadPostcssImport;
18 | },
19 | loadCssNano: function() {
20 | return loadCssNano;
21 | },
22 | loadAutoprefixer: function() {
23 | return loadAutoprefixer;
24 | }
25 | });
26 | const _index = require("../../../peers/index.js");
27 | function loadPostcss() {
28 | // Try to load a local `postcss` version first
29 | try {
30 | return require("postcss");
31 | } catch {}
32 | return (0, _index.lazyPostcss)();
33 | }
34 | function loadPostcssImport() {
35 | // Try to load a local `postcss-import` version first
36 | try {
37 | return require("postcss-import");
38 | } catch {}
39 | return (0, _index.lazyPostcssImport)();
40 | }
41 | function loadCssNano() {
42 | let options = {
43 | preset: [
44 | "default",
45 | {
46 | cssDeclarationSorter: false
47 | }
48 | ]
49 | };
50 | // Try to load a local `cssnano` version first
51 | try {
52 | return require("cssnano");
53 | } catch {}
54 | return (0, _index.lazyCssnano)()(options);
55 | }
56 | function loadAutoprefixer() {
57 | // Try to load a local `autoprefixer` version first
58 | try {
59 | return require("autoprefixer");
60 | } catch {}
61 | return (0, _index.lazyAutoprefixer)();
62 | }
63 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/css/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Nicolas Gallagher
4 | Copyright (c) Jonathan Neal
5 | Copyright (c) Sindre Sorhus (sindresorhus.com)
6 | Copyright (c) Adam Wathan
7 | Copyright (c) Jonathan Reinink
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = require("./plugin");
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/lib/detectNesting.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | function isRoot(node) {
12 | return node.type === "root";
13 | }
14 | function isAtLayer(node) {
15 | return node.type === "atrule" && node.name === "layer";
16 | }
17 | function _default(_context) {
18 | return (root, result)=>{
19 | let found = false;
20 | root.walkAtRules("tailwind", (node)=>{
21 | if (found) return false;
22 | if (node.parent && !(isRoot(node.parent) || isAtLayer(node.parent))) {
23 | found = true;
24 | node.warn(result, [
25 | "Nested @tailwind rules were detected, but are not supported.",
26 | "Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix",
27 | "Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy"
28 | ].join("\n"));
29 | return false;
30 | }
31 | });
32 | root.walkRules((rule)=>{
33 | if (found) return false;
34 | rule.walkRules((nestedRule)=>{
35 | found = true;
36 | nestedRule.warn(result, [
37 | "Nested CSS was detected, but CSS nesting has not been configured correctly.",
38 | "Please enable a CSS nesting plugin *before* Tailwind in your configuration.",
39 | "See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting"
40 | ].join("\n"));
41 | return false;
42 | });
43 | });
44 | };
45 | }
46 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/lib/load-config.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | function _export(target, all) {
6 | for(var name in all)Object.defineProperty(target, name, {
7 | enumerable: true,
8 | get: all[name]
9 | });
10 | }
11 | _export(exports, {
12 | useCustomJiti: function() {
13 | return useCustomJiti;
14 | },
15 | loadConfig: function() {
16 | return loadConfig;
17 | }
18 | });
19 | const _jiti = /*#__PURE__*/ _interop_require_default(require("jiti"));
20 | const _sucrase = require("sucrase");
21 | function _interop_require_default(obj) {
22 | return obj && obj.__esModule ? obj : {
23 | default: obj
24 | };
25 | }
26 | let jiti = null;
27 | function useCustomJiti(_jiti) {
28 | jiti = _jiti;
29 | }
30 | function lazyJiti() {
31 | return jiti !== null && jiti !== void 0 ? jiti : jiti = (0, _jiti.default)(__filename, {
32 | interopDefault: true,
33 | transform: (opts)=>{
34 | return (0, _sucrase.transform)(opts.source, {
35 | transforms: [
36 | "typescript",
37 | "imports"
38 | ]
39 | });
40 | }
41 | });
42 | }
43 | function loadConfig(path) {
44 | let config = function() {
45 | try {
46 | return path ? require(path) : {};
47 | } catch {
48 | return lazyJiti()(path);
49 | }
50 | }();
51 | var _config_default;
52 | return (_config_default = config.default) !== null && _config_default !== void 0 ? _config_default : config;
53 | }
54 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/lib/partitionApplyAtRules.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return expandApplyAtRules;
9 | }
10 | });
11 | function partitionRules(root) {
12 | if (!root.walkAtRules) return;
13 | let applyParents = new Set();
14 | root.walkAtRules("apply", (rule)=>{
15 | applyParents.add(rule.parent);
16 | });
17 | if (applyParents.size === 0) {
18 | return;
19 | }
20 | for (let rule of applyParents){
21 | let nodeGroups = [];
22 | let lastGroup = [];
23 | for (let node of rule.nodes){
24 | if (node.type === "atrule" && node.name === "apply") {
25 | if (lastGroup.length > 0) {
26 | nodeGroups.push(lastGroup);
27 | lastGroup = [];
28 | }
29 | nodeGroups.push([
30 | node
31 | ]);
32 | } else {
33 | lastGroup.push(node);
34 | }
35 | }
36 | if (lastGroup.length > 0) {
37 | nodeGroups.push(lastGroup);
38 | }
39 | if (nodeGroups.length === 1) {
40 | continue;
41 | }
42 | for (let group of [
43 | ...nodeGroups
44 | ].reverse()){
45 | let clone = rule.clone({
46 | nodes: []
47 | });
48 | clone.append(group);
49 | rule.after(clone);
50 | }
51 | rule.remove();
52 | }
53 | }
54 | function expandApplyAtRules() {
55 | return (root)=>{
56 | partitionRules(root);
57 | };
58 | }
59 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/lib/substituteScreenAtRules.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const _normalizeScreens = require("../util/normalizeScreens");
12 | const _buildMediaQuery = /*#__PURE__*/ _interop_require_default(require("../util/buildMediaQuery"));
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | function _default({ tailwindConfig: { theme } }) {
19 | return function(css) {
20 | css.walkAtRules("screen", (atRule)=>{
21 | let screen = atRule.params;
22 | let screens = (0, _normalizeScreens.normalizeScreens)(theme.screens);
23 | let screenDefinition = screens.find(({ name })=>name === screen);
24 | if (!screenDefinition) {
25 | throw atRule.error(`No \`${screen}\` screen found.`);
26 | }
27 | atRule.name = "media";
28 | atRule.params = (0, _buildMediaQuery.default)(screenDefinition);
29 | });
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/oxide/cli.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | require("./cli/index");
6 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/oxide/postcss-plugin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = require("../plugin.js");
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/postcss-plugins/nesting/README.md:
--------------------------------------------------------------------------------
1 | # tailwindcss/nesting
2 |
3 | This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands Tailwind's custom syntax like `@apply` and `@screen`.
4 |
5 | Add it to your PostCSS configuration, somewhere before Tailwind itself:
6 |
7 | ```js
8 | // postcss.config.js
9 | module.exports = {
10 | plugins: [
11 | require('postcss-import'),
12 | require('tailwindcss/nesting'),
13 | require('tailwindcss'),
14 | require('autoprefixer'),
15 | ]
16 | }
17 | ```
18 |
19 | By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax).
20 |
21 | If you'd rather use [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside:
22 |
23 | ```shell
24 | npm install postcss-nesting
25 | ```
26 |
27 | Then pass the plugin itself as an argument to `tailwindcss/nesting` in your PostCSS configuration:
28 |
29 | ```js
30 | // postcss.config.js
31 | module.exports = {
32 | plugins: [
33 | require('postcss-import'),
34 | require('tailwindcss/nesting')(require('postcss-nesting')),
35 | require('tailwindcss'),
36 | require('autoprefixer'),
37 | ]
38 | }
39 | ```
40 |
41 | This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `tailwindcss/nesting` itself.
42 |
43 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/postcss-plugins/nesting/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const _plugin = require("./plugin");
12 | const _default = Object.assign(function(opts) {
13 | return {
14 | postcssPlugin: "tailwindcss/nesting",
15 | Once (root, { result }) {
16 | return (0, _plugin.nesting)(opts)(root, result);
17 | }
18 | };
19 | }, {
20 | postcss: true
21 | });
22 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/public/create-plugin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const _createPlugin = /*#__PURE__*/ _interop_require_default(require("../util/createPlugin"));
12 | function _interop_require_default(obj) {
13 | return obj && obj.__esModule ? obj : {
14 | default: obj
15 | };
16 | }
17 | const _default = _createPlugin.default;
18 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/public/default-config.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const _cloneDeep = require("../util/cloneDeep");
12 | const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full"));
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | const _default = (0, _cloneDeep.cloneDeep)(_configfull.default);
19 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/public/default-theme.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const _cloneDeep = require("../util/cloneDeep");
12 | const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full"));
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | const _default = (0, _cloneDeep.cloneDeep)(_configfull.default.theme);
19 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/public/load-config.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const _loadconfig = require("../lib/load-config");
12 | const _default = _loadconfig.loadConfig;
13 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/public/resolve-config.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return resolveConfig;
9 | }
10 | });
11 | const _resolveConfig = /*#__PURE__*/ _interop_require_default(require("../util/resolveConfig"));
12 | const _getAllConfigs = /*#__PURE__*/ _interop_require_default(require("../util/getAllConfigs"));
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | function resolveConfig(...configs) {
19 | let [, ...defaultConfigs] = (0, _getAllConfigs.default)(configs[0]);
20 | return (0, _resolveConfig.default)([
21 | ...configs,
22 | ...defaultConfigs
23 | ]);
24 | }
25 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/applyImportantSelector.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "applyImportantSelector", {
6 | enumerable: true,
7 | get: function() {
8 | return applyImportantSelector;
9 | }
10 | });
11 | const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser"));
12 | const _pseudoElements = require("./pseudoElements");
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | function applyImportantSelector(selector, important) {
19 | let sel = (0, _postcssselectorparser.default)().astSync(selector);
20 | sel.each((sel)=>{
21 | // Wrap with :is if it's not already wrapped
22 | let isWrapped = sel.nodes[0].type === "pseudo" && sel.nodes[0].value === ":is" && sel.nodes.every((node)=>node.type !== "combinator");
23 | if (!isWrapped) {
24 | sel.nodes = [
25 | _postcssselectorparser.default.pseudo({
26 | value: ":is",
27 | nodes: [
28 | sel.clone()
29 | ]
30 | })
31 | ];
32 | }
33 | (0, _pseudoElements.movePseudos)(sel);
34 | });
35 | return `${important} ${sel.toString()}`;
36 | }
37 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/bigSign.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return bigSign;
9 | }
10 | });
11 | function bigSign(bigIntValue) {
12 | return (bigIntValue > 0n) - (bigIntValue < 0n);
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/buildMediaQuery.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return buildMediaQuery;
9 | }
10 | });
11 | function buildMediaQuery(screens) {
12 | screens = Array.isArray(screens) ? screens : [
13 | screens
14 | ];
15 | return screens.map((screen)=>{
16 | let values = screen.values.map((screen)=>{
17 | if (screen.raw !== undefined) {
18 | return screen.raw;
19 | }
20 | return [
21 | screen.min && `(min-width: ${screen.min})`,
22 | screen.max && `(max-width: ${screen.max})`
23 | ].filter(Boolean).join(" and ");
24 | });
25 | return screen.not ? `not all and ${values}` : values;
26 | }).join(", ");
27 | }
28 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/cloneDeep.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "cloneDeep", {
6 | enumerable: true,
7 | get: function() {
8 | return cloneDeep;
9 | }
10 | });
11 | function cloneDeep(value) {
12 | if (Array.isArray(value)) {
13 | return value.map((child)=>cloneDeep(child));
14 | }
15 | if (typeof value === "object" && value !== null) {
16 | return Object.fromEntries(Object.entries(value).map(([k, v])=>[
17 | k,
18 | cloneDeep(v)
19 | ]));
20 | }
21 | return value;
22 | }
23 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/configurePlugins.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | function _default(pluginConfig, plugins) {
12 | if (pluginConfig === undefined) {
13 | return plugins;
14 | }
15 | const pluginNames = Array.isArray(pluginConfig) ? pluginConfig : [
16 | ...new Set(plugins.filter((pluginName)=>{
17 | return pluginConfig !== false && pluginConfig[pluginName] !== false;
18 | }).concat(Object.keys(pluginConfig).filter((pluginName)=>{
19 | return pluginConfig[pluginName] !== false;
20 | })))
21 | ];
22 | return pluginNames;
23 | }
24 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/createPlugin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | function createPlugin(plugin, config) {
12 | return {
13 | handler: plugin,
14 | config
15 | };
16 | }
17 | createPlugin.withOptions = function(pluginFunction, configFunction = ()=>({})) {
18 | const optionsFunction = function(options) {
19 | return {
20 | __options: options,
21 | handler: pluginFunction(options),
22 | config: configFunction(options)
23 | };
24 | };
25 | optionsFunction.__isOptionsFunction = true;
26 | // Expose plugin dependencies so that `object-hash` returns a different
27 | // value if anything here changes, to ensure a rebuild is triggered.
28 | optionsFunction.__pluginFunction = pluginFunction;
29 | optionsFunction.__configFunction = configFunction;
30 | return optionsFunction;
31 | };
32 | const _default = createPlugin;
33 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/defaults.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "defaults", {
6 | enumerable: true,
7 | get: function() {
8 | return defaults;
9 | }
10 | });
11 | function defaults(target, ...sources) {
12 | for (let source of sources){
13 | for(let k in source){
14 | var _target_hasOwnProperty;
15 | if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty = target.hasOwnProperty) === null || _target_hasOwnProperty === void 0 ? void 0 : _target_hasOwnProperty.call(target, k))) {
16 | target[k] = source[k];
17 | }
18 | }
19 | for (let k of Object.getOwnPropertySymbols(source)){
20 | var _target_hasOwnProperty1;
21 | if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty1 = target.hasOwnProperty) === null || _target_hasOwnProperty1 === void 0 ? void 0 : _target_hasOwnProperty1.call(target, k))) {
22 | target[k] = source[k];
23 | }
24 | }
25 | }
26 | return target;
27 | }
28 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/escapeClassName.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return escapeClassName;
9 | }
10 | });
11 | const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser"));
12 | const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas"));
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | function escapeClassName(className) {
19 | var _node_raws;
20 | let node = _postcssselectorparser.default.className();
21 | node.value = className;
22 | var _node_raws_value;
23 | return (0, _escapeCommas.default)((_node_raws_value = node === null || node === void 0 ? void 0 : (_node_raws = node.raws) === null || _node_raws === void 0 ? void 0 : _node_raws.value) !== null && _node_raws_value !== void 0 ? _node_raws_value : node.value);
24 | }
25 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/escapeCommas.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return escapeCommas;
9 | }
10 | });
11 | function escapeCommas(className) {
12 | return className.replace(/\\,/g, "\\2c ");
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/flattenColorPalette.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return _default;
9 | }
10 | });
11 | const flattenColorPalette = (colors)=>Object.assign({}, ...Object.entries(colors !== null && colors !== void 0 ? colors : {}).flatMap(([color, values])=>typeof values == "object" ? Object.entries(flattenColorPalette(values)).map(([number, hex])=>({
12 | [color + (number === "DEFAULT" ? "" : `-${number}`)]: hex
13 | })) : [
14 | {
15 | [`${color}`]: values
16 | }
17 | ]));
18 | const _default = flattenColorPalette;
19 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/hashConfig.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return hashConfig;
9 | }
10 | });
11 | const _objecthash = /*#__PURE__*/ _interop_require_default(require("object-hash"));
12 | function _interop_require_default(obj) {
13 | return obj && obj.__esModule ? obj : {
14 | default: obj
15 | };
16 | }
17 | function hashConfig(config) {
18 | return (0, _objecthash.default)(config, {
19 | ignoreUnknown: true
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/isKeyframeRule.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return isKeyframeRule;
9 | }
10 | });
11 | function isKeyframeRule(rule) {
12 | return rule.parent && rule.parent.type === "atrule" && /keyframes$/.test(rule.parent.name);
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/isPlainObject.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return isPlainObject;
9 | }
10 | });
11 | function isPlainObject(value) {
12 | if (Object.prototype.toString.call(value) !== "[object Object]") {
13 | return false;
14 | }
15 | const prototype = Object.getPrototypeOf(value);
16 | return prototype === null || Object.getPrototypeOf(prototype) === null;
17 | }
18 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/log.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | function _export(target, all) {
6 | for(var name in all)Object.defineProperty(target, name, {
7 | enumerable: true,
8 | get: all[name]
9 | });
10 | }
11 | _export(exports, {
12 | dim: function() {
13 | return dim;
14 | },
15 | default: function() {
16 | return _default;
17 | }
18 | });
19 | const _picocolors = /*#__PURE__*/ _interop_require_default(require("picocolors"));
20 | function _interop_require_default(obj) {
21 | return obj && obj.__esModule ? obj : {
22 | default: obj
23 | };
24 | }
25 | let alreadyShown = new Set();
26 | function log(type, messages, key) {
27 | if (typeof process !== "undefined" && process.env.JEST_WORKER_ID) return;
28 | if (key && alreadyShown.has(key)) return;
29 | if (key) alreadyShown.add(key);
30 | console.warn("");
31 | messages.forEach((message)=>console.warn(type, "-", message));
32 | }
33 | function dim(input) {
34 | return _picocolors.default.dim(input);
35 | }
36 | const _default = {
37 | info (key, messages) {
38 | log(_picocolors.default.bold(_picocolors.default.cyan("info")), ...Array.isArray(key) ? [
39 | key
40 | ] : [
41 | messages,
42 | key
43 | ]);
44 | },
45 | warn (key, messages) {
46 | log(_picocolors.default.bold(_picocolors.default.yellow("warn")), ...Array.isArray(key) ? [
47 | key
48 | ] : [
49 | messages,
50 | key
51 | ]);
52 | },
53 | risk (key, messages) {
54 | log(_picocolors.default.bold(_picocolors.default.magenta("risk")), ...Array.isArray(key) ? [
55 | key
56 | ] : [
57 | messages,
58 | key
59 | ]);
60 | }
61 | };
62 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/nameClass.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | function _export(target, all) {
6 | for(var name in all)Object.defineProperty(target, name, {
7 | enumerable: true,
8 | get: all[name]
9 | });
10 | }
11 | _export(exports, {
12 | asClass: function() {
13 | return asClass;
14 | },
15 | default: function() {
16 | return nameClass;
17 | },
18 | formatClass: function() {
19 | return formatClass;
20 | }
21 | });
22 | const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("./escapeClassName"));
23 | const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas"));
24 | function _interop_require_default(obj) {
25 | return obj && obj.__esModule ? obj : {
26 | default: obj
27 | };
28 | }
29 | function asClass(name) {
30 | return (0, _escapeCommas.default)(`.${(0, _escapeClassName.default)(name)}`);
31 | }
32 | function nameClass(classPrefix, key) {
33 | return asClass(formatClass(classPrefix, key));
34 | }
35 | function formatClass(classPrefix, key) {
36 | if (key === "DEFAULT") {
37 | return classPrefix;
38 | }
39 | if (key === "-" || key === "-DEFAULT") {
40 | return `-${classPrefix}`;
41 | }
42 | if (key.startsWith("-")) {
43 | return `-${classPrefix}${key}`;
44 | }
45 | if (key.startsWith("/")) {
46 | return `${classPrefix}${key}`;
47 | }
48 | return `${classPrefix}-${key}`;
49 | }
50 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/negateValue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return negateValue;
9 | }
10 | });
11 | function negateValue(value) {
12 | value = `${value}`;
13 | if (value === "0") {
14 | return "0";
15 | }
16 | // Flip sign of numbers
17 | if (/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(value)) {
18 | return value.replace(/^[+-]?/, (sign)=>sign === "-" ? "" : "-");
19 | }
20 | // What functions we support negating numeric values for
21 | // var() isn't inherently a numeric function but we support it anyway
22 | // The trigonometric functions are omitted because you'll need to use calc(…) with them _anyway_
23 | // to produce generally useful results and that will be covered already
24 | let numericFunctions = [
25 | "var",
26 | "calc",
27 | "min",
28 | "max",
29 | "clamp"
30 | ];
31 | for (const fn of numericFunctions){
32 | if (value.includes(`${fn}(`)) {
33 | return `calc(${value} * -1)`;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/parseDependency.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | /**
3 | * @typedef {{type: 'dependency', file: string} | {type: 'dir-dependency', dir: string, glob: string}} Dependency
4 | */ /**
5 | *
6 | * @param {import('../lib/content.js').ContentPath} contentPath
7 | * @returns {Dependency[]}
8 | */ "use strict";
9 | Object.defineProperty(exports, "__esModule", {
10 | value: true
11 | });
12 | Object.defineProperty(exports, "default", {
13 | enumerable: true,
14 | get: function() {
15 | return parseDependency;
16 | }
17 | });
18 | function parseDependency(contentPath) {
19 | if (contentPath.ignore) {
20 | return [];
21 | }
22 | if (!contentPath.glob) {
23 | return [
24 | {
25 | type: "dependency",
26 | file: contentPath.base
27 | }
28 | ];
29 | }
30 | if (process.env.ROLLUP_WATCH === "true") {
31 | // rollup-plugin-postcss does not support dir-dependency messages
32 | // but directories can be watched in the same way as files
33 | return [
34 | {
35 | type: "dependency",
36 | file: contentPath.base
37 | }
38 | ];
39 | }
40 | return [
41 | {
42 | type: "dir-dependency",
43 | dir: contentPath.base,
44 | glob: contentPath.glob
45 | }
46 | ];
47 | }
48 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/parseGlob.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "parseGlob", {
6 | enumerable: true,
7 | get: function() {
8 | return parseGlob;
9 | }
10 | });
11 | const _globparent = /*#__PURE__*/ _interop_require_default(require("glob-parent"));
12 | function _interop_require_default(obj) {
13 | return obj && obj.__esModule ? obj : {
14 | default: obj
15 | };
16 | }
17 | function parseGlob(pattern) {
18 | let glob = pattern;
19 | let base = (0, _globparent.default)(pattern);
20 | if (base !== ".") {
21 | glob = pattern.substr(base.length);
22 | if (glob.charAt(0) === "/") {
23 | glob = glob.substr(1);
24 | }
25 | }
26 | if (glob.substr(0, 2) === "./") {
27 | glob = glob.substr(2);
28 | }
29 | if (glob.charAt(0) === "/") {
30 | glob = glob.substr(1);
31 | }
32 | return {
33 | base,
34 | glob
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/parseObjectStyles.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return parseObjectStyles;
9 | }
10 | });
11 | const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss"));
12 | const _postcssnested = /*#__PURE__*/ _interop_require_default(require("postcss-nested"));
13 | const _postcssjs = /*#__PURE__*/ _interop_require_default(require("postcss-js"));
14 | function _interop_require_default(obj) {
15 | return obj && obj.__esModule ? obj : {
16 | default: obj
17 | };
18 | }
19 | function parseObjectStyles(styles) {
20 | if (!Array.isArray(styles)) {
21 | return parseObjectStyles([
22 | styles
23 | ]);
24 | }
25 | return styles.flatMap((style)=>{
26 | return (0, _postcss.default)([
27 | (0, _postcssnested.default)({
28 | bubble: [
29 | "screen"
30 | ]
31 | })
32 | ]).process(style, {
33 | parser: _postcssjs.default
34 | }).root.nodes;
35 | });
36 | }
37 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/prefixSelector.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, /**
6 | * @template {string | import('postcss-selector-parser').Root} T
7 | *
8 | * Prefix all classes in the selector with the given prefix
9 | *
10 | * It can take either a string or a selector AST and will return the same type
11 | *
12 | * @param {string} prefix
13 | * @param {T} selector
14 | * @param {boolean} prependNegative
15 | * @returns {T}
16 | */ "default", {
17 | enumerable: true,
18 | get: function() {
19 | return _default;
20 | }
21 | });
22 | const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser"));
23 | function _interop_require_default(obj) {
24 | return obj && obj.__esModule ? obj : {
25 | default: obj
26 | };
27 | }
28 | function _default(prefix, selector, prependNegative = false) {
29 | if (prefix === "") {
30 | return selector;
31 | }
32 | /** @type {import('postcss-selector-parser').Root} */ let ast = typeof selector === "string" ? (0, _postcssselectorparser.default)().astSync(selector) : selector;
33 | ast.walkClasses((classSelector)=>{
34 | let baseClass = classSelector.value;
35 | let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith("-");
36 | classSelector.value = shouldPlaceNegativeBeforePrefix ? `-${prefix}${baseClass.slice(1)}` : `${prefix}${baseClass}`;
37 | });
38 | return typeof selector === "string" ? ast.toString() : ast;
39 | }
40 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/removeAlphaVariables.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This function removes any uses of CSS variables used as an alpha channel
3 | *
4 | * This is required for selectors like `:visited` which do not allow
5 | * changes in opacity or external control using CSS variables.
6 | *
7 | * @param {import('postcss').Container} container
8 | * @param {string[]} toRemove
9 | */ "use strict";
10 | Object.defineProperty(exports, "__esModule", {
11 | value: true
12 | });
13 | Object.defineProperty(exports, "removeAlphaVariables", {
14 | enumerable: true,
15 | get: function() {
16 | return removeAlphaVariables;
17 | }
18 | });
19 | function removeAlphaVariables(container, toRemove) {
20 | container.walkDecls((decl)=>{
21 | if (toRemove.includes(decl.prop)) {
22 | decl.remove();
23 | return;
24 | }
25 | for (let varName of toRemove){
26 | if (decl.value.includes(`/ var(${varName})`)) {
27 | decl.value = decl.value.replace(`/ var(${varName})`, "");
28 | }
29 | }
30 | });
31 | }
32 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/responsive.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return responsive;
9 | }
10 | });
11 | const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss"));
12 | const _cloneNodes = /*#__PURE__*/ _interop_require_default(require("./cloneNodes"));
13 | function _interop_require_default(obj) {
14 | return obj && obj.__esModule ? obj : {
15 | default: obj
16 | };
17 | }
18 | function responsive(rules) {
19 | return _postcss.default.atRule({
20 | name: "responsive"
21 | }).append((0, _cloneNodes.default)(Array.isArray(rules) ? rules : [
22 | rules
23 | ]));
24 | }
25 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/tap.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "tap", {
6 | enumerable: true,
7 | get: function() {
8 | return tap;
9 | }
10 | });
11 | function tap(value, mutator) {
12 | mutator(value);
13 | return value;
14 | }
15 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/toColorValue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "default", {
6 | enumerable: true,
7 | get: function() {
8 | return toColorValue;
9 | }
10 | });
11 | function toColorValue(maybeFunction) {
12 | return typeof maybeFunction === "function" ? maybeFunction({}) : maybeFunction;
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/toPath.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Parse a path string into an array of path segments.
3 | *
4 | * Square bracket notation `a[b]` may be used to "escape" dots that would otherwise be interpreted as path separators.
5 | *
6 | * Example:
7 | * a -> ['a']
8 | * a.b.c -> ['a', 'b', 'c']
9 | * a[b].c -> ['a', 'b', 'c']
10 | * a[b.c].e.f -> ['a', 'b.c', 'e', 'f']
11 | * a[b][c][d] -> ['a', 'b', 'c', 'd']
12 | *
13 | * @param {string|string[]} path
14 | **/ "use strict";
15 | Object.defineProperty(exports, "__esModule", {
16 | value: true
17 | });
18 | Object.defineProperty(exports, "toPath", {
19 | enumerable: true,
20 | get: function() {
21 | return toPath;
22 | }
23 | });
24 | function toPath(path) {
25 | if (Array.isArray(path)) return path;
26 | let openBrackets = path.split("[").length - 1;
27 | let closedBrackets = path.split("]").length - 1;
28 | if (openBrackets !== closedBrackets) {
29 | throw new Error(`Path is invalid. Has unbalanced brackets: ${path}`);
30 | }
31 | return path.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean);
32 | }
33 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/validateConfig.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "validateConfig", {
6 | enumerable: true,
7 | get: function() {
8 | return validateConfig;
9 | }
10 | });
11 | const _log = /*#__PURE__*/ _interop_require_default(require("./log"));
12 | function _interop_require_default(obj) {
13 | return obj && obj.__esModule ? obj : {
14 | default: obj
15 | };
16 | }
17 | function validateConfig(config) {
18 | if (config.content.files.length === 0) {
19 | _log.default.warn("content-problems", [
20 | "The `content` option in your Tailwind CSS configuration is missing or empty.",
21 | "Configure your content sources or your generated CSS will be missing styles.",
22 | "https://tailwindcss.com/docs/content-configuration"
23 | ]);
24 | }
25 | // Warn if the line-clamp plugin is installed
26 | try {
27 | let plugin = require("@tailwindcss/line-clamp");
28 | if (config.plugins.includes(plugin)) {
29 | _log.default.warn("line-clamp-in-core", [
30 | "As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.",
31 | "Remove it from the `plugins` array in your configuration to eliminate this warning."
32 | ]);
33 | config.plugins = config.plugins.filter((p)=>p !== plugin);
34 | }
35 | } catch {}
36 | return config;
37 | }
38 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/util/validateFormalSyntax.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", {
3 | value: true
4 | });
5 | Object.defineProperty(exports, "backgroundSize", {
6 | enumerable: true,
7 | get: function() {
8 | return backgroundSize;
9 | }
10 | });
11 | const _dataTypes = require("./dataTypes");
12 | const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly");
13 | function backgroundSize(value) {
14 | let keywordValues = [
15 | "cover",
16 | "contain"
17 | ];
18 | // the type will probably be a css function
19 | // so we have to use `splitAtTopLevelOnly`
20 | return (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(value, ",").every((part)=>{
21 | let sizes = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(part, "_").filter(Boolean);
22 | if (sizes.length === 1 && keywordValues.includes(sizes[0])) return true;
23 | if (sizes.length !== 1 && sizes.length !== 2) return false;
24 | return sizes.every((size)=>(0, _dataTypes.length)(size) || (0, _dataTypes.percentage)(size) || size === "auto");
25 | });
26 | }
27 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) Bogdan Chadkin
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/README.md:
--------------------------------------------------------------------------------
1 | # postcss-value-parser (forked + inlined)
2 |
3 | This is a customized version of of [PostCSS Value Parser](https://github.com/TrySound/postcss-value-parser) to fix some bugs around parsing CSS functions.
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/index.d.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = postcssValueParser;
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var parse = require("./parse");
3 | var walk = require("./walk");
4 | var stringify = require("./stringify");
5 | function ValueParser(value) {
6 | if (this instanceof ValueParser) {
7 | this.nodes = parse(value);
8 | return this;
9 | }
10 | return new ValueParser(value);
11 | }
12 | ValueParser.prototype.toString = function() {
13 | return Array.isArray(this.nodes) ? stringify(this.nodes) : "";
14 | };
15 | ValueParser.prototype.walk = function(cb, bubble) {
16 | walk(this.nodes, cb, bubble);
17 | return this;
18 | };
19 | ValueParser.unit = require("./unit");
20 | ValueParser.walk = walk;
21 | ValueParser.stringify = stringify;
22 | module.exports = ValueParser;
23 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/stringify.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | function stringifyNode(node, custom) {
3 | var type = node.type;
4 | var value = node.value;
5 | var buf;
6 | var customResult;
7 | if (custom && (customResult = custom(node)) !== undefined) {
8 | return customResult;
9 | } else if (type === "word" || type === "space") {
10 | return value;
11 | } else if (type === "string") {
12 | buf = node.quote || "";
13 | return buf + value + (node.unclosed ? "" : buf);
14 | } else if (type === "comment") {
15 | return "/*" + value + (node.unclosed ? "" : "*/");
16 | } else if (type === "div") {
17 | return (node.before || "") + value + (node.after || "");
18 | } else if (Array.isArray(node.nodes)) {
19 | buf = stringify(node.nodes, custom);
20 | if (type !== "function") {
21 | return buf;
22 | }
23 | return value + "(" + (node.before || "") + buf + (node.after || "") + (node.unclosed ? "" : ")");
24 | }
25 | return value;
26 | }
27 | function stringify(nodes, custom) {
28 | var result, i;
29 | if (Array.isArray(nodes)) {
30 | result = "";
31 | for(i = nodes.length - 1; ~i; i -= 1){
32 | result = stringifyNode(nodes[i], custom) + result;
33 | }
34 | return result;
35 | }
36 | return stringifyNode(nodes, custom);
37 | }
38 | module.exports = stringify;
39 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/walk.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = function walk(nodes, cb, bubble) {
3 | var i, max, node, result;
4 | for(i = 0, max = nodes.length; i < max; i += 1){
5 | node = nodes[i];
6 | if (!bubble) {
7 | result = cb(node, i, nodes);
8 | }
9 | if (result !== false && node.type === "function" && Array.isArray(node.nodes)) {
10 | walk(node.nodes, cb, bubble);
11 | }
12 | if (bubble) {
13 | cb(node, i, nodes);
14 | }
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/loadConfig.d.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from './types/config'
2 |
3 | declare function loadConfig(path: string): Config
4 | export = loadConfig
5 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/loadConfig.js:
--------------------------------------------------------------------------------
1 | let loadConfig = require('./lib/public/load-config')
2 | module.exports = (loadConfig.__esModule ? loadConfig : { default: loadConfig }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/nesting/index.d.ts:
--------------------------------------------------------------------------------
1 | import type { AcceptedPlugin, PluginCreator } from 'postcss'
2 |
3 | declare const plugin: PluginCreator
4 | export = plugin
5 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/nesting/index.js:
--------------------------------------------------------------------------------
1 | let nesting = require('../lib/postcss-plugins/nesting')
2 | module.exports = (nesting.__esModule ? nesting : { default: nesting }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/plugin.d.ts:
--------------------------------------------------------------------------------
1 | import type { Config, PluginCreator } from './types/config'
2 | type Plugin = {
3 | withOptions(
4 | plugin: (options: T) => PluginCreator,
5 | config?: (options: T) => Partial
6 | ): { (options: T): { handler: PluginCreator; config?: Partial }; __isOptionsFunction: true }
7 | (plugin: PluginCreator, config?: Partial): { handler: PluginCreator; config?: Partial }
8 | }
9 |
10 | declare const plugin: Plugin
11 | export = plugin
12 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/plugin.js:
--------------------------------------------------------------------------------
1 | let createPlugin = require('./lib/public/create-plugin')
2 | module.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // These settings are duplicated in .editorconfig:
3 | tabWidth: 2, // indent_size = 2
4 | useTabs: false, // indent_style = space
5 | endOfLine: 'lf', // end_of_line = lf
6 | semi: false, // default: true
7 | singleQuote: true, // default: false
8 | printWidth: 100, // default: 80
9 | trailingComma: 'es5',
10 | bracketSpacing: true,
11 | overrides: [
12 | {
13 | files: '*.js',
14 | options: {
15 | parser: 'flow',
16 | },
17 | },
18 | ],
19 | }
20 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/resolveConfig.d.ts:
--------------------------------------------------------------------------------
1 | import { Config, ResolvableTo, ThemeConfig } from './types/config'
2 | import { DefaultTheme } from './types/generated/default-theme'
3 | import { DefaultColors } from './types/generated/colors'
4 |
5 | type ResolvedConfig = Omit & {
6 | theme: MergeThemes<
7 | UnwrapResolvables>,
8 | T['theme'] extends { extend: infer TExtend } ? UnwrapResolvables : {}
9 | >
10 | }
11 |
12 | type UnwrapResolvables = {
13 | [K in keyof T]: T[K] extends ResolvableTo ? R : T[K]
14 | }
15 |
16 | type ThemeConfigResolved = UnwrapResolvables
17 | type DefaultThemeFull = DefaultTheme & { colors: DefaultColors }
18 |
19 | type MergeThemes = {
20 | [K in keyof ThemeConfigResolved | keyof Overrides]: (K extends keyof Overrides
21 | ? Overrides[K]
22 | : K extends keyof DefaultThemeFull
23 | ? DefaultThemeFull[K]
24 | : K extends keyof ThemeConfigResolved
25 | ? ThemeConfigResolved[K]
26 | : never) &
27 | (K extends keyof Extensions ? Extensions[K] : {})
28 | }
29 |
30 | declare function resolveConfig(config: T): ResolvedConfig
31 | export = resolveConfig
32 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/resolveConfig.js:
--------------------------------------------------------------------------------
1 | let resolveConfig = require('./lib/public/resolve-config')
2 | module.exports = (resolveConfig.__esModule ? resolveConfig : { default: resolveConfig }).default
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/screens.css:
--------------------------------------------------------------------------------
1 | @tailwind screens;
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/scripts/create-plugin-list.js:
--------------------------------------------------------------------------------
1 | import { corePlugins } from '../src/corePlugins'
2 | import fs from 'fs'
3 | import path from 'path'
4 |
5 | let corePluginList = Object.keys(corePlugins)
6 |
7 | fs.writeFileSync(
8 | path.join(process.cwd(), 'src', 'corePluginList.js'),
9 | `export default ${JSON.stringify(corePluginList)}`
10 | )
11 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/scripts/release-channel.js:
--------------------------------------------------------------------------------
1 | // Given a version, figure out what the release channel is so that we can publish to the correct
2 | // channel on npm.
3 | //
4 | // E.g.:
5 | //
6 | // 1.2.3 -> latest (default)
7 | // 0.0.0-insiders.ffaa88 -> insiders
8 | // 4.1.0-alpha.4 -> alpha
9 |
10 | let version =
11 | process.argv[2] || process.env.npm_package_version || require('../package.json').version
12 |
13 | let match = /\d+\.\d+\.\d+-(.*)\.\d+/g.exec(version)
14 | if (match) {
15 | console.log(match[1])
16 | } else {
17 | console.log('latest')
18 | }
19 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/scripts/release-notes.js:
--------------------------------------------------------------------------------
1 | // Given a version, figure out what the release notes are so that we can use this to pre-fill the
2 | // relase notes on a GitHub release for the current version.
3 |
4 | let path = require('path')
5 | let fs = require('fs')
6 |
7 | let version =
8 | process.argv[2] || process.env.npm_package_version || require('../package.json').version
9 |
10 | let changelog = fs.readFileSync(path.resolve(__dirname, '..', 'CHANGELOG.md'), 'utf8')
11 | let match = new RegExp(
12 | `## \\[${version}\\] - (.*)\\n\\n([\\s\\S]*?)\\n(?:(?:##\\s)|(?:\\[))`,
13 | 'g'
14 | ).exec(changelog)
15 |
16 | if (match) {
17 | let [, , notes] = match
18 | console.log(notes.trim())
19 | } else {
20 | console.log(`Placeholder release notes for version: v${version}`)
21 | }
22 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/scripts/swap-engines.js:
--------------------------------------------------------------------------------
1 | let fs = require('fs')
2 | let path = require('path')
3 |
4 | let engines = {
5 | stable: {
6 | files: [
7 | path.resolve(__dirname, '..', 'package.stable.json'),
8 | path.resolve(__dirname, '..', 'package-lock.stable.json'),
9 | ],
10 | },
11 | oxide: {
12 | files: [
13 | path.resolve(__dirname, '..', 'package.oxide.json'),
14 | path.resolve(__dirname, '..', 'package-lock.oxide.json'),
15 | ],
16 | },
17 | }
18 |
19 | // Find out what the current engine is that we are using:
20 | let [otherEngine, info] = Object.entries(engines).find(([, info]) =>
21 | info.files.every((file) => fs.existsSync(file))
22 | )
23 | let currentEngine = otherEngine === 'oxide' ? 'stable' : 'oxide'
24 |
25 | console.log(`Current engine: \`${currentEngine}\`, swapping to \`${otherEngine}\``)
26 |
27 | // Swap the engines
28 | for (let file of info.files) {
29 | fs.renameSync(
30 | file.replace(`.${otherEngine}`, ''),
31 | file.replace(`.${otherEngine}`, `.${currentEngine}`)
32 | )
33 | }
34 | for (let file of engines[otherEngine].files) {
35 | fs.renameSync(file, file.replace(`.${otherEngine}`, ''))
36 | }
37 |
38 | console.log(
39 | 'Engines have been swapped. Make sure to run `npm install` to update your dependencies.'
40 | )
41 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/scripts/type-utils.js:
--------------------------------------------------------------------------------
1 | export function union(types) {
2 | return [...new Set(types)].join(' | ')
3 | }
4 |
5 | export function unionValues(values) {
6 | return union(values.map(forValue))
7 | }
8 |
9 | export function forKeys(value) {
10 | return union(Object.keys(value).map((key) => `'${key}'`))
11 | }
12 |
13 | export function forValue(value) {
14 | if (Array.isArray(value)) {
15 | return `(${unionValues(value)})[]`
16 | }
17 |
18 | if (typeof value === 'object') {
19 | return `Record<${forKeys(value)}, ${unionValues(Object.values(value))}>`
20 | }
21 |
22 | if (typeof value === 'string') {
23 | return `string`
24 | }
25 |
26 | return `any`
27 | }
28 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/cli-peer-dependencies.js:
--------------------------------------------------------------------------------
1 | export function lazyPostcss() {
2 | return require('postcss')
3 | }
4 |
5 | export function lazyPostcssImport() {
6 | return require('postcss-import')
7 | }
8 |
9 | export function lazyAutoprefixer() {
10 | return require('autoprefixer')
11 | }
12 |
13 | export function lazyCssnano() {
14 | return require('cssnano')
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | if (__OXIDE__) {
4 | module.exports = require('./oxide/cli')
5 | } else {
6 | module.exports = require('./cli/index')
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/cli/build/deps.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | import {
4 | // @ts-ignore
5 | lazyPostcss,
6 |
7 | // @ts-ignore
8 | lazyPostcssImport,
9 |
10 | // @ts-ignore
11 | lazyCssnano,
12 |
13 | // @ts-ignore
14 | lazyAutoprefixer,
15 | } from '../../../peers/index.js'
16 |
17 | /**
18 | * @returns {import('postcss')}
19 | */
20 | export function loadPostcss() {
21 | // Try to load a local `postcss` version first
22 | try {
23 | return require('postcss')
24 | } catch {}
25 |
26 | return lazyPostcss()
27 | }
28 |
29 | export function loadPostcssImport() {
30 | // Try to load a local `postcss-import` version first
31 | try {
32 | return require('postcss-import')
33 | } catch {}
34 |
35 | return lazyPostcssImport()
36 | }
37 |
38 | export function loadCssNano() {
39 | let options = { preset: ['default', { cssDeclarationSorter: false }] }
40 |
41 | // Try to load a local `cssnano` version first
42 | try {
43 | return require('cssnano')
44 | } catch {}
45 |
46 | return lazyCssnano()(options)
47 | }
48 |
49 | export function loadAutoprefixer() {
50 | // Try to load a local `autoprefixer` version first
51 | try {
52 | return require('autoprefixer')
53 | } catch {}
54 |
55 | return lazyAutoprefixer()
56 | }
57 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/cli/build/index.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | import fs from 'fs'
4 | import path from 'path'
5 | import { resolveDefaultConfigPath } from '../../util/resolveConfigPath.js'
6 | import { createProcessor } from './plugin.js'
7 |
8 | export async function build(args) {
9 | let input = args['--input']
10 | let shouldWatch = args['--watch']
11 |
12 | // TODO: Deprecate this in future versions
13 | if (!input && args['_'][1]) {
14 | console.error('[deprecation] Running tailwindcss without -i, please provide an input file.')
15 | input = args['--input'] = args['_'][1]
16 | }
17 |
18 | if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) {
19 | console.error(`Specified input file ${args['--input']} does not exist.`)
20 | process.exit(9)
21 | }
22 |
23 | if (args['--config'] && !fs.existsSync((args['--config'] = path.resolve(args['--config'])))) {
24 | console.error(`Specified config file ${args['--config']} does not exist.`)
25 | process.exit(9)
26 | }
27 |
28 | // TODO: Reference the @config path here if exists
29 | let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath()
30 |
31 | let processor = await createProcessor(args, configPath)
32 |
33 | if (shouldWatch) {
34 | // Abort the watcher if stdin is closed to avoid zombie processes
35 | // You can disable this behavior with --watch=always
36 | if (args['--watch'] !== 'always') {
37 | process.stdin.on('end', () => process.exit(0))
38 | }
39 |
40 | process.stdin.resume()
41 |
42 | await processor.watch()
43 | } else {
44 | await processor.build().catch((e) => {
45 | console.error(e)
46 | process.exit(1)
47 | })
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/css/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Nicolas Gallagher
4 | Copyright (c) Jonathan Neal
5 | Copyright (c) Sindre Sorhus (sindresorhus.com)
6 | Copyright (c) Adam Wathan
7 | Copyright (c) Jonathan Reinink
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./plugin')
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/cacheInvalidation.js:
--------------------------------------------------------------------------------
1 | import crypto from 'crypto'
2 | import * as sharedState from './sharedState'
3 |
4 | /**
5 | * Calculate the hash of a string.
6 | *
7 | * This doesn't need to be cryptographically secure or
8 | * anything like that since it's used only to detect
9 | * when the CSS changes to invalidate the context.
10 | *
11 | * This is wrapped in a try/catch because it's really dependent
12 | * on how Node itself is build and the environment and OpenSSL
13 | * version / build that is installed on the user's machine.
14 | *
15 | * Based on the environment this can just outright fail.
16 | *
17 | * See https://github.com/nodejs/node/issues/40455
18 | *
19 | * @param {string} str
20 | */
21 | function getHash(str) {
22 | try {
23 | return crypto.createHash('md5').update(str, 'utf-8').digest('binary')
24 | } catch (err) {
25 | return ''
26 | }
27 | }
28 |
29 | /**
30 | * Determine if the CSS tree is different from the
31 | * previous version for the given `sourcePath`.
32 | *
33 | * @param {string} sourcePath
34 | * @param {import('postcss').Node} root
35 | */
36 | export function hasContentChanged(sourcePath, root) {
37 | let css = root.toString()
38 |
39 | // We only care about files with @tailwind directives
40 | // Other files use an existing context
41 | if (!css.includes('@tailwind')) {
42 | return false
43 | }
44 |
45 | let existingHash = sharedState.sourceHashMap.get(sourcePath)
46 | let rootHash = getHash(css)
47 | let didChange = existingHash !== rootHash
48 |
49 | sharedState.sourceHashMap.set(sourcePath, rootHash)
50 |
51 | return didChange
52 | }
53 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/collapseAdjacentRules.js:
--------------------------------------------------------------------------------
1 | let comparisonMap = {
2 | atrule: ['name', 'params'],
3 | rule: ['selector'],
4 | }
5 | let types = new Set(Object.keys(comparisonMap))
6 |
7 | export default function collapseAdjacentRules() {
8 | function collapseRulesIn(root) {
9 | let currentRule = null
10 | root.each((node) => {
11 | if (!types.has(node.type)) {
12 | currentRule = null
13 | return
14 | }
15 |
16 | if (currentRule === null) {
17 | currentRule = node
18 | return
19 | }
20 |
21 | let properties = comparisonMap[node.type]
22 |
23 | if (node.type === 'atrule' && node.name === 'font-face') {
24 | currentRule = node
25 | } else if (
26 | properties.every(
27 | (property) =>
28 | (node[property] ?? '').replace(/\s+/g, ' ') ===
29 | (currentRule[property] ?? '').replace(/\s+/g, ' ')
30 | )
31 | ) {
32 | // An AtRule may not have children (for example if we encounter duplicate @import url(…) rules)
33 | if (node.nodes) {
34 | currentRule.append(node.nodes)
35 | }
36 |
37 | node.remove()
38 | } else {
39 | currentRule = node
40 | }
41 | })
42 |
43 | // After we've collapsed adjacent rules & at-rules, we need to collapse
44 | // adjacent rules & at-rules that are children of at-rules.
45 | // We do not care about nesting rules because Tailwind CSS
46 | // explicitly does not handle rule nesting on its own as
47 | // the user is expected to use a nesting plugin
48 | root.each((node) => {
49 | if (node.type === 'atrule') {
50 | collapseRulesIn(node)
51 | }
52 | })
53 | }
54 |
55 | return (root) => {
56 | collapseRulesIn(root)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/detectNesting.js:
--------------------------------------------------------------------------------
1 | function isRoot(node) {
2 | return node.type === 'root'
3 | }
4 |
5 | function isAtLayer(node) {
6 | return node.type === 'atrule' && node.name === 'layer'
7 | }
8 |
9 | export default function (_context) {
10 | return (root, result) => {
11 | let found = false
12 |
13 | root.walkAtRules('tailwind', (node) => {
14 | if (found) return false
15 |
16 | if (node.parent && !(isRoot(node.parent) || isAtLayer(node.parent))) {
17 | found = true
18 | node.warn(
19 | result,
20 | [
21 | 'Nested @tailwind rules were detected, but are not supported.',
22 | "Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix",
23 | 'Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy',
24 | ].join('\n')
25 | )
26 | return false
27 | }
28 | })
29 |
30 | root.walkRules((rule) => {
31 | if (found) return false
32 |
33 | rule.walkRules((nestedRule) => {
34 | found = true
35 | nestedRule.warn(
36 | result,
37 | [
38 | 'Nested CSS was detected, but CSS nesting has not been configured correctly.',
39 | 'Please enable a CSS nesting plugin *before* Tailwind in your configuration.',
40 | 'See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting',
41 | ].join('\n')
42 | )
43 | return false
44 | })
45 | })
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/findAtConfigPath.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 |
4 | /**
5 | * Find the @config at-rule in the given CSS AST and return the relative path to the config file
6 | *
7 | * @param {import('postcss').Root} root
8 | * @param {import('postcss').Result} result
9 | */
10 | export function findAtConfigPath(root, result) {
11 | let configPath = null
12 | let relativeTo = null
13 |
14 | root.walkAtRules('config', (rule) => {
15 | relativeTo = rule.source?.input.file ?? result.opts.from ?? null
16 |
17 | if (relativeTo === null) {
18 | throw rule.error(
19 | 'The `@config` directive cannot be used without setting `from` in your PostCSS config.'
20 | )
21 | }
22 |
23 | if (configPath) {
24 | throw rule.error('Only one `@config` directive is allowed per file.')
25 | }
26 |
27 | let matches = rule.params.match(/(['"])(.*?)\1/)
28 | if (!matches) {
29 | throw rule.error('A path is required when using the `@config` directive.')
30 | }
31 |
32 | let inputPath = matches[2]
33 | if (path.isAbsolute(inputPath)) {
34 | throw rule.error('The `@config` directive cannot be used with an absolute path.')
35 | }
36 |
37 | configPath = path.resolve(path.dirname(relativeTo), inputPath)
38 | if (!fs.existsSync(configPath)) {
39 | throw rule.error(
40 | `The config file at "${inputPath}" does not exist. Make sure the path is correct and the file exists.`
41 | )
42 | }
43 |
44 | rule.remove()
45 | })
46 |
47 | return configPath ? configPath : null
48 | }
49 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/load-config.ts:
--------------------------------------------------------------------------------
1 | import jitiFactory from 'jiti'
2 | import { transform } from 'sucrase'
3 |
4 | import { Config } from '../../types/config'
5 |
6 | let jiti: ReturnType | null = null
7 |
8 | // @internal
9 | // This WILL be removed in some future release
10 | // If you rely on this your stuff WILL break
11 | export function useCustomJiti(_jiti: ReturnType) {
12 | jiti = _jiti
13 | }
14 |
15 | function lazyJiti() {
16 | return (
17 | jiti ??
18 | (jiti = jitiFactory(__filename, {
19 | interopDefault: true,
20 | transform: (opts) => {
21 | return transform(opts.source, {
22 | transforms: ['typescript', 'imports'],
23 | })
24 | },
25 | }))
26 | )
27 | }
28 |
29 | export function loadConfig(path: string): Config {
30 | let config = (function () {
31 | try {
32 | return path ? require(path) : {}
33 | } catch {
34 | return lazyJiti()(path)
35 | }
36 | })()
37 |
38 | return config.default ?? config
39 | }
40 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/partitionApplyAtRules.js:
--------------------------------------------------------------------------------
1 | function partitionRules(root) {
2 | if (!root.walkAtRules) return
3 |
4 | let applyParents = new Set()
5 |
6 | root.walkAtRules('apply', (rule) => {
7 | applyParents.add(rule.parent)
8 | })
9 |
10 | if (applyParents.size === 0) {
11 | return
12 | }
13 |
14 | for (let rule of applyParents) {
15 | let nodeGroups = []
16 | let lastGroup = []
17 |
18 | for (let node of rule.nodes) {
19 | if (node.type === 'atrule' && node.name === 'apply') {
20 | if (lastGroup.length > 0) {
21 | nodeGroups.push(lastGroup)
22 | lastGroup = []
23 | }
24 | nodeGroups.push([node])
25 | } else {
26 | lastGroup.push(node)
27 | }
28 | }
29 |
30 | if (lastGroup.length > 0) {
31 | nodeGroups.push(lastGroup)
32 | }
33 |
34 | if (nodeGroups.length === 1) {
35 | continue
36 | }
37 |
38 | for (let group of [...nodeGroups].reverse()) {
39 | let clone = rule.clone({ nodes: [] })
40 | clone.append(group)
41 | rule.after(clone)
42 | }
43 |
44 | rule.remove()
45 | }
46 | }
47 |
48 | export default function expandApplyAtRules() {
49 | return (root) => {
50 | partitionRules(root)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/sharedState.js:
--------------------------------------------------------------------------------
1 | import pkg from '../../package.json'
2 |
3 | export const env =
4 | typeof process !== 'undefined'
5 | ? {
6 | NODE_ENV: process.env.NODE_ENV,
7 | DEBUG: resolveDebug(process.env.DEBUG),
8 | ENGINE: pkg.tailwindcss.engine,
9 | }
10 | : {
11 | NODE_ENV: 'production',
12 | DEBUG: false,
13 | ENGINE: pkg.tailwindcss.engine,
14 | }
15 |
16 | export const contextMap = new Map()
17 | export const configContextMap = new Map()
18 | export const contextSourcesMap = new Map()
19 | export const sourceHashMap = new Map()
20 | export const NOT_ON_DEMAND = new String('*')
21 |
22 | export const NONE = Symbol('__NONE__')
23 |
24 | export function resolveDebug(debug) {
25 | if (debug === undefined) {
26 | return false
27 | }
28 |
29 | // Environment variables are strings, so convert to boolean
30 | if (debug === 'true' || debug === '1') {
31 | return true
32 | }
33 |
34 | if (debug === 'false' || debug === '0') {
35 | return false
36 | }
37 |
38 | // Keep the debug convention into account:
39 | // DEBUG=* -> This enables all debug modes
40 | // DEBUG=projectA,projectB,projectC -> This enables debug for projectA, projectB and projectC
41 | // DEBUG=projectA:* -> This enables all debug modes for projectA (if you have sub-types)
42 | // DEBUG=projectA,-projectB -> This enables debug for projectA and explicitly disables it for projectB
43 |
44 | if (debug === '*') {
45 | return true
46 | }
47 |
48 | let debuggers = debug.split(',').map((d) => d.split(':')[0])
49 |
50 | // Ignoring tailwindcss
51 | if (debuggers.includes('-tailwindcss')) {
52 | return false
53 | }
54 |
55 | // Including tailwindcss
56 | if (debuggers.includes('tailwindcss')) {
57 | return true
58 | }
59 |
60 | return false
61 | }
62 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/lib/substituteScreenAtRules.js:
--------------------------------------------------------------------------------
1 | import { normalizeScreens } from '../util/normalizeScreens'
2 | import buildMediaQuery from '../util/buildMediaQuery'
3 |
4 | export default function ({ tailwindConfig: { theme } }) {
5 | return function (css) {
6 | css.walkAtRules('screen', (atRule) => {
7 | let screen = atRule.params
8 | let screens = normalizeScreens(theme.screens)
9 | let screenDefinition = screens.find(({ name }) => name === screen)
10 |
11 | if (!screenDefinition) {
12 | throw atRule.error(`No \`${screen}\` screen found.`)
13 | }
14 |
15 | atRule.name = 'media'
16 | atRule.params = buildMediaQuery(screenDefinition)
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/oxide/cli.ts:
--------------------------------------------------------------------------------
1 | import './cli/index'
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/oxide/cli/build/index.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import { resolveDefaultConfigPath } from '../../../util/resolveConfigPath'
4 | import { createProcessor } from './plugin'
5 |
6 | export async function build(args) {
7 | let input = args['--input']
8 | let shouldWatch = args['--watch']
9 |
10 | // TODO: Deprecate this in future versions
11 | if (!input && args['_'][1]) {
12 | console.error('[deprecation] Running tailwindcss without -i, please provide an input file.')
13 | input = args['--input'] = args['_'][1]
14 | }
15 |
16 | if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) {
17 | console.error(`Specified input file ${args['--input']} does not exist.`)
18 | process.exit(9)
19 | }
20 |
21 | if (args['--config'] && !fs.existsSync((args['--config'] = path.resolve(args['--config'])))) {
22 | console.error(`Specified config file ${args['--config']} does not exist.`)
23 | process.exit(9)
24 | }
25 |
26 | // TODO: Reference the @config path here if exists
27 | let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath()
28 |
29 | let processor = await createProcessor(args, configPath)
30 |
31 | if (shouldWatch) {
32 | // Abort the watcher if stdin is closed to avoid zombie processes
33 | // You can disable this behavior with --watch=always
34 | if (args['--watch'] !== 'always') {
35 | process.stdin.on('end', () => process.exit(0))
36 | }
37 |
38 | process.stdin.resume()
39 |
40 | await processor.watch()
41 | } else {
42 | await processor.build().catch((e) => {
43 | console.error(e)
44 | process.exit(1)
45 | })
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/oxide/postcss-plugin.ts:
--------------------------------------------------------------------------------
1 | module.exports = require('../plugin.js')
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/postcss-plugins/nesting/index.js:
--------------------------------------------------------------------------------
1 | import { nesting } from './plugin'
2 |
3 | export default Object.assign(
4 | function (opts) {
5 | return {
6 | postcssPlugin: 'tailwindcss/nesting',
7 | Once(root, { result }) {
8 | return nesting(opts)(root, result)
9 | },
10 | }
11 | },
12 | { postcss: true }
13 | )
14 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/public/create-plugin.js:
--------------------------------------------------------------------------------
1 | import createPlugin from '../util/createPlugin'
2 | export default createPlugin
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/public/default-config.js:
--------------------------------------------------------------------------------
1 | import { cloneDeep } from '../util/cloneDeep'
2 | import defaultConfig from '../../stubs/config.full'
3 |
4 | export default cloneDeep(defaultConfig)
5 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/public/default-theme.js:
--------------------------------------------------------------------------------
1 | import { cloneDeep } from '../util/cloneDeep'
2 | import defaultFullConfig from '../../stubs/config.full'
3 |
4 | export default cloneDeep(defaultFullConfig.theme)
5 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/public/load-config.js:
--------------------------------------------------------------------------------
1 | import { loadConfig } from '../lib/load-config'
2 | export default loadConfig
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/public/resolve-config.js:
--------------------------------------------------------------------------------
1 | import resolveConfigObjects from '../util/resolveConfig'
2 | import getAllConfigs from '../util/getAllConfigs'
3 |
4 | export default function resolveConfig(...configs) {
5 | let [, ...defaultConfigs] = getAllConfigs(configs[0])
6 | return resolveConfigObjects([...configs, ...defaultConfigs])
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/applyImportantSelector.js:
--------------------------------------------------------------------------------
1 | import parser from 'postcss-selector-parser'
2 | import { movePseudos } from './pseudoElements'
3 |
4 | export function applyImportantSelector(selector, important) {
5 | let sel = parser().astSync(selector)
6 |
7 | sel.each((sel) => {
8 | // Wrap with :is if it's not already wrapped
9 | let isWrapped =
10 | sel.nodes[0].type === 'pseudo' &&
11 | sel.nodes[0].value === ':is' &&
12 | sel.nodes.every((node) => node.type !== 'combinator')
13 |
14 | if (!isWrapped) {
15 | sel.nodes = [
16 | parser.pseudo({
17 | value: ':is',
18 | nodes: [sel.clone()],
19 | }),
20 | ]
21 | }
22 |
23 | movePseudos(sel)
24 | })
25 |
26 | return `${important} ${sel.toString()}`
27 | }
28 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/bigSign.js:
--------------------------------------------------------------------------------
1 | export default function bigSign(bigIntValue) {
2 | return (bigIntValue > 0n) - (bigIntValue < 0n)
3 | }
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/buildMediaQuery.js:
--------------------------------------------------------------------------------
1 | export default function buildMediaQuery(screens) {
2 | screens = Array.isArray(screens) ? screens : [screens]
3 |
4 | return screens
5 | .map((screen) => {
6 | let values = screen.values.map((screen) => {
7 | if (screen.raw !== undefined) {
8 | return screen.raw
9 | }
10 |
11 | return [
12 | screen.min && `(min-width: ${screen.min})`,
13 | screen.max && `(max-width: ${screen.max})`,
14 | ]
15 | .filter(Boolean)
16 | .join(' and ')
17 | })
18 |
19 | return screen.not ? `not all and ${values}` : values
20 | })
21 | .join(', ')
22 | }
23 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/cloneDeep.js:
--------------------------------------------------------------------------------
1 | export function cloneDeep(value) {
2 | if (Array.isArray(value)) {
3 | return value.map((child) => cloneDeep(child))
4 | }
5 |
6 | if (typeof value === 'object' && value !== null) {
7 | return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, cloneDeep(v)]))
8 | }
9 |
10 | return value
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/cloneNodes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {import('postcss').Container[]} nodes
3 | * @param {any} source
4 | * @param {any} raws
5 | * @returns {import('postcss').Container[]}
6 | */
7 | export default function cloneNodes(nodes, source = undefined, raws = undefined) {
8 | return nodes.map((node) => {
9 | let cloned = node.clone()
10 |
11 | if (raws !== undefined) {
12 | cloned.raws.tailwind = {
13 | ...cloned.raws.tailwind,
14 | ...raws,
15 | }
16 | }
17 |
18 | if (source !== undefined) {
19 | traverse(cloned, (node) => {
20 | // Do not traverse nodes that have opted
21 | // to preserve their original source
22 | let shouldPreserveSource = node.raws.tailwind?.preserveSource === true && node.source
23 | if (shouldPreserveSource) {
24 | return false
25 | }
26 |
27 | // Otherwise we can safely replace the source
28 | // And continue traversing
29 | node.source = source
30 | })
31 | }
32 |
33 | return cloned
34 | })
35 | }
36 |
37 | /**
38 | * Traverse a tree of nodes and don't traverse children if the callback
39 | * returns false. Ideally we'd use Container#walk instead of this
40 | * function but it stops traversing siblings too.
41 | *
42 | * @param {import('postcss').Container} node
43 | * @param {(node: import('postcss').Container) => boolean} onNode
44 | */
45 | function traverse(node, onNode) {
46 | if (onNode(node) !== false) {
47 | node.each?.((child) => traverse(child, onNode))
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/configurePlugins.js:
--------------------------------------------------------------------------------
1 | export default function (pluginConfig, plugins) {
2 | if (pluginConfig === undefined) {
3 | return plugins
4 | }
5 |
6 | const pluginNames = Array.isArray(pluginConfig)
7 | ? pluginConfig
8 | : [
9 | ...new Set(
10 | plugins
11 | .filter((pluginName) => {
12 | return pluginConfig !== false && pluginConfig[pluginName] !== false
13 | })
14 | .concat(
15 | Object.keys(pluginConfig).filter((pluginName) => {
16 | return pluginConfig[pluginName] !== false
17 | })
18 | )
19 | ),
20 | ]
21 |
22 | return pluginNames
23 | }
24 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/createPlugin.js:
--------------------------------------------------------------------------------
1 | function createPlugin(plugin, config) {
2 | return {
3 | handler: plugin,
4 | config,
5 | }
6 | }
7 |
8 | createPlugin.withOptions = function (pluginFunction, configFunction = () => ({})) {
9 | const optionsFunction = function (options) {
10 | return {
11 | __options: options,
12 | handler: pluginFunction(options),
13 | config: configFunction(options),
14 | }
15 | }
16 |
17 | optionsFunction.__isOptionsFunction = true
18 |
19 | // Expose plugin dependencies so that `object-hash` returns a different
20 | // value if anything here changes, to ensure a rebuild is triggered.
21 | optionsFunction.__pluginFunction = pluginFunction
22 | optionsFunction.__configFunction = configFunction
23 |
24 | return optionsFunction
25 | }
26 |
27 | export default createPlugin
28 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/createUtilityPlugin.js:
--------------------------------------------------------------------------------
1 | import transformThemeValue from './transformThemeValue'
2 |
3 | export default function createUtilityPlugin(
4 | themeKey,
5 | utilityVariations = [[themeKey, [themeKey]]],
6 | { filterDefault = false, ...options } = {}
7 | ) {
8 | let transformValue = transformThemeValue(themeKey)
9 | return function ({ matchUtilities, theme }) {
10 | for (let utilityVariation of utilityVariations) {
11 | let group = Array.isArray(utilityVariation[0]) ? utilityVariation : [utilityVariation]
12 |
13 | matchUtilities(
14 | group.reduce((obj, [classPrefix, properties]) => {
15 | return Object.assign(obj, {
16 | [classPrefix]: (value) => {
17 | return properties.reduce((obj, name) => {
18 | if (Array.isArray(name)) {
19 | return Object.assign(obj, { [name[0]]: name[1] })
20 | }
21 | return Object.assign(obj, { [name]: transformValue(value) })
22 | }, {})
23 | },
24 | })
25 | }, {}),
26 | {
27 | ...options,
28 | values: filterDefault
29 | ? Object.fromEntries(
30 | Object.entries(theme(themeKey) ?? {}).filter(([modifier]) => modifier !== 'DEFAULT')
31 | )
32 | : theme(themeKey),
33 | }
34 | )
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/defaults.js:
--------------------------------------------------------------------------------
1 | export function defaults(target, ...sources) {
2 | for (let source of sources) {
3 | for (let k in source) {
4 | if (!target?.hasOwnProperty?.(k)) {
5 | target[k] = source[k]
6 | }
7 | }
8 |
9 | for (let k of Object.getOwnPropertySymbols(source)) {
10 | if (!target?.hasOwnProperty?.(k)) {
11 | target[k] = source[k]
12 | }
13 | }
14 | }
15 |
16 | return target
17 | }
18 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/escapeClassName.js:
--------------------------------------------------------------------------------
1 | import parser from 'postcss-selector-parser'
2 | import escapeCommas from './escapeCommas'
3 |
4 | export default function escapeClassName(className) {
5 | let node = parser.className()
6 | node.value = className
7 | return escapeCommas(node?.raws?.value ?? node.value)
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/escapeCommas.js:
--------------------------------------------------------------------------------
1 | export default function escapeCommas(className) {
2 | return className.replace(/\\,/g, '\\2c ')
3 | }
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/flattenColorPalette.js:
--------------------------------------------------------------------------------
1 | const flattenColorPalette = (colors) =>
2 | Object.assign(
3 | {},
4 | ...Object.entries(colors ?? {}).flatMap(([color, values]) =>
5 | typeof values == 'object'
6 | ? Object.entries(flattenColorPalette(values)).map(([number, hex]) => ({
7 | [color + (number === 'DEFAULT' ? '' : `-${number}`)]: hex,
8 | }))
9 | : [{ [`${color}`]: values }]
10 | )
11 | )
12 |
13 | export default flattenColorPalette
14 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/getAllConfigs.js:
--------------------------------------------------------------------------------
1 | import defaultFullConfig from '../../stubs/config.full.js'
2 | import { flagEnabled } from '../featureFlags'
3 |
4 | export default function getAllConfigs(config) {
5 | const configs = (config?.presets ?? [defaultFullConfig])
6 | .slice()
7 | .reverse()
8 | .flatMap((preset) => getAllConfigs(preset instanceof Function ? preset() : preset))
9 |
10 | const features = {
11 | // Add experimental configs here...
12 | respectDefaultRingColorOpacity: {
13 | theme: {
14 | ringColor: ({ theme }) => ({
15 | DEFAULT: '#3b82f67f',
16 | ...theme('colors'),
17 | }),
18 | },
19 | },
20 |
21 | disableColorOpacityUtilitiesByDefault: {
22 | corePlugins: {
23 | backgroundOpacity: false,
24 | borderOpacity: false,
25 | divideOpacity: false,
26 | placeholderOpacity: false,
27 | ringOpacity: false,
28 | textOpacity: false,
29 | },
30 | },
31 | }
32 |
33 | const experimentals = Object.keys(features)
34 | .filter((feature) => flagEnabled(config, feature))
35 | .map((feature) => features[feature])
36 |
37 | return [config, ...experimentals, ...configs]
38 | }
39 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/hashConfig.js:
--------------------------------------------------------------------------------
1 | import hash from 'object-hash'
2 |
3 | export default function hashConfig(config) {
4 | return hash(config, { ignoreUnknown: true })
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/isKeyframeRule.js:
--------------------------------------------------------------------------------
1 | export default function isKeyframeRule(rule) {
2 | return rule.parent && rule.parent.type === 'atrule' && /keyframes$/.test(rule.parent.name)
3 | }
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/isPlainObject.js:
--------------------------------------------------------------------------------
1 | export default function isPlainObject(value) {
2 | if (Object.prototype.toString.call(value) !== '[object Object]') {
3 | return false
4 | }
5 |
6 | const prototype = Object.getPrototypeOf(value)
7 | return prototype === null || Object.getPrototypeOf(prototype) === null
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/isSyntacticallyValidPropertyValue.js:
--------------------------------------------------------------------------------
1 | let matchingBrackets = new Map([
2 | ['{', '}'],
3 | ['[', ']'],
4 | ['(', ')'],
5 | ])
6 | let inverseMatchingBrackets = new Map(
7 | Array.from(matchingBrackets.entries()).map(([k, v]) => [v, k])
8 | )
9 |
10 | let quotes = new Set(['"', "'", '`'])
11 |
12 | // Arbitrary values must contain balanced brackets (), [] and {}. Escaped
13 | // values don't count, and brackets inside quotes also don't count.
14 | //
15 | // E.g.: w-[this-is]w-[weird-and-invalid]
16 | // E.g.: w-[this-is\\]w-\\[weird-but-valid]
17 | // E.g.: content-['this-is-also-valid]-weirdly-enough']
18 | export default function isSyntacticallyValidPropertyValue(value) {
19 | let stack = []
20 | let inQuotes = false
21 |
22 | for (let i = 0; i < value.length; i++) {
23 | let char = value[i]
24 |
25 | if (char === ':' && !inQuotes && stack.length === 0) {
26 | return false
27 | }
28 |
29 | // Non-escaped quotes allow us to "allow" anything in between
30 | if (quotes.has(char) && value[i - 1] !== '\\') {
31 | inQuotes = !inQuotes
32 | }
33 |
34 | if (inQuotes) continue
35 | if (value[i - 1] === '\\') continue // Escaped
36 |
37 | if (matchingBrackets.has(char)) {
38 | stack.push(char)
39 | } else if (inverseMatchingBrackets.has(char)) {
40 | let inverse = inverseMatchingBrackets.get(char)
41 |
42 | // Nothing to pop from, therefore it is unbalanced
43 | if (stack.length <= 0) {
44 | return false
45 | }
46 |
47 | // Popped value must match the inverse value, otherwise it is unbalanced
48 | if (stack.pop() !== inverse) {
49 | return false
50 | }
51 | }
52 | }
53 |
54 | // If there is still something on the stack, it is also unbalanced
55 | if (stack.length > 0) {
56 | return false
57 | }
58 |
59 | // All good, totally balanced!
60 | return true
61 | }
62 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/log.js:
--------------------------------------------------------------------------------
1 | import colors from 'picocolors'
2 |
3 | let alreadyShown = new Set()
4 |
5 | function log(type, messages, key) {
6 | if (typeof process !== 'undefined' && process.env.JEST_WORKER_ID) return
7 |
8 | if (key && alreadyShown.has(key)) return
9 | if (key) alreadyShown.add(key)
10 |
11 | console.warn('')
12 | messages.forEach((message) => console.warn(type, '-', message))
13 | }
14 |
15 | export function dim(input) {
16 | return colors.dim(input)
17 | }
18 |
19 | export default {
20 | info(key, messages) {
21 | log(colors.bold(colors.cyan('info')), ...(Array.isArray(key) ? [key] : [messages, key]))
22 | },
23 | warn(key, messages) {
24 | log(colors.bold(colors.yellow('warn')), ...(Array.isArray(key) ? [key] : [messages, key]))
25 | },
26 | risk(key, messages) {
27 | log(colors.bold(colors.magenta('risk')), ...(Array.isArray(key) ? [key] : [messages, key]))
28 | },
29 | }
30 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/nameClass.js:
--------------------------------------------------------------------------------
1 | import escapeClassName from './escapeClassName'
2 | import escapeCommas from './escapeCommas'
3 |
4 | export function asClass(name) {
5 | return escapeCommas(`.${escapeClassName(name)}`)
6 | }
7 |
8 | export default function nameClass(classPrefix, key) {
9 | return asClass(formatClass(classPrefix, key))
10 | }
11 |
12 | export function formatClass(classPrefix, key) {
13 | if (key === 'DEFAULT') {
14 | return classPrefix
15 | }
16 |
17 | if (key === '-' || key === '-DEFAULT') {
18 | return `-${classPrefix}`
19 | }
20 |
21 | if (key.startsWith('-')) {
22 | return `-${classPrefix}${key}`
23 | }
24 |
25 | if (key.startsWith('/')) {
26 | return `${classPrefix}${key}`
27 | }
28 |
29 | return `${classPrefix}-${key}`
30 | }
31 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/negateValue.js:
--------------------------------------------------------------------------------
1 | export default function negateValue(value) {
2 | value = `${value}`
3 |
4 | if (value === '0') {
5 | return '0'
6 | }
7 |
8 | // Flip sign of numbers
9 | if (/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(value)) {
10 | return value.replace(/^[+-]?/, (sign) => (sign === '-' ? '' : '-'))
11 | }
12 |
13 | // What functions we support negating numeric values for
14 | // var() isn't inherently a numeric function but we support it anyway
15 | // The trigonometric functions are omitted because you'll need to use calc(…) with them _anyway_
16 | // to produce generally useful results and that will be covered already
17 | let numericFunctions = ['var', 'calc', 'min', 'max', 'clamp']
18 |
19 | for (const fn of numericFunctions) {
20 | if (value.includes(`${fn}(`)) {
21 | return `calc(${value} * -1)`
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/parseDependency.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | /**
4 | * @typedef {{type: 'dependency', file: string} | {type: 'dir-dependency', dir: string, glob: string}} Dependency
5 | */
6 |
7 | /**
8 | *
9 | * @param {import('../lib/content.js').ContentPath} contentPath
10 | * @returns {Dependency[]}
11 | */
12 | export default function parseDependency(contentPath) {
13 | if (contentPath.ignore) {
14 | return []
15 | }
16 |
17 | if (!contentPath.glob) {
18 | return [
19 | {
20 | type: 'dependency',
21 | file: contentPath.base,
22 | },
23 | ]
24 | }
25 |
26 | if (process.env.ROLLUP_WATCH === 'true') {
27 | // rollup-plugin-postcss does not support dir-dependency messages
28 | // but directories can be watched in the same way as files
29 | return [
30 | {
31 | type: 'dependency',
32 | file: contentPath.base,
33 | },
34 | ]
35 | }
36 |
37 | return [
38 | {
39 | type: 'dir-dependency',
40 | dir: contentPath.base,
41 | glob: contentPath.glob,
42 | },
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/parseGlob.js:
--------------------------------------------------------------------------------
1 | import globParent from 'glob-parent'
2 |
3 | // Based on `glob-base`
4 | // https://github.com/micromatch/glob-base/blob/master/index.js
5 | export function parseGlob(pattern) {
6 | let glob = pattern
7 | let base = globParent(pattern)
8 |
9 | if (base !== '.') {
10 | glob = pattern.substr(base.length)
11 | if (glob.charAt(0) === '/') {
12 | glob = glob.substr(1)
13 | }
14 | }
15 |
16 | if (glob.substr(0, 2) === './') {
17 | glob = glob.substr(2)
18 | }
19 | if (glob.charAt(0) === '/') {
20 | glob = glob.substr(1)
21 | }
22 |
23 | return { base, glob }
24 | }
25 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/parseObjectStyles.js:
--------------------------------------------------------------------------------
1 | import postcss from 'postcss'
2 | import postcssNested from 'postcss-nested'
3 | import postcssJs from 'postcss-js'
4 |
5 | export default function parseObjectStyles(styles) {
6 | if (!Array.isArray(styles)) {
7 | return parseObjectStyles([styles])
8 | }
9 |
10 | return styles.flatMap((style) => {
11 | return postcss([
12 | postcssNested({
13 | bubble: ['screen'],
14 | }),
15 | ]).process(style, {
16 | parser: postcssJs,
17 | }).root.nodes
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/prefixSelector.js:
--------------------------------------------------------------------------------
1 | import parser from 'postcss-selector-parser'
2 |
3 | /**
4 | * @template {string | import('postcss-selector-parser').Root} T
5 | *
6 | * Prefix all classes in the selector with the given prefix
7 | *
8 | * It can take either a string or a selector AST and will return the same type
9 | *
10 | * @param {string} prefix
11 | * @param {T} selector
12 | * @param {boolean} prependNegative
13 | * @returns {T}
14 | */
15 | export default function (prefix, selector, prependNegative = false) {
16 | if (prefix === '') {
17 | return selector
18 | }
19 |
20 | /** @type {import('postcss-selector-parser').Root} */
21 | let ast = typeof selector === 'string' ? parser().astSync(selector) : selector
22 |
23 | ast.walkClasses((classSelector) => {
24 | let baseClass = classSelector.value
25 | let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-')
26 |
27 | classSelector.value = shouldPlaceNegativeBeforePrefix
28 | ? `-${prefix}${baseClass.slice(1)}`
29 | : `${prefix}${baseClass}`
30 | })
31 |
32 | return typeof selector === 'string' ? ast.toString() : ast
33 | }
34 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/removeAlphaVariables.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This function removes any uses of CSS variables used as an alpha channel
3 | *
4 | * This is required for selectors like `:visited` which do not allow
5 | * changes in opacity or external control using CSS variables.
6 | *
7 | * @param {import('postcss').Container} container
8 | * @param {string[]} toRemove
9 | */
10 | export function removeAlphaVariables(container, toRemove) {
11 | container.walkDecls((decl) => {
12 | if (toRemove.includes(decl.prop)) {
13 | decl.remove()
14 |
15 | return
16 | }
17 |
18 | for (let varName of toRemove) {
19 | if (decl.value.includes(`/ var(${varName})`)) {
20 | decl.value = decl.value.replace(`/ var(${varName})`, '')
21 | }
22 | }
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/resolveConfigPath.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 |
4 | const defaultConfigFiles = [
5 | './tailwind.config.js',
6 | './tailwind.config.cjs',
7 | './tailwind.config.mjs',
8 | './tailwind.config.ts',
9 | ]
10 |
11 | function isObject(value) {
12 | return typeof value === 'object' && value !== null
13 | }
14 |
15 | function isEmpty(obj) {
16 | return Object.keys(obj).length === 0
17 | }
18 |
19 | function isString(value) {
20 | return typeof value === 'string' || value instanceof String
21 | }
22 |
23 | export default function resolveConfigPath(pathOrConfig) {
24 | // require('tailwindcss')({ theme: ..., variants: ... })
25 | if (isObject(pathOrConfig) && pathOrConfig.config === undefined && !isEmpty(pathOrConfig)) {
26 | return null
27 | }
28 |
29 | // require('tailwindcss')({ config: 'custom-config.js' })
30 | if (
31 | isObject(pathOrConfig) &&
32 | pathOrConfig.config !== undefined &&
33 | isString(pathOrConfig.config)
34 | ) {
35 | return path.resolve(pathOrConfig.config)
36 | }
37 |
38 | // require('tailwindcss')({ config: { theme: ..., variants: ... } })
39 | if (
40 | isObject(pathOrConfig) &&
41 | pathOrConfig.config !== undefined &&
42 | isObject(pathOrConfig.config)
43 | ) {
44 | return null
45 | }
46 |
47 | // require('tailwindcss')('custom-config.js')
48 | if (isString(pathOrConfig)) {
49 | return path.resolve(pathOrConfig)
50 | }
51 |
52 | // require('tailwindcss')
53 | return resolveDefaultConfigPath()
54 | }
55 |
56 | export function resolveDefaultConfigPath() {
57 | for (const configFile of defaultConfigFiles) {
58 | try {
59 | const configPath = path.resolve(configFile)
60 | fs.accessSync(configPath)
61 | return configPath
62 | } catch (err) {}
63 | }
64 |
65 | return null
66 | }
67 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/responsive.js:
--------------------------------------------------------------------------------
1 | import postcss from 'postcss'
2 | import cloneNodes from './cloneNodes'
3 |
4 | export default function responsive(rules) {
5 | return postcss
6 | .atRule({
7 | name: 'responsive',
8 | })
9 | .append(cloneNodes(Array.isArray(rules) ? rules : [rules]))
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/splitAtTopLevelOnly.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This splits a string on a top-level character.
3 | *
4 | * Regex doesn't support recursion (at least not the JS-flavored version).
5 | * So we have to use a tiny state machine to keep track of paren placement.
6 | *
7 | * Expected behavior using commas:
8 | * var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0)
9 | * ─┬─ ┬ ┬ ┬
10 | * x x x ╰──────── Split because top-level
11 | * ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens
12 | *
13 | * @param {string} input
14 | * @param {string} separator
15 | */
16 | export function splitAtTopLevelOnly(input, separator) {
17 | let stack = []
18 | let parts = []
19 | let lastPos = 0
20 | let isEscaped = false
21 |
22 | for (let idx = 0; idx < input.length; idx++) {
23 | let char = input[idx]
24 |
25 | if (stack.length === 0 && char === separator[0] && !isEscaped) {
26 | if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) {
27 | parts.push(input.slice(lastPos, idx))
28 | lastPos = idx + separator.length
29 | }
30 | }
31 |
32 | if (isEscaped) {
33 | isEscaped = false
34 | } else if (char === '\\') {
35 | isEscaped = true
36 | }
37 |
38 | if (char === '(' || char === '[' || char === '{') {
39 | stack.push(char)
40 | } else if (
41 | (char === ')' && stack[stack.length - 1] === '(') ||
42 | (char === ']' && stack[stack.length - 1] === '[') ||
43 | (char === '}' && stack[stack.length - 1] === '{')
44 | ) {
45 | stack.pop()
46 | }
47 | }
48 |
49 | parts.push(input.slice(lastPos))
50 |
51 | return parts
52 | }
53 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/tap.js:
--------------------------------------------------------------------------------
1 | export function tap(value, mutator) {
2 | mutator(value)
3 | return value
4 | }
5 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/toColorValue.js:
--------------------------------------------------------------------------------
1 | export default function toColorValue(maybeFunction) {
2 | return typeof maybeFunction === 'function' ? maybeFunction({}) : maybeFunction
3 | }
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/toPath.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Parse a path string into an array of path segments.
3 | *
4 | * Square bracket notation `a[b]` may be used to "escape" dots that would otherwise be interpreted as path separators.
5 | *
6 | * Example:
7 | * a -> ['a']
8 | * a.b.c -> ['a', 'b', 'c']
9 | * a[b].c -> ['a', 'b', 'c']
10 | * a[b.c].e.f -> ['a', 'b.c', 'e', 'f']
11 | * a[b][c][d] -> ['a', 'b', 'c', 'd']
12 | *
13 | * @param {string|string[]} path
14 | **/
15 | export function toPath(path) {
16 | if (Array.isArray(path)) return path
17 |
18 | let openBrackets = path.split('[').length - 1
19 | let closedBrackets = path.split(']').length - 1
20 |
21 | if (openBrackets !== closedBrackets) {
22 | throw new Error(`Path is invalid. Has unbalanced brackets: ${path}`)
23 | }
24 |
25 | return path.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean)
26 | }
27 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/validateConfig.js:
--------------------------------------------------------------------------------
1 | import log from './log'
2 |
3 | export function validateConfig(config) {
4 | if (config.content.files.length === 0) {
5 | log.warn('content-problems', [
6 | 'The `content` option in your Tailwind CSS configuration is missing or empty.',
7 | 'Configure your content sources or your generated CSS will be missing styles.',
8 | 'https://tailwindcss.com/docs/content-configuration',
9 | ])
10 | }
11 |
12 | // Warn if the line-clamp plugin is installed
13 | try {
14 | let plugin = require('@tailwindcss/line-clamp')
15 | if (config.plugins.includes(plugin)) {
16 | log.warn('line-clamp-in-core', [
17 | 'As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.',
18 | 'Remove it from the `plugins` array in your configuration to eliminate this warning.',
19 | ])
20 |
21 | config.plugins = config.plugins.filter((p) => p !== plugin)
22 | }
23 | } catch {}
24 |
25 | return config
26 | }
27 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/validateFormalSyntax.js:
--------------------------------------------------------------------------------
1 | import { length, percentage } from './dataTypes'
2 | import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'
3 |
4 | /**
5 | *
6 | * https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#formal_syntax
7 | *
8 | * background-size =
9 | * #
10 | *
11 | * =
12 | * [ | auto ]{1,2} |
13 | * cover |
14 | * contain
15 | *
16 | * =
17 | * |
18 | *
19 | *
20 | * @param {string} value
21 | */
22 | export function backgroundSize(value) {
23 | let keywordValues = ['cover', 'contain']
24 | // the type will probably be a css function
25 | // so we have to use `splitAtTopLevelOnly`
26 | return splitAtTopLevelOnly(value, ',').every((part) => {
27 | let sizes = splitAtTopLevelOnly(part, '_').filter(Boolean)
28 | if (sizes.length === 1 && keywordValues.includes(sizes[0])) return true
29 |
30 | if (sizes.length !== 1 && sizes.length !== 2) return false
31 |
32 | return sizes.every((size) => length(size) || percentage(size) || size === 'auto')
33 | })
34 | }
35 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/util/withAlphaVariable.js:
--------------------------------------------------------------------------------
1 | import { parseColor, formatColor } from './color'
2 |
3 | export function withAlphaValue(color, alphaValue, defaultValue) {
4 | if (typeof color === 'function') {
5 | return color({ opacityValue: alphaValue })
6 | }
7 |
8 | let parsed = parseColor(color, { loose: true })
9 |
10 | if (parsed === null) {
11 | return defaultValue
12 | }
13 |
14 | return formatColor({ ...parsed, alpha: alphaValue })
15 | }
16 |
17 | export default function withAlphaVariable({ color, property, variable }) {
18 | let properties = [].concat(property)
19 | if (typeof color === 'function') {
20 | return {
21 | [variable]: '1',
22 | ...Object.fromEntries(
23 | properties.map((p) => {
24 | return [p, color({ opacityVariable: variable, opacityValue: `var(${variable})` })]
25 | })
26 | ),
27 | }
28 | }
29 |
30 | const parsed = parseColor(color)
31 |
32 | if (parsed === null) {
33 | return Object.fromEntries(properties.map((p) => [p, color]))
34 | }
35 |
36 | if (parsed.alpha !== undefined) {
37 | // Has an alpha value, return color as-is
38 | return Object.fromEntries(properties.map((p) => [p, color]))
39 | }
40 |
41 | return {
42 | [variable]: '1',
43 | ...Object.fromEntries(
44 | properties.map((p) => {
45 | return [p, formatColor({ ...parsed, alpha: `var(${variable})` })]
46 | })
47 | ),
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) Bogdan Chadkin
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/README.md:
--------------------------------------------------------------------------------
1 | # postcss-value-parser (forked + inlined)
2 |
3 | This is a customized version of of [PostCSS Value Parser](https://github.com/TrySound/postcss-value-parser) to fix some bugs around parsing CSS functions.
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/index.js:
--------------------------------------------------------------------------------
1 | var parse = require('./parse')
2 | var walk = require('./walk')
3 | var stringify = require('./stringify')
4 |
5 | function ValueParser(value) {
6 | if (this instanceof ValueParser) {
7 | this.nodes = parse(value)
8 | return this
9 | }
10 | return new ValueParser(value)
11 | }
12 |
13 | ValueParser.prototype.toString = function () {
14 | return Array.isArray(this.nodes) ? stringify(this.nodes) : ''
15 | }
16 |
17 | ValueParser.prototype.walk = function (cb, bubble) {
18 | walk(this.nodes, cb, bubble)
19 | return this
20 | }
21 |
22 | ValueParser.unit = require('./unit')
23 |
24 | ValueParser.walk = walk
25 |
26 | ValueParser.stringify = stringify
27 |
28 | module.exports = ValueParser
29 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/stringify.js:
--------------------------------------------------------------------------------
1 | function stringifyNode(node, custom) {
2 | var type = node.type
3 | var value = node.value
4 | var buf
5 | var customResult
6 |
7 | if (custom && (customResult = custom(node)) !== undefined) {
8 | return customResult
9 | } else if (type === 'word' || type === 'space') {
10 | return value
11 | } else if (type === 'string') {
12 | buf = node.quote || ''
13 | return buf + value + (node.unclosed ? '' : buf)
14 | } else if (type === 'comment') {
15 | return '/*' + value + (node.unclosed ? '' : '*/')
16 | } else if (type === 'div') {
17 | return (node.before || '') + value + (node.after || '')
18 | } else if (Array.isArray(node.nodes)) {
19 | buf = stringify(node.nodes, custom)
20 | if (type !== 'function') {
21 | return buf
22 | }
23 | return value + '(' + (node.before || '') + buf + (node.after || '') + (node.unclosed ? '' : ')')
24 | }
25 | return value
26 | }
27 |
28 | function stringify(nodes, custom) {
29 | var result, i
30 |
31 | if (Array.isArray(nodes)) {
32 | result = ''
33 | for (i = nodes.length - 1; ~i; i -= 1) {
34 | result = stringifyNode(nodes[i], custom) + result
35 | }
36 | return result
37 | }
38 | return stringifyNode(nodes, custom)
39 | }
40 |
41 | module.exports = stringify
42 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/walk.js:
--------------------------------------------------------------------------------
1 | module.exports = function walk(nodes, cb, bubble) {
2 | var i, max, node, result
3 |
4 | for (i = 0, max = nodes.length; i < max; i += 1) {
5 | node = nodes[i]
6 | if (!bubble) {
7 | result = cb(node, i, nodes)
8 | }
9 |
10 | if (result !== false && node.type === 'function' && Array.isArray(node.nodes)) {
11 | walk(node.nodes, cb, bubble)
12 | }
13 |
14 | if (bubble) {
15 | cb(node, i, nodes)
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/.npmignore:
--------------------------------------------------------------------------------
1 | !*
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "semi": false,
4 | "singleQuote": true,
5 | "trailingComma": "es5"
6 | }
7 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/config.simple.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: [],
3 | theme: {
4 | extend: {},
5 | },
6 | plugins: [],
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = __CONFIG__
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default __CONFIG__
3 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/stubs/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'tailwindcss'
2 |
3 | export default __CONFIG__ satisfies Config
4 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 |
3 | @tailwind components;
4 |
5 | @tailwind utilities;
6 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/types/generated/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/tooling/tailwind-config/node_modules/tailwindcss/types/generated/.gitkeep
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import type { PluginCreator } from 'postcss'
2 | import type { Config } from 'tailwindcss/types/config'
3 |
4 | declare const plugin: PluginCreator
5 |
6 | declare type _Config = Config
7 | declare namespace plugin {
8 | export type { _Config as Config }
9 | }
10 |
11 | export = plugin
12 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/utilities.css:
--------------------------------------------------------------------------------
1 | @tailwind utilities;
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/node_modules/tailwindcss/variants.css:
--------------------------------------------------------------------------------
1 | @tailwind variants;
2 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@stackwise-tooling/tailwind-config",
3 | "version": "0.1.0",
4 | "private": true,
5 | "main": "index.ts",
6 | "license": "MIT",
7 | "files": [
8 | "index.ts"
9 | ],
10 | "scripts": {
11 | "clean": "rm -rf .turbo node_modules",
12 | "lint": "eslint .",
13 | "format": "prettier --check . --ignore-path ../../.gitignore",
14 | "typecheck": "tsc --noEmit"
15 | },
16 | "dependencies": {
17 | "autoprefixer": "^10.4.16",
18 | "tailwindcss": "3.3.6"
19 | },
20 | "devDependencies": {
21 | "@stackwise-tooling/eslint-config": "*",
22 | "@stackwise-tooling/prettier-config": "*",
23 | "@stackwise-tooling/tsconfig": "*",
24 | "eslint": "^8.55.0",
25 | "prettier": "^3.1.0",
26 | "typescript": "^5.3.2"
27 | },
28 | "eslintConfig": {
29 | "root": true,
30 | "extends": [
31 | "@stackwise-tooling/eslint-config/base"
32 | ]
33 | },
34 | "prettier": "@stackwise-tooling/prettier-config"
35 | }
36 |
--------------------------------------------------------------------------------
/tooling/tailwind-config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@stackwise-tooling/tsconfig/base.json",
3 | "compilerOptions": {
4 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
5 | },
6 | "include": ["."],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/tsconfig/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "strict": false,
16 | "strictNullChecks": true,
17 | "noImplicitAny": false,
18 | "noImplicitThis": false,
19 | "alwaysStrict": false,
20 | "plugins": [
21 | {
22 | "name": "next"
23 | }
24 | ],
25 | "paths": {
26 | "@/*": ["./*"]
27 | }
28 | },
29 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "app/stacks/[slug]"],
30 | "exclude": ["node_modules", "scripts"]
31 | }
32 |
--------------------------------------------------------------------------------
/tooling/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@stackwise-tooling/tsconfig",
3 | "private": true,
4 | "version": "0.1.0",
5 | "files": [
6 | "base.json"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@stackwise-tooling/tsconfig/base.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./*"]
7 | },
8 | "plugins": [
9 | {
10 | "name": "next"
11 | }
12 | ],
13 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
14 | },
15 | "include": [".", ".next/types/**/*.ts"],
16 | "exclude": ["node_modules"]
17 | }
18 |
--------------------------------------------------------------------------------