Compare commits
64 Commits
@now/next@
...
@now/next@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6f71c8d7b | ||
|
|
d90892dc9c | ||
|
|
60d2f8b96c | ||
|
|
2488adf80d | ||
|
|
9deb5b31d2 | ||
|
|
ae55823c3c | ||
|
|
d3395553fe | ||
|
|
e742dd3a48 | ||
|
|
4f0f44e746 | ||
|
|
0da98a7f5d | ||
|
|
685989ae57 | ||
|
|
6bc121e7b1 | ||
|
|
56d3fed954 | ||
|
|
40bbff9bee | ||
|
|
66ab011f4a | ||
|
|
f4237d3db0 | ||
|
|
6f9a083dba | ||
|
|
688fcc6a5b | ||
|
|
847102cf62 | ||
|
|
25d5b9c9cf | ||
|
|
271bab786e | ||
|
|
028e023aba | ||
|
|
39719eed20 | ||
|
|
438339258d | ||
|
|
be445c987c | ||
|
|
93fef7885b | ||
|
|
899c9962ad | ||
|
|
2b601d2424 | ||
|
|
3e36b05434 | ||
|
|
59c9665c3f | ||
|
|
901137c7f6 | ||
|
|
e594e7bbbb | ||
|
|
a477b1c22e | ||
|
|
22ac20d838 | ||
|
|
3794234d7a | ||
|
|
92a40db048 | ||
|
|
502aad7c2b | ||
|
|
b49afb61a6 | ||
|
|
d380902ad3 | ||
|
|
ffaed62094 | ||
|
|
b0adeb68fe | ||
|
|
2372832654 | ||
|
|
e6a9586b7e | ||
|
|
9687415eed | ||
|
|
49b375ed6a | ||
|
|
906dea096e | ||
|
|
3225a83084 | ||
|
|
87794cfcc5 | ||
|
|
79ad0ce0c4 | ||
|
|
fda5987465 | ||
|
|
5cfdd5a6b2 | ||
|
|
bd6e0f9f93 | ||
|
|
aa8d002309 | ||
|
|
42ce9aca86 | ||
|
|
156f596189 | ||
|
|
8acfd5bf71 | ||
|
|
76c99ebb28 | ||
|
|
5fb119b99c | ||
|
|
99b766d9cb | ||
|
|
c207cf9b40 | ||
|
|
dd00ac4621 | ||
|
|
3d18a067a0 | ||
|
|
c48571a799 | ||
|
|
6eeb6983d9 |
2
.gitignore
vendored
@@ -19,3 +19,5 @@ packages/now-cli/test/dev/fixtures/08-hugo/hugo
|
||||
packages/now-cli/test/dev/fixtures/**/dist
|
||||
packages/now-cli/test/dev/fixtures/**/public
|
||||
packages/now-cli/test/fixtures/integration
|
||||
test/lib/deployment/failed-page.txt
|
||||
.DS_Store
|
||||
|
||||
455
packages/frameworks/frameworks.json
Normal file
@@ -0,0 +1,455 @@
|
||||
[
|
||||
{
|
||||
"name": "Next.js",
|
||||
"slug": "nextjs",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/next.svg",
|
||||
"tagline": "Next.js makes you productive with React instantly — whether you want to build static or dynamic sites. ",
|
||||
"website": "https://nextjs.org",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"next\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Gatsby",
|
||||
"slug": "gatsby",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/gatsby.svg",
|
||||
"tagline": "Gatsby helps developers build blazing fast websites and apps with React.",
|
||||
"website": "https://gatsbyjs.org",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"gatsby\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Hexo",
|
||||
"slug": "hexo",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/hexo.svg",
|
||||
"tagline": "Hexo is a fast, simple & powerful blog framework powered by Node.js.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"hexo\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Eleventy",
|
||||
"slug": "eleventy",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/eleventy.svg",
|
||||
"tagline": "11ty is a simpler static site generator written in JavaScript, created to be an alternative to Jekyll.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@11ty\\/eleventy\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Docusaurus",
|
||||
"slug": "docusaurus",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/docusaurus.svg",
|
||||
"tagline": "Docusaurus makes it easy to maintain Open Source documentation websites.",
|
||||
"detectors": {
|
||||
"some": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"docusaurus\":\\s*\".+?\"[^}]*}"
|
||||
},
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@docusaurus\\/core\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Preact",
|
||||
"slug": "preact",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/preact.svg",
|
||||
"tagline": "Preact is a fast 3kB alternative to React with the same modern API.",
|
||||
"website": "https://preactjs.com",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"preact-cli\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Ember",
|
||||
"slug": "ember",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/ember.svg",
|
||||
"tagline": "Ember.js helps webapp developers be more productive out of the box.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"ember-cli\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Vue.js",
|
||||
"slug": "vue",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/vue.svg",
|
||||
"tagline": "Vue.js is a versatile JavaScript framework that is as approachable as it is performant.",
|
||||
"website": "https://vuejs.org",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@vue\\/cli-service\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Scully",
|
||||
"slug": "scully",
|
||||
"tagline": "Scully is a static site generator for Angular.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@scullyio\\/init\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Angular",
|
||||
"slug": "angular",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/angular.svg",
|
||||
"tagline": "Angular is a TypeScript-based cross-platform framework from Google.",
|
||||
"website": "https://angular.io",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@angular\\/cli\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Polymer",
|
||||
"slug": "polymer",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/polymer.svg",
|
||||
"tagline": "Polymer is an open-source webapps library from Google, for building using Web Components.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"polymer-cli\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Svelte",
|
||||
"slug": "svelte",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/svelte.svg",
|
||||
"tagline": "Svelte lets you write high performance reactive apps with significantly less boilerplate. ",
|
||||
"website": "https://svelte.dev",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"sirv-cli\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Create-React-App",
|
||||
"slug": "create-react-app",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/react.svg",
|
||||
"tagline": "Create React App allows you to get going with React in no time.",
|
||||
"website": "https://create-react-app.dev",
|
||||
"detectors": {
|
||||
"some": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"react-scripts\":\\s*\".+?\"[^}]*}"
|
||||
},
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"react-dev-utils\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Gridsome",
|
||||
"slug": "gridsome",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/gridsome.svg",
|
||||
"tagline": "Gridsome is a Vue.js-powered framework for building websites & apps that are fast by default.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"gridsome\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "UmiJS",
|
||||
"slug": "umijs",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/umi.svg",
|
||||
"tagline": "UmiJS is an extensible enterprise-level React application framework.",
|
||||
"website": "https://umijs.org",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"umi\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Sapper",
|
||||
"slug": "sapper",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/svelte.svg",
|
||||
"tagline": "Sapper is a framework for building high-performance universal web apps with Svelte.",
|
||||
"website": "https://sapper.svelte.dev",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"sapper\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Saber",
|
||||
"slug": "saber",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/saber.svg",
|
||||
"tagline": "Saber is a framework for building static sites in Vue.js that supports data from any source.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"saber\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Stencil",
|
||||
"slug": "stencil",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/stencil.svg",
|
||||
"tagline": "Stencil is a powerful toolchain for building Progressive Web Apps and Design Systems.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@stencil\\/core\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Nuxt.js",
|
||||
"slug": "nuxtjs",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/nuxt.svg",
|
||||
"tagline": "Nuxt.js is the web comprehensive framework that lets you dream big with Vue.js.",
|
||||
"website": "https://nuxtjs.org",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"nuxt\":\\s*\".+?\"[^}]*}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Hugo",
|
||||
"slug": "hugo",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/hugo.svg",
|
||||
"tagline": "Hugo is the world’s fastest framework for building websites, written in Go.",
|
||||
"website": "https://gohugo.io",
|
||||
"detectors": {
|
||||
"some": [
|
||||
{
|
||||
"file": "config.yaml"
|
||||
},
|
||||
{
|
||||
"file": "config.toml"
|
||||
},
|
||||
{
|
||||
"file": "config.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Jekyll",
|
||||
"slug": "jekyll",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/jekyll.svg",
|
||||
"tagline": "Jekyll makes it super easy to transform your plain text into static websites and blogs.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "_config.yml"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Brunch",
|
||||
"slug": "brunch",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/brunch.svg",
|
||||
"tagline": "Brunch is a fast and simple webapp build tool with seamless incremental compilation for rapid development.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "brunch-config.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Middleman",
|
||||
"slug": "middleman",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/middleman.svg",
|
||||
"tagline": "Middleman is a static site generator that uses all the shortcuts and tools in modern web development.",
|
||||
"detectors": {
|
||||
"every": [
|
||||
{
|
||||
"file": "config.rb"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Vanilla",
|
||||
"slug": "vanilla",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/vanilla.svg",
|
||||
"tagline": "Love the original way of making websites?"
|
||||
},
|
||||
{
|
||||
"name": "Storybook",
|
||||
"slug": "storybook",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/storybook.svg",
|
||||
"tagline": "Storybook is an open source tool for developing UI components in isolation for React, Vue, and Angular.",
|
||||
"website": "https://storybook.js.org"
|
||||
},
|
||||
{
|
||||
"name": "Docz",
|
||||
"slug": "docz",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/docz.svg",
|
||||
"tagline": "Docz makes it easy to write and publish beautiful interactive documentation for your code.",
|
||||
"website": "https://docz.site"
|
||||
},
|
||||
{
|
||||
"name": "mdx-deck",
|
||||
"slug": "mdx-deck",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/mdx-deck.svg",
|
||||
"tagline": "MDX Deck allows you to swiftly create React MDX-based presentation decks.",
|
||||
"website": "https://github.com/jxnblk/mdx-deck"
|
||||
},
|
||||
{
|
||||
"name": "Aurelia",
|
||||
"slug": "aurelia",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/aurelia.svg",
|
||||
"tagline": "Aurelia is an all-in-one framework for building web, desktop, and mobile applications."
|
||||
},
|
||||
{
|
||||
"name": "VuePress",
|
||||
"slug": "vuepress",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/vuepress.png",
|
||||
"tagline": "VuePress is the performant way to create static sites with Vue.js."
|
||||
},
|
||||
{
|
||||
"name": "Charge.js",
|
||||
"slug": "charge",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/chargejs.svg",
|
||||
"tagline": "Charge is an opinionated, zero-config static site generator written in JavaScript."
|
||||
},
|
||||
{
|
||||
"name": "Riot.js",
|
||||
"slug": "riot",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/riot.svg",
|
||||
"tagline": "Riot.js lets you build user interfaces with custom tags using simple and enjoyable syntax."
|
||||
},
|
||||
{
|
||||
"name": "Marko.js",
|
||||
"slug": "marko",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/marko.png",
|
||||
"tagline": "Marko is a super fast UI library that makes building web apps fun."
|
||||
},
|
||||
{
|
||||
"name": "Mithril.js",
|
||||
"slug": "mithril",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/mithriljs.svg",
|
||||
"tagline": "Mithril is a lightweight modern web framework for that makes it easy to build SPAs."
|
||||
},
|
||||
{
|
||||
"name": "Metalsmith",
|
||||
"slug": "metalsmith",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/metalsmith.png",
|
||||
"tagline": "Metalsmith is an extremely simple, extendable static site generator."
|
||||
},
|
||||
{
|
||||
"name": "HyperApp",
|
||||
"slug": "hyperapp",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/hyperapp.svg",
|
||||
"tagline": "HyperApp is a low-footprint framework for building web interfaces without a learning curve."
|
||||
},
|
||||
{
|
||||
"name": "Zola",
|
||||
"slug": "zola",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/zola.svg",
|
||||
"tagline": "Zola is a one-stop static site engine for all of your static needs."
|
||||
},
|
||||
{
|
||||
"name": "Pelican",
|
||||
"slug": "pelican",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/pelican.png",
|
||||
"tagline": "Pelican is a versatile static site generator, written in Python."
|
||||
},
|
||||
{
|
||||
"name": "MkDocs",
|
||||
"slug": "mkdocs",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/mkdocs.svg",
|
||||
"tagline": "MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation."
|
||||
},
|
||||
{
|
||||
"name": "Assemble",
|
||||
"slug": "assemble",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/assemble.svg",
|
||||
"tagline": "A static site generator for Grunt.js and Yeoman, Assemble makes it dead simple to build modular sites and blogs."
|
||||
},
|
||||
{
|
||||
"name": "Ionic React",
|
||||
"slug": "ionic-react",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/ionic-react.svg",
|
||||
"tagline": "Ionic React allows you to build mobile PWAs with React and the Ionic Framework."
|
||||
},
|
||||
{
|
||||
"name": "Foundation",
|
||||
"slug": "foundation",
|
||||
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/foundation.svg",
|
||||
"tagline": "Foundation is the most advanced responsive front-end framework in the world."
|
||||
}
|
||||
]
|
||||
16
packages/frameworks/index.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export interface FrameworkDetectionItem {
|
||||
file: string;
|
||||
matchContent?: string;
|
||||
}
|
||||
|
||||
export interface Framework {
|
||||
name: string;
|
||||
slug: string;
|
||||
logo: string;
|
||||
tagline: string;
|
||||
website: string;
|
||||
detectors?: {
|
||||
every?: FrameworkDetectionItem[];
|
||||
some?: FrameworkDetectionItem[];
|
||||
};
|
||||
}
|
||||
1
packages/frameworks/logos/angular.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 1L3 8.636l3.203 28.313L24 47l17.797-10.051L45 8.636 24 1z" fill="#DA0B36"/><path d="M24 1v5.106-.023V47l17.797-10.051L45 8.636 24 1z" fill="#C10933"/><path d="M24.022 6L11 36h4.855l2.618-6.713h11.054L32.145 36H37L24.022 6zm3.804 19.15H20.22l3.803-9.403 3.804 9.402z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 374 B |
4
packages/frameworks/logos/assemble.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 52 48">
|
||||
<path fill="#111" stroke="#190000" stroke-linecap="square" stroke-miterlimit="10" stroke-width=".5" d="M22.32 4.48h7.5l16.5 38.97h-8.55l-3.53-8.9H17.71l-3.63 8.75h-8.4L22.33 4.48h0zm3.53 9.68c.05.15 5.45 13.13 5.45 13.13H20.55s5.27-13.24 5.3-13.13z"/>
|
||||
<path fill="#fff" stroke="#190000" stroke-linecap="square" stroke-miterlimit="10" stroke-width=".5" d="M25.77 14l5.44 13.13H20.47S25.73 13.9 25.77 14z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 490 B |
61
packages/frameworks/logos/aurelia.svg
Normal file
@@ -0,0 +1,61 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<path fill="url(#paint0_linear)" d="M31.48 8.75l-4.44 2.99-4.58-6.9 4.44-2.99 4.58 6.9z"/>
|
||||
<path fill="url(#paint1_linear)" d="M35.09 29.48l7.58 11.45L33.64 47l-7.6-11.45-1.31-2 9.03-6.06 1.33 2z"/>
|
||||
<path fill="url(#paint2_linear)" d="M23.7 37.13l1.67 2.52-6.87 4.62-3-4.52 1.5-1 5.38-3.62 1.32 2z"/>
|
||||
<path fill="url(#paint3_linear)" d="M38.84 24.07l1.93-1.3 3 4.52-4.44 2.99-1.67-2.52 2.5-1.7-1.32-1.99zm-1.18 3.69l-1.33-2 2.51-1.69 1.33 2-2.51 1.69z"/>
|
||||
<path fill="url(#paint4_linear)" d="M7.7 24.72l-1.5 1.01-4.57-6.9 6.88-4.62 3.2 4.84-5.37 3.6 5.38-3.6 1.36 2.06-5.37 3.61z"/>
|
||||
<path fill="url(#paint5_linear)" d="M24.47 13.46l-9.04 6.07-1.37-2.06L6.55 6.13 15.58.06 23.1 11.4l1.37 2.06z"/>
|
||||
<path fill="url(#paint6_linear)" d="M29.55 10.05l-2.51 1.69-1.37-2.07-3.2-4.83 4.43-2.99 4.58 6.9-1.93 1.3z"/>
|
||||
<path fill="#714896" d="M18.33 40.74l-1.33-2 5.38-3.6 1.32 1.99-5.37 3.61z"/>
|
||||
<path fill="#6F4795" d="M37.66 27.76l-1.33-2 2.51-1.69 1.33 2-2.51 1.69z"/>
|
||||
<path fill="#88519F" d="M7.7 24.72l-1.36-2.06 5.38-3.61 1.36 2.06-5.37 3.61z"/>
|
||||
<path fill="#85509E" d="M27.04 11.74l-1.37-2.07L28.18 8l1.37 2.06-2.51 1.69z"/>
|
||||
<path fill="#8D166A" d="M35.09 29.48l-9.04 6.07-1.32-2 9.03-6.06 1.33 2z"/>
|
||||
<path fill="#A70D6F" d="M23.1 11.4l1.37 2.06-9.04 6.07-1.37-2.06 9.04-6.07z"/>
|
||||
<path fill="#9E61AD" d="M5.14 9.75l1.71 2.57-2.56 1.72-1.7-2.57 2.55-1.72z"/>
|
||||
<path fill="#8053A3" d="M14.36 40.6l1.7 2.57-2.55 1.72-1.71-2.57 2.56-1.72z"/>
|
||||
<path fill="url(#paint7_linear)" d="M7.63 43.19L.15 31.8l40-26.93 7.84 11.2L7.63 43.19z"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="-12.53" x2="47.68" y1="-9.38" y2="33.11" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C06FBB"/>
|
||||
<stop offset="1" stop-color="#6E4D9B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="37.82" x2="4.33" y1="43" y2="6.94" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6E4D9B"/>
|
||||
<stop offset=".14" stop-color="#77327A"/>
|
||||
<stop offset=".29" stop-color="#B31777"/>
|
||||
<stop offset=".84" stop-color="#CD0F7E"/>
|
||||
<stop offset="1" stop-color="#ED2C89"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="-7.42" x2="35.06" y1="-28.24" y2="47.35" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C06FBB"/>
|
||||
<stop offset="1" stop-color="#6E4D9B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="-24.72" x2="44.39" y1="-12.24" y2="43.73" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C06FBB"/>
|
||||
<stop offset="1" stop-color="#6E4D9B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="-14.41" x2="49.9" y1="-12.4" y2="44.01" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C06FBB"/>
|
||||
<stop offset="1" stop-color="#6E4D9B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear" x1="40.79" x2="7.22" y1="43.89" y2="7.61" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6E4D9B"/>
|
||||
<stop offset=".14" stop-color="#77327A"/>
|
||||
<stop offset=".29" stop-color="#B31777"/>
|
||||
<stop offset=".84" stop-color="#CD0F7E"/>
|
||||
<stop offset="1" stop-color="#ED2C89"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear" x1="-12.52" x2="48.68" y1="-11.86" y2="40.25" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C06FBB"/>
|
||||
<stop offset="1" stop-color="#6E4D9B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear" x1="5.65" x2="34.95" y1="39.23" y2="2.75" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6E4D9B"/>
|
||||
<stop offset=".14" stop-color="#77327A"/>
|
||||
<stop offset=".53" stop-color="#B31777"/>
|
||||
<stop offset=".79" stop-color="#CD0F7E"/>
|
||||
<stop offset="1" stop-color="#ED2C89"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
3
packages/frameworks/logos/brunch.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="49" height="48" fill="none">
|
||||
<path fill="#3F894A" d="M14.52 35.93a3.39 3.39 0 0 0-1.14-2.41 4.65 4.65 0 0 0-.1-.1l-.02-.01a7.6 7.6 0 0 1-2.14-5.4c0-3.08 1.37-11.87 1.67-11.87.23 0 .23 4.24.08 8.22-.1 2.77.3 3.86.96 3.86.88 0 1.02-2.79 1.11-5.92.08-2.57.3-6.14.48-6.16.28 0 .51 3.55.59 6.13.1 3.2.32 5.87 1.05 5.87.77 0 1-1.23.95-3.97-.07-3.34-.07-8.03.17-8.03.3 0 1.3 3.09 1.54 11.88a7.36 7.36 0 0 1-2.14 5.39h-.01l-.11.1a3.39 3.39 0 0 0-1.14 2.42 62.5 62.5 0 0 0-.13 4.62l6.78 6.78c.1-2.95.08-5.74-.05-7.84-.05-.79-.17-1.7-.3-2.43-.05-.23-.2-.44-.2-.63v-25.6c0-2.18 2.05-3.2 3.93 1.58 1.88 4.8 1.35 21.84 1.35 23.05 0 .26-.22.56-.59.86l-.4.29c-1.12.9-1.28 1.95-1.34 2.88-.14 2.26-.25 5.31-.28 8.51l9.34-9.34c-.02-1.1-.05-2.08-.1-2.9-.02-.32-.1-.64-.16-.98-.16-.95-1.35-1.74-2.03-2.43-1.33-1.33-2.19-3.58-2.19-6.11 0-4.11 2.28-9.32 5.1-9.32 2.8 0 5.08 5.2 5.08 9.32 0 2.53-.85 4.78-2.18 6.11-.69.7-1.87 1.48-2.04 2.43-.06.34-.14.66-.16.98l-.07 1.65 13.05-13.05L24.36 0 0 24.36 14.64 39c-.02-1.16-.06-2.2-.12-3.07z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
15
packages/frameworks/logos/chargejs.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<path fill="url(#paint0_linear)" fill-rule="evenodd" d="M17.1 48l-16-9.4a1.87 1.87 0 0 1-.92-1.61l-.1-25.7A1.89 1.89 0 0 1 1 9.64L17.32.16l7.19 6.76 6.1-6.59 16.2 9.53a1.87 1.87 0 0 1 .93 1.6l.1 25.71a1.89 1.89 0 0 1-.92 1.63l-15.7 9.13-7.52-7.07-6.6 7.13V48z" clip-rule="evenodd" opacity=".9"/>
|
||||
<path fill="url(#paint1_linear)" fill-rule="evenodd" d="M44.44 13.39l.1 21.59a1.89 1.89 0 0 1-.92 1.63L25.27 47.29a1.85 1.85 0 0 1-1.87 0L4.9 36.38a1.87 1.87 0 0 1-.92-1.6l-.11-21.6a1.89 1.89 0 0 1 .93-1.63L23.15.88a1.85 1.85 0 0 1 1.87.01l18.5 10.89a1.87 1.87 0 0 1 .92 1.6v.01z" clip-rule="evenodd"/>
|
||||
<path fill="#fff" d="M32.14 19.09l-7.1 1.92.1-10.96-9.5 19.41 7.09-1.92-.11 10.96 9.52-19.41z"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="23.17" x2="31.2" y1="-3.24" y2="50.11" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FE4386"/>
|
||||
<stop offset="1" stop-color="#FFBB94"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="24.59" x2="28.79" y1="2.21" y2="47.42" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F8016B"/>
|
||||
<stop offset="1" stop-color="#FC716A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
packages/frameworks/logos/docusaurus.svg
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
11
packages/frameworks/logos/docz.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="53" height="42" fill="none">
|
||||
<path fill="#E2D9C5" d="M17.92 4.81h31.96A4.3 4.3 0 0 0 45.52.44H13.56a4.3 4.3 0 0 1 4.36 4.37z"/>
|
||||
<path fill="#F2EBDA" d="M41.14 4.76A4.34 4.34 0 0 1 45.5.44H13.55a4.34 4.34 0 0 0-4.36 4.32v35.49h27.6c2.4 0 4.35-1.93 4.35-4.32V4.76z"/>
|
||||
<path fill="#E2D9C5" d="M40.44.44a4.36 4.36 0 0 0-4.37 4.35v31.38c0 2.4-1.96 4.35-4.38 4.35H37a4.36 4.36 0 0 0 4.37-4.35V4.8c0-2.4 1.96-4.35 4.38-4.35h-5.31z"/>
|
||||
<path fill="#E2D9C5" d="M32.53 35.92H.5c.03 2.68 1.97 4.6 4.37 4.6H36.9c-2.4 0-4.34-1.92-4.37-4.6z"/>
|
||||
<path fill="#DDA064" d="M30.19 28c.88-2.74 1.68-5.53 3.56-7.67 4.1-4.66 12.34-6.03 18.31-5.88a53 53 0 0 0-5.38 5.12c-2.12 2.28-6.74 5.3-8.96 5.99-3.46 1.06-5.06 1.24-7.53 2.44z"/>
|
||||
<path fill="#B57947" d="M30.19 28c.88-2.74 15.9-13.71 21.87-13.56a53.02 53.02 0 0 0-5.38 5.12c-2.12 2.28-6.74 5.32-8.96 6-3.46 1.06-5.06 1.23-7.53 2.44z"/>
|
||||
<path fill="#1F2D3D" d="M38.06 8.1c0-.37-.34-.66-.77-.66H20.9c-.42 0-.76.3-.76.65 0 .37.34.66.77.66h16.4c.42 0 .76-.3.76-.66zM13.94 8.75h2.75c.45 0 .81-.3.81-.66 0-.36-.36-.65-.81-.65h-2.75c-.45 0-.81.3-.81.65 0 .37.36.66.81.66zM13.9 31.06c-.43 0-.77.3-.77.66 0 .36.34.66.77.66h8.08c.42 0 .77-.3.77-.66 0-.36-.35-.66-.77-.66H13.9zM26.25 24.72c0-.36-.35-.66-.79-.66H13.91c-.43 0-.78.3-.78.66 0 .36.35.66.78.66h11.55c.44 0 .79-.3.79-.66zM31.94 16.84c0-.36-.36-.65-.8-.65H13.93c-.44 0-.8.3-.8.65 0 .37.36.66.8.66h17.23c.43 0 .79-.3.79-.66z"/>
|
||||
<path fill="#1F2D3D" d="M41.3 26.62a.77.77 0 0 0-.76.78v9.43c0 2-1.6 3.61-3.57 3.61h-.1c-2 0-3.54-1.66-3.56-3.88a.77.77 0 0 0-.77-.77H10.3V5.17c0-2 1.6-3.61 3.57-3.61h28.12l-.06.07-.08.09-.09.1-.07.08-.08.1-.07.1-.07.1-.07.1-.07.1-.06.1-.07.12-.06.1-.05.11-.06.12-.05.1c-.01.05-.03.08-.05.12l-.04.12-.05.12-.04.12-.04.11-.03.13-.04.12-.03.13-.02.12-.03.13-.02.12-.01.15-.02.1-.01.17v.1l-.01.26v6.91c0 .43.34.77.76.77.43 0 .77-.34.77-.77V6.2h7.91c.2 0 .4-.09.55-.23a.78.78 0 0 0 .22-.56C50.72 2.33 48.53 0 45.64 0H13.87a5.14 5.14 0 0 0-5.1 5.17v30.62h-8c-.2 0-.4.09-.55.23a.78.78 0 0 0-.22.56C.03 39.67 2.22 42 5.1 42h31.87c2.81 0 5.1-2.32 5.1-5.17V27.4a.77.77 0 0 0-.77-.78zm.81-21.99l.01-.07.02-.1.02-.07a3.53 3.53 0 0 1 .2-.65l.04-.07.04-.09.03-.06.04-.09.02-.03a3.72 3.72 0 0 1 .32-.48l.02-.02.08-.1.02-.02.1-.1v-.02l.1-.1.02-.01.1-.1h.01a3.46 3.46 0 0 1 1.85-.85v-.01l.16-.02H45.48l.08-.01h.09c1.76 0 3.16 1.28 3.49 3.09H42.1v-.02zm-37 35.81c-1.77 0-3.17-1.28-3.5-3.09h30.22a6 6 0 0 0 .03.24l.02.08a6 6 0 0 0 .03.15l.02.1.03.14.03.1a6.14 6.14 0 0 0 .18.56l.04.1.05.12.04.09.06.12.04.08.08.15.03.05.11.19c0 .02.02.03.03.04l.1.15a4.63 4.63 0 0 0 .13.18l.04.07.08.1.06.07a5.16 5.16 0 0 0 .15.17l.04.04H5.1z"/>
|
||||
<path fill="#1F2D3D" d="M52.94 14.35v-.03a.77.77 0 0 0-.04-.21v-.01-.01a.77.77 0 0 0-.05-.1v-.01a.78.78 0 0 0-.06-.08l-.01-.02a.78.78 0 0 0-.07-.07l-.01-.02a.8.8 0 0 0-.17-.12l-.02-.01a.79.79 0 0 0-.33-.08c-6.56-.17-15.11 1.4-19.44 6.29-1.89 2.14-2.76 4.86-3.6 7.49l-.22.64v.03l-1.33 4.67a.78.78 0 0 0 .76.99c.34 0 .65-.23.75-.57l1.23-4.33c1.5-.7 2.71-1.02 4.34-1.46.85-.23 1.81-.5 2.97-.85 2.52-.76 7.34-3.97 9.55-6.35a53.37 53.37 0 0 1 5.46-5.18.78.78 0 0 0 .15-.16l.02-.02a.77.77 0 0 0 .11-.32v-.08-.02zm-19.02 6.54c1.83-2.06 4.62-3.62 8.31-4.63 1-.27 2.04-.49 3.12-.67a60.73 60.73 0 0 0-6.83 3.95 62.64 62.64 0 0 0-6.81 5.16c.56-1.4 1.23-2.7 2.21-3.8zm12.12-1.82c-2.16 2.32-6.82 5.3-8.86 5.93-1.13.34-2.08.6-2.92.83-.75.2-1.44.38-2.12.6.3-.29.66-.61 1.08-.98 1.7-1.46 3.88-3.1 6.17-4.62 3.95-2.62 7.53-4.46 10.16-5.26a60.6 60.6 0 0 0-3.5 3.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
1
packages/frameworks/logos/eleventy.svg
Normal file
|
After Width: | Height: | Size: 13 KiB |
1
packages/frameworks/logos/ember.svg
Normal file
|
After Width: | Height: | Size: 39 KiB |
73
packages/frameworks/logos/foundation.svg
Normal file
@@ -0,0 +1,73 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="483" height="400">
|
||||
<path fill="#EAF7FE" d="M316 92l15-18c-10-11-30-9-30-9l12-14-20-8c3-9 13-17 13-17-37-14-64 3-64 3 2-9 14-22 14-22-37 2-65 32-65 32 0-5 4-19 4-19s-20 14-31 35c-4 7-19 61-21 73 0 0-5-2-10-1 0 0 7 10 8 14s-7 33-10 38-7 7-9 8c0 0 3 5 6 6 0 0-1 16-3 20s-8 9-10 11c0 0 6 7 10 7l-6 10c-2 2-5-2-5-2l1 8c1 3 0 7-1 9s-5 15-6 21 1 11 1 11 2-3 4-4c0 0 0 13 3 19l9 13s-1-4 1-6c0 0 3 11 18 13 33 5 56 11 94-11 35-21 31-96 42-144 5-23 17-45 27-62 7-8 18-14 18-14h-9z"/>
|
||||
<ellipse cx="248" cy="377" fill="#E5E5E5" rx="230" ry="17"/>
|
||||
<path fill="#A1D4E9" d="M83 369l1-5c0-5 1-11 5-16l-3 1c5-6 10-10 13-11l-3-1c3-2 11-3 18-4l-3-2 13 1 21-4-2-6c8 0 20 2 23 3 2 0 3 5 4 5 0 0 20-11 20 8l-1 36-16-1h-28l-43 1v-2H92v-2-2l-9 1z"/>
|
||||
<path fill="#85C1CE" d="M92 368h-4c0-24 24-30 24-30-21 8-20 27-20 30zM97 363l6-9c8-11 22-12 22-12-25 5-23 30-23 30h-4l1-9h-2z"/>
|
||||
<path fill="#4F4E51" d="M162 82c-22-8-34-30-34-30s-6 16 1 33c6 12 19 20 26 24l7-27z"/>
|
||||
<path fill="#5C5B5D" d="M162 82c-22-8-34-30-34-30s2 30 30 43l4-13z"/>
|
||||
<g fill="#A1D4E9">
|
||||
<path d="M128 208l-8-8c-4-7-5-15-5-15-2 2-2 6-2 7a55 55 0 00-13-9l-8 1 3 61 21 10s20-31 12-47zM95 181l-12-5s4 3 3 6c0 2 3 2 6 2v-4l3 1z"/>
|
||||
<path d="M95 181l-4-1 1 4 8-1-5-2z"/>
|
||||
</g>
|
||||
<path fill="#CDEAF5" d="M183 64c13-22 56-42 64-45l9-12c-37 2-65 32-65 32 0-5 4-19 4-19s-20 14-31 35c-4 7-19 61-21 73 0 0-5-2-10-1 0 0 7 10 8 14s-7 33-10 38-7 7-9 8c0 0 3 5 6 6 0 0-1 16-3 20s-8 9-10 11c0 0 5 7 9 8l-5 9c-2 2-5-2-5-2l1 8c1 3 0 7-1 9s-5 15-6 21 1 11 1 11 2-3 4-4c0 0 0 13 3 19l9 13s-1-2 1-4c0 0 4 9 19 14 12 4 22 5 36 1 9-3 15-13 15-13-62 20-80-22-73-49 4-13 19-35 19-35-7 2-11-5-11-5s3 0 9-6c5-5 4-34 4-34l-6 1c1 0 2-1 6-10l-3-1v-1c2-6 1-13 3-19l2-5h6l4-17c12-54 25-85 25-85-2 6 2 16 2 16z"/>
|
||||
<path fill="#5D5C5E" d="M120 235c1 2 1 5-1 6l-38 28c-2 2-5 2-6 0l-56-74c-1-2-1-5 1-6l38-29c2-1 5-1 6 1l56 74z"/>
|
||||
<path fill="none" stroke="#738083" stroke-miterlimit="10" stroke-width="2" d="M120 235c1 2 1 5-1 6l-38 28c-2 2-5 2-6 0l-56-74c-1-2-1-5 1-6l38-29c2-1 5-1 6 1l56 74z"/>
|
||||
<path fill="#747F84" d="M109 229l-38 28-41-54 38-29z"/>
|
||||
<path fill="#414141" d="M98 247c2 2 1 4 0 5-2 1-4 1-5-1v-5c2-1 4 0 5 1z"/>
|
||||
<path fill="none" stroke="#414141" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M39 187l12-9"/>
|
||||
<g fill="#E9F7FE" opacity=".5">
|
||||
<path d="M91 208l-33 26-18-25 33-25zM75 236l-10 7-5-6 10-7zM95 214l-21 16-2-2 21-16zM99 218l-22 16-2-2 22-16z"/>
|
||||
<g>
|
||||
<path d="M82 245l-10 8-5-7 10-7zM102 223l-21 17-2-3 21-16zM105 227l-21 16-2-3 21-16z"/>
|
||||
</g>
|
||||
<path d="M70 182l-33 25-3-3 34-26z"/>
|
||||
</g>
|
||||
<path fill="#A1D4E9" d="M99 207c-19 15-41 3-41 3 3-6 21-30 34-30 0 0 19 8 7 27zM87 224c-25-7-47-1-47-1-10 2-7 14-2 23l4 14 3-3c5 7 15 12 28 4 16-10 14-37 14-37z"/>
|
||||
<ellipse cx="214.2" cy="174" fill="#CDEAF5" rx="10.8" ry="13.7"/>
|
||||
<ellipse cx="160.3" cy="165.8" fill="#CDEAF5" rx="10.8" ry="13.7"/>
|
||||
<ellipse cx="213.2" cy="170.2" fill="#FFF" rx="10.7" ry="13.5"/>
|
||||
<ellipse cx="160.2" cy="162.2" fill="#FFF" rx="10.7" ry="13.5"/>
|
||||
<path fill="#4F4E51" d="M166 156v1c0 2-1 4-3 4l-2-3-2 4c0 4 3 7 5 7 3 0 6-3 6-7 0-3-2-5-4-6z"/>
|
||||
<path fill="#5C5B5D" d="M255 165c-4-3-9-4-9-4-4-2-13-4-23-5l-31-1h-12a38 38 0 01-4-2l-9-4-13-2-20-1-2 1-2 4v4l2 4 1 2v11c1 3 3 6 10 8l5 1c12 3 17 2 21 0s6-10 8-14v-2l1-1 1-1 3 1 2 1v4l1 4v1c0 3 1 9 4 11 1 2 6 4 11 6l11 2h21c4-1 5-3 7-7l1-1v-1l5-17 9 3 1-5zm-82-4l-4 11c-2 5-2 5-4 6-2 0-9 0-17-2-6-1-10-4-10-6v-18-1h8c6 0 14 3 17 4h2c5 2 8 4 8 6zm66 8l-5 17c-1 2-3 2-10 3h-1a91 91 0 01-24-4c-6-2-7-3-8-6l-1-15c0-2 0-3 2-3h25a143 143 0 0120 4c1 0 3 2 2 4z"/>
|
||||
<path fill="#4F4E51" d="M216 163v1c0 2-1 4-3 4l-2-3-2 4c0 4 3 7 5 7 3 0 6-3 6-7 0-3-2-5-4-6z"/>
|
||||
<path fill="#A1D4E9" d="M207 121s19-8 28 1c0 0 0-9-12-9-8 0-12 4-16 8zM211 111s6-6 17-4c0 0-4-4-9-3-4 1-6 3-8 7zM154 127s10 3 14 10c0 0 1-6-4-9-5-2-6-2-10-1zM171 126s-2-4-7-4c0 0 4-2 6 0 0 0 2 2 1 4z"/>
|
||||
<path fill="#5C5B5D" d="M176 198l25 5 2-4v5s-7 2-13 1l10-1s-13-1-24-6zM280 102l3 2c26 10 52-4 52-4s-4 16-20 27c-15 10-39 5-39 5-2 3-3 10-3 10s-4-9-1-24c2-10 7-16 8-16"/>
|
||||
<path fill="#747F83" d="M280 102l3 2c26 10 52-4 52-4s-23 31-62 15c0 0 1-7 7-13"/>
|
||||
<path fill="#CDEAF5" d="M125 231s10 2 16-2c0 0 2 9 10 15 0 0 7-12 14-14l1 11s13 1 25-9c0 0-3 14-30 15v-8s-6 7-10 16c0 0-14-10-16-19h-12l2-5z"/>
|
||||
<path fill="#85C1CE" d="M76 222s-13 10-22 13c0 0 22-5 29-8 0 0-6 15-24 21 0 0 17-2 24-8 0 0-8 23-25 25 0 0 10 1 19-7 9-9 11-27 10-34l-11-2zM100 207l7-5s0 5-5 8l-2-3z"/>
|
||||
<path fill="#EAF7FE" d="M331 263c3-2 5-1 4-10-1-8-6-17-6-17M279 221l-5 2 6 2zM334 228s12-3 16-10"/>
|
||||
<path fill="#85C1CE" d="M130 330s16 10 39 7v-8s-13 1-26-4v3l-4-2v3l-9 1z"/>
|
||||
<path fill="#CDEAF5" d="M222 347h-3c-11 0-19-2-30-1l-22 1 10-10 1 3 6-10 11-15-17 6-4 6v1c-2-2-4-3-4-1l-1 2c-3 5-17 14-17 14l-2 1 3 1v2l-1 1v5l-1 10c0 2-2 4-4 4 0 0 2 2 3 1v1s-1 8 6 9h21l21 1v-3l12 1 2-4 18 1c3-19-2-26-8-27z"/>
|
||||
<path fill="#EAF7FE" d="M233 367v-6l1 1-3-8c-2-4-5-7-10-7l1-2c-4-1-7-2-14-1 4-1 8-4 12-7l2 1 2-5h-1l7-8 2 3 6-16-28 9-3 3-11-11-14 19-3 7c-1-1-1-3-2-2-4 4-8 8-12 10h8l-4 2 12-1c12-1 19 4 19 4v-1c1 1 4 3 6 8 0 1 2 8 1 10l2-1v9h8s1-10-1-18h2c-1-4-4-7-7-8l-1-1s16-2 16 23h3l7 1-1-1-2-6zm-27-8l2 4-2-4z"/>
|
||||
<path fill="#EAF7FE" d="M194 358l2-1c-3-2-7-2-9-2h-2s7 6 6 24h7s3-14-4-21z"/>
|
||||
<g>
|
||||
<path fill="#5D5C5E" d="M452 372c0 5-5 9-10 9H237c-6 0-10-4-10-9V227c0-5 4-10 10-10h205c5 0 10 5 10 10v145z"/>
|
||||
<path fill="none" stroke="#738083" stroke-miterlimit="10" stroke-width="2" d="M452 372c0 5-5 9-10 9H237c-6 0-10-4-10-9V227c0-5 4-10 10-10h205c5 0 10 5 10 10v145h0z"/>
|
||||
<path fill="#747F84" d="M247 231h185v136H247z"/>
|
||||
<path fill="#414141" d="M243 299c0 3-2 5-5 5-2 0-4-2-4-5 0-2 2-4 4-4 3 0 5 2 5 4z"/>
|
||||
<path fill="none" stroke="#414141" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M440 290v18"/>
|
||||
<g fill="#E9F7FE" opacity=".5">
|
||||
<path d="M252 237h176v12H252zM252 252h176v58H252zM252 317h28v20h-28zM284 317h53v5h-53zM284 324h53v5h-53zM284 332h53v5h-53z"/>
|
||||
<g>
|
||||
<path d="M342 317h28v20h-28zM374 317h53v5h-53zM374 324h53v5h-53zM374 332h53v5h-53z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M252 343h28v20h-28zM284 343h53v5h-53zM284 351h53v5h-53zM284 358h53v5h-53z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M342 343h28v20h-28zM374 343h53v5h-53zM374 351h53v5h-53zM374 358h53v5h-53z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#EAF7FE" d="M382 187l8 3-10-11-15-7 2-2h-10l-30-4 2-3-39 2 1-4-6 3c0-3 5-9 5-9-6 1-11 9-11 9l-1 5-7 47h112c1-9 0-21-2-29h1zm-94-20z"/>
|
||||
<path fill="#4F4E51" d="M330 260l-4 5-8-7-12 9-7-10c-2-3-2-14-2-14l-3 2 5-15s30-6 31 30z" opacity=".3"/>
|
||||
<path fill="#EAF7FE" d="M333 246c1-4-1-8-1-12l2-5c1-2 3-2 5-3a385 385 0 017-4c10-5 37-8 37-8-39-15-95 0-95 0-11 7-17 30-17 30 9-7 35-22 35-22-1 11-16 11 25 41 0-6 2-11 3-17h-1z"/>
|
||||
<path fill="#CDEAF5" d="M289 197c-7 5-13 12-18 19h15l13-10-15-1s21-5 29-9c10-8 17-13 26-16 0 0 1-1-1-1l4-1 10-3s-20-2-63 22z"/>
|
||||
<path fill="#4F4E51" d="M285 229h-19l-2 6-1 9 22-15z" opacity=".3"/>
|
||||
<path fill="#EAF7FE" d="M299 206s-26 15-27 29l-1 9 28-21v-17zM305 224c-5 16-5 16-4 24l2 8 11 11s10-7 9-14c-3-23-18-29-18-29z"/>
|
||||
<path fill="#EAF7FE" d="M293 230s4-5 14-6c7 0 0-5 0-5l-13 1"/>
|
||||
<path fill="#EAF7FE" d="M302 252l-2-12-2 2c3-15 2-15 5-19 3-7 3 21 3 21"/>
|
||||
<path fill="#CDEAF5" d="M317 240c1-5 1-13 3-18l-2 3c-2 4-4 10-4 17 0 8 7 17 7 17l2-2-4-8s-2-3-2-9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.3 KiB |
1
packages/frameworks/logos/gatsby.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M42.857 24h-12v3.428h8.229c-1.2 5.143-4.972 9.43-9.943 11.143L9.429 18.857c2.057-6 7.885-10.286 14.571-10.286 5.143 0 9.771 2.572 12.686 6.515l2.571-2.229C35.83 8.23 30.343 5.143 24 5.143c-8.914 0-16.457 6.343-18.343 14.743l22.629 22.628c8.228-2.057 14.571-9.6 14.571-18.514zm-37.714.171c0 4.8 1.886 9.429 5.486 13.029 3.6 3.6 8.4 5.486 13.028 5.486L5.143 24.17z" fill="#fff"/><path d="M24 0C10.8 0 0 10.8 0 24s10.8 24 24 24 24-10.8 24-24S37.2 0 24 0zM10.629 37.371c-3.6-3.6-5.486-8.4-5.486-13.028l18.686 18.514c-4.8-.171-9.6-1.886-13.2-5.486zm17.485 4.972L5.657 19.886C7.543 11.486 15.086 5.143 24 5.143c6.343 0 11.829 3.086 15.257 7.714l-2.571 2.229C33.77 11.143 29.143 8.57 24 8.57c-6.686 0-12.343 4.286-14.571 10.286l19.714 19.714c4.971-1.714 8.743-6 9.943-11.142h-8.229V24h12c0 8.914-6.343 16.457-14.743 18.343z" fill="#639"/></svg>
|
||||
|
After Width: | Height: | Size: 921 B |
1
packages/frameworks/logos/gridsome.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M43.395 19.862c2.308-.11 4.35 1.68 4.55 3.99.863 11.174-9.364 23.692-23.775 24.092C12.025 48.244.013 38.521.013 23.82c0-2.317 1.915-4.195 4.225-4.195a4.19 4.19 0 0 1 4.184 4.195c0 9.67 7.776 15.928 15.542 15.737 9.56-.266 15.776-8.544 15.453-15.303a4.19 4.19 0 0 1 3.978-4.392z" fill="url(#paint0_linear)"/><path d="M32.944 24.145c0-2.372 1.935-4.295 4.321-4.295h6.298c2.387 0 4.382 1.923 4.382 4.295s-1.995 4.295-4.382 4.295h-6.298c-2.386 0-4.321-1.923-4.321-4.295zm-13.215.006a4.297 4.297 0 0 1 4.291-4.301 4.297 4.297 0 0 1 4.292 4.301 4.297 4.297 0 0 1-4.292 4.301 4.297 4.297 0 0 1-4.291-4.301z" fill="#00A672"/><path fill-rule="evenodd" clip-rule="evenodd" d="M28.193 4.055a4.19 4.19 0 0 1-4.006 4.365c-9.966.415-16.05 8.248-15.753 15.685.092 2.315-1.668 4.267-3.976 4.36-2.309.092-4.34-1.777-4.431-4.092C-.456 12.253 9.635.273 23.84.037a4.188 4.188 0 0 1 4.353 4.018z" fill="#00A672"/><defs><linearGradient id="paint0_linear" x1="24.005" y1="19.625" x2="24.005" y2="47.951" gradientUnits="userSpaceOnUse"><stop stop-color="#00583E"/><stop offset="1" stop-color="#00835C"/></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
packages/frameworks/logos/hexo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M23.829.005l-20.735 12 .002 23.964L23.878 47.92l20.736-12V11.97L23.829.004z" fill="#0E83CD"/><path d="M14.101 34.338l.002-10.362.002-10.363 1.882-1.101 1.804 1.067.019 4.235.02 4.234h12.05l.019-4.231.02-4.232 1.83-1.059 1.857 1.087V23.97l-.002 10.355-1.837 1.027-1.849-1.04-.02-4.21-.019-4.212H17.83l-.019 4.21.006 4.23-1.848 1.085-1.866-1.076z" fill="#fff"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(3)" d="M0 0H41.645V48H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 591 B |
5
packages/frameworks/logos/hugo.svg
Normal file
|
After Width: | Height: | Size: 30 KiB |
4
packages/frameworks/logos/hyperapp.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<rect width="48" height="48" fill="#0080FF" rx="24"/>
|
||||
<path fill="#fff" d="M18.5386 21.6899h7.8153l1.8771 3.8487h-9.6924v9.6902h-3.8481v-9.6902H5v-3.8487h9.6905V12h3.8481v9.6899zm24.1057 13.5389h-4.5342L26.7809 12h4.5341l11.3293 23.2288z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 328 B |
4
packages/frameworks/logos/ionic-react.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<rect width="48" height="48" fill="#4180FC" rx="24"/>
|
||||
<path fill="#fff" fill-rule="evenodd" d="M38.4327 17.0558l.1306.3047C39.5211 19.4721 40 21.6925 40 24c0 8.8163-7.1837 16-16 16S8 32.8163 8 24 15.1837 8 24 8c2.5905 0 5.0503.6095 7.3143 1.7415l.3047.1524-.2612.2177c-.653.5224-1.1537 1.1755-1.4802 1.9374l-.0871.2177-.1959-.0871C27.8313 11.3524 25.9592 10.917 24 10.917c-7.2272 0-13.083 5.8558-13.083 13.083S16.7728 37.083 24 37.083 37.083 31.2054 37.083 24c0-1.7197-.3265-3.4177-1.0014-5.0068l-.087-.2177.2176-.0871c.7619-.283 1.4585-.7619 2.0028-1.3714l.2177-.2612zm-3.962.3048c1.8395 0 3.3307-1.4912 3.3307-3.3306 0-1.8395-1.4912-3.3307-3.3307-3.3307-1.8394 0-3.3306 1.4912-3.3306 3.3307 0 1.8394 1.4912 3.3306 3.3306 3.3306zm-10.4708-.6531c-4.0272 0-7.2925 3.2653-7.2925 7.2926 0 4.0272 3.2653 7.2925 7.2925 7.2925 4.0272 0 7.2925-3.2653 7.2925-7.2925 0-4.0273-3.2653-7.2926-7.2925-7.2926z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1003 B |
19
packages/frameworks/logos/jekyll.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<path fill="#333" d="M0 24a24 24 0 1 0 48 0 24 24 0 0 0-48 0z"/>
|
||||
<path fill="#000" d="M25.22 5.55a.52.52 0 0 0 0 .22s.23 1.56-.03 2.25l-11.35 29.5a4.22 4.22 0 0 0 7.88 3.03l11.35-29.5c.22-.57 1.48-1.7 1.48-1.7.07-.04.12-.1.15-.16v-.01l.02-.04c.3-.76-1.6-2.2-4.21-3.2-2.62-1-4.98-1.2-5.27-.45l-.02.04v.02z" opacity=".3"/>
|
||||
<path fill="url(#paint0_linear)" d="M24.9 5.3a.51.51 0 0 0-.01.22s.23 1.56-.03 2.25L13.5 37.27a4.22 4.22 0 0 0 7.88 3.03l11.35-29.5c.22-.58 1.49-1.7 1.49-1.7.06-.04.1-.1.14-.16v-.01l.03-.04c.29-.76-1.6-2.2-4.22-3.2-2.62-1-4.98-1.2-5.27-.45l-.01.04v.01z"/>
|
||||
<path fill="url(#paint1_linear)" d="M28.45 18.64L20.27 39.9a3.06 3.06 0 0 1-3.91 1.72 3.12 3.12 0 0 1-1.83-3.93l5.23-13.59s.65-1.05 1.93-1.8c1.29-.75 2.34-.6 3.77-1.22 1.42-.64 3-2.45 3-2.45z"/>
|
||||
<path fill="#333" d="M29.33 7.92c1.62.63 3.07.79 3.24.36.16-.43-1.02-1.28-2.65-1.9-1.62-.63-3.08-.8-3.24-.37-.17.43 1.02 1.28 2.65 1.91z"/>
|
||||
<path fill="#fff" d="M24.89 5.52s.23 1.57-.03 2.25L13.5 37.27a4.22 4.22 0 0 0 3.58 5.68 4.22 4.22 0 0 1-1.41-4.85L26.8 9.19s-1.52-1.42-1.91-3.67z" opacity=".3"/>
|
||||
<path fill="#fff" d="M21.24 24.87a.33.33 0 1 0 0-.65.33.33 0 0 0 0 .65zM23.4 27.42a.5.5 0 1 0 0-.99.5.5 0 0 0 0 1zM20.1 30.7a.93.93 0 1 0 0-1.87.93.93 0 0 0 0 1.86zM18.6 31.98a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zM20.57 35.49a.33.33 0 1 0 0-.66.33.33 0 0 0 0 .66z" opacity=".5"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="18.32" x2="27.81" y1="22.36" y2="26.01" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#919191"/>
|
||||
<stop offset="1" stop-color="#fff"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="18.08" x2="23.83" y1="28.47" y2="30.68" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#900"/>
|
||||
<stop offset="1" stop-color="#E80000"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
BIN
packages/frameworks/logos/marko.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
11
packages/frameworks/logos/mdx-deck.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="138" height="57">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="136.5" height="55.5" x=".8" y=".8" fill="#FFF" stroke="#EAEAEA" stroke-width="1.5" rx="4.5"/>
|
||||
<g stroke="#000" stroke-width="6">
|
||||
<path stroke-linecap="square" d="M70.5 36V13.8"/>
|
||||
<path d="M57 27.2L70.6 41 84 27.4"/>
|
||||
</g>
|
||||
<path stroke="#000" stroke-width="6" d="M16.4 44V19l13.9 13.8 14-14v25"/>
|
||||
<path stroke="#F9AC00" stroke-width="6" d="M122.4 41.3L93.2 12m.4 29.3L122.8 12"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 539 B |
BIN
packages/frameworks/logos/metalsmith.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
9
packages/frameworks/logos/middleman.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<rect width="48" height="48" fill="#FBC547" rx="24"/>
|
||||
<path fill="#000" fill-opacity=".45" d="M6 12.53L23.65 9v2.65L6 14.29v-1.76z"/>
|
||||
<path fill="#fff" d="M23.65 9l17.64 3.53v1.76l-17.64-2.64V9z"/>
|
||||
<path fill="#000" fill-opacity=".45" d="M6 15.88v16.24l3.97.44V22.4l3.97 7.33 4.15-7.33V33.8l4.67.62V13.6l-5.02.7-3.8 7.33-3.8-6.18-4.14.44z"/>
|
||||
<path fill="#fff" d="M41.3 15.88v16.24l-3.98.44V22.4l-3.97 7.33-4.14-7.33V33.8l-4.68.62V13.6l5.03.7 3.8 7.33 3.79-6.18 4.14.44z"/>
|
||||
<path fill="#000" fill-opacity=".45" d="M6 35.47L23.65 39v-2.65L6 33.71v1.76z"/>
|
||||
<path fill="#fff" d="M23.65 39l17.64-3.53v-1.76l-17.64 2.64V39z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 715 B |
4
packages/frameworks/logos/mithriljs.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<rect width="48" height="48" fill="#000" rx="24"/>
|
||||
<path fill="#fff" d="M36.109 17.5974C36.0934 11.1453 30.839 5.9 24.3831 5.9c-6.4659 0-11.7267 5.2609-11.7267 11.7268 0 .0202.0037.0394.0037.0596C9.2734 19.745 7 23.4594 7 27.7033 7 34.1701 12.2599 39.43 18.7267 39.43c2.0816 0 4.0338-.5516 5.7308-1.507 1.697.9554 3.6501 1.507 5.7316 1.507 6.4669 0 11.7268-5.2608 11.7268-11.7267 0-4.3054-2.3386-8.0666-5.8069-10.1059zM24.4575 35.4587c-2.122-1.5722-3.5849-3.9842-3.8731-6.7477 1.1931.4112 2.4679.6443 3.7987.6443 1.3896 0 2.7167-.2551 3.953-.7012-.2735 2.7874-1.742 5.2214-3.8786 6.8046zm-9.6406-16.5782c1.1959-.5314 2.5175-.8343 3.9098-.8343a9.5872 9.5872 0 0 1 3.8126.7875c-1.9403 1.6759-3.3307 3.9695-3.8502 6.5778-2.077-1.5253-3.5225-3.8547-3.8722-6.531zm9.5662 8.4043c-1.3372 0-2.612-.2735-3.7712-.7682.3313-2.6873 1.7704-5.0314 3.8456-6.5687 2.0586 1.5254 3.4895 3.8428 3.8364 6.5026-1.1968.5332-2.5185.8343-3.9108.8343zm1.9926-8.4521a9.6043 9.6043 0 0 1 3.8125-.7874c1.3373 0 2.6121.2735 3.7722.7682-.3267 2.6478-1.7282 4.9598-3.7529 6.4998-.5342-2.5689-1.9154-4.8248-3.8318-6.4806zm-1.9926-10.863c4.9855 0 9.1 3.7969 9.6057 8.6502-1.1931-.4102-2.4679-.6443-3.7997-.6443-2.0815 0-4.0346.5516-5.7316 1.5071-1.6961-.9555-3.6483-1.5071-5.7308-1.5071-1.3895 0-2.7167.2552-3.9529.7003.48-4.8799 4.6055-8.7062 9.6093-8.7062zm-5.6564 29.3916c-5.326 0-9.658-4.332-9.658-9.658 0-3.1371 1.5098-5.9207 3.8337-7.6866.6828 3.2867 2.7525 6.0639 5.5609 7.7169.0101 3.5308 1.5924 6.6935 4.0769 8.8393a9.5766 9.5766 0 0 1-3.8135.7884zm11.4624 0a9.587 9.587 0 0 1-3.8125-.7875c2.4918-2.1522 4.0787-5.3269 4.0787-8.8696 0-.0202-.0037-.0404-.0037-.0596 2.7599-1.6787 4.7809-4.4532 5.4316-7.7243 2.3982 1.7595 3.964 4.5881 3.964 7.783-.001 5.3251-4.333 9.658-9.6581 9.658z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
4
packages/frameworks/logos/mkdocs.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<circle cx="24" cy="24" r="24" fill="#2FA4E7"/>
|
||||
<path fill="#fff" d="M32.55 32.91V16h-3.07L24.1 29.23h-.2L18.52 16h-3.07v16.91h2.43V20.52h.17L23 32.61h2l4.95-12.09h.17v12.39h2.43z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 270 B |
1
packages/frameworks/logos/next.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22.428.013c-.103.01-.431.042-.727.066C14.883.693 8.497 4.37 4.453 10.024A23.754 23.754 0 0 0 .216 20.51C.023 21.828 0 22.217 0 24.005c0 1.787.023 2.177.216 3.495 1.304 9.012 7.718 16.584 16.417 19.39 1.558.501 3.2.844 5.068 1.05.727.08 3.87.08 4.598 0 3.224-.356 5.954-1.154 8.648-2.529.412-.21.492-.267.436-.314-.038-.028-1.797-2.388-3.909-5.24l-3.838-5.184-4.809-7.117c-2.646-3.913-4.824-7.112-4.842-7.112-.019-.005-.038 3.157-.047 7.018-.014 6.76-.019 7.033-.103 7.192-.122.23-.216.324-.413.427-.15.075-.282.09-.99.09h-.812l-.216-.137a.878.878 0 0 1-.314-.342l-.099-.211.01-9.407.014-9.41.145-.184c.075-.098.235-.225.347-.286.193-.094.268-.103 1.08-.103.957 0 1.116.038 1.365.31.07.075 2.674 3.997 5.79 8.721s7.376 11.175 9.469 14.342l3.8 5.756.192-.127c1.704-1.107 3.505-2.683 4.932-4.325a23.888 23.888 0 0 0 5.65-12.268c.192-1.319.215-1.708.215-3.495 0-1.788-.023-2.177-.216-3.495-1.304-9.013-7.718-16.584-16.417-19.39C29.832.623 28.199.28 26.369.074c-.45-.047-3.551-.099-3.94-.061zm9.825 14.515a.947.947 0 0 1 .474.554c.038.122.047 2.73.038 8.608l-.014 8.436-1.488-2.28-1.492-2.28v-6.132c0-3.964.019-6.193.047-6.3a.957.957 0 0 1 .465-.592c.192-.098.262-.108 1-.108.694 0 .816.01.97.094z" fill="#000"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
5
packages/frameworks/logos/nuxt.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="48" height="38" viewBox="0 0 48 38" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.7599 35.9199L14.6399 35.7999C14.3999 35.3199 14.3999 34.8399 14.3999 34.3599H2.99992L20.0399 4.11988L27.1199 16.9599L29.3999 15.2799L22.3199 2.43988C22.1999 2.19988 21.3599 0.879883 19.9199 0.879883C19.3199 0.879883 18.3599 1.11988 17.6399 2.43988L0.479919 33.0399C0.359919 33.2799 -0.360081 34.7199 0.359919 35.9199C0.599919 36.5199 1.31992 37.1199 2.87992 37.1199H17.2799C15.7199 37.1199 14.9999 36.5199 14.7599 35.9199Z" fill="#00C58E"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.3999 33.1598L33.5999 8.31977C33.3599 8.07977 32.6399 6.75977 31.1999 6.75977C30.5999 6.75977 29.7599 6.99977 28.9199 8.31977L27.1199 11.1998V16.9598L31.1999 9.87977L44.8799 34.3598H39.7199C39.7913 34.853 39.7075 35.3563 39.4799 35.7998V35.9198C38.7599 37.1198 37.1999 37.1198 36.9599 37.1198H45.1199C45.3599 37.1198 46.9199 37.1198 47.6399 35.9198C47.8799 35.3198 48.1199 34.3598 47.3999 33.1598Z" fill="#108775"/>
|
||||
<path d="M39.84 35.9199V35.7999L39.96 35.5599C40.08 35.1999 40.2 34.7199 40.08 34.3599L39.6 33.0399L28.8 14.08L27.24 11.2H27.12L25.56 14.08L14.64 33.0399L14.28 34.3599C14.1908 34.8922 14.275 35.4391 14.52 35.9199C14.88 36.5199 15.6 37.1199 17.04 37.1199H37.2C37.56 37.1199 39.12 37.1199 39.84 35.9199ZM27.12 16.96L37.08 34.3599H17.28L27.12 16.96Z" fill="#2F495E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
BIN
packages/frameworks/logos/pelican.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
1
packages/frameworks/logos/polymer.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M28.8 40.371L9.6 7.113H19.2l19.201 33.258h-9.6z" fill="#FF4081"/><path d="M28.8 40.371l4.8-8.314 4.802 8.314H28.8z" fill="#fff" fill-opacity=".2"/><path d="M24 32.057l4.8 8.314 4.8-8.314H24z" fill="#fff" fill-opacity=".1"/><path d="M19.2 23.742l4.8 8.315 4.8-8.315h-9.6z" fill="#000" fill-opacity=".1"/><path d="M19.2 23.742l4.8-8.314 4.8 8.314h-9.6z" fill="#000" fill-opacity=".2"/><path d="M14.4 15.428l4.8 8.314 4.8-8.314h-9.6z" fill="#000" fill-opacity=".3"/><path d="M14.4 15.428l4.8-8.315 4.8 8.315h-9.6z" fill="#000" fill-opacity=".4"/><path d="M9.599 7.113l4.801 8.315 4.8-8.315H9.6z" fill="#000" fill-opacity=".5"/><path d="M9.599 40.371L-.002 23.742l4.8-8.314L19.2 40.37H9.599z" fill="#536DFE"/><path d="M9.599 40.371l4.801-8.314 4.8 8.314H9.6z" fill="#fff" fill-opacity=".2"/><path d="M4.799 32.057l4.8 8.314 4.801-8.314H4.8z" fill="#fff" fill-opacity=".1"/><path d="M-.002 23.742l4.8 8.315 4.8-8.315h-9.6z" fill="#000" fill-opacity=".1"/><path d="M-.002 23.742l4.8-8.314 4.8 8.314h-9.6z" fill="#000" fill-opacity=".2"/><path d="M9.599 23.742l-4.8-8.314 4.8-8.315 4.801 8.315L9.6 23.742z" fill="#303F9F"/><path d="M14.4 15.428L9.6 7.113l-4.8 8.315H14.4z" fill="#000" fill-opacity=".2"/><path d="M38.401 40.371l-4.8-8.314 4.8-8.315 4.8 8.315-4.8 8.314z" fill="#3F51B5"/><path d="M43.201 32.057l-4.8 8.314-4.8-8.314h9.6z" fill="#000" fill-opacity=".2"/><path d="M43.201 32.057L28.8 7.113h9.601l9.602 16.63-4.802 8.314z" fill="#7986CB"/><path d="M38.401 23.742l4.8 8.315 4.801-8.315h-9.6z" fill="#fff" fill-opacity=".2"/><path d="M38.401 23.742l4.8-8.314 4.801 8.314h-9.6z" fill="#fff" fill-opacity=".1"/><path d="M33.6 15.428l4.801-8.315 4.8 8.315h-9.6z" fill="#000" fill-opacity=".1"/><path d="M28.8 7.113l4.8 8.315 4.801-8.315H28.8z" fill="#000" fill-opacity=".2"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(0 7)" d="M0 0H48V33.375H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
packages/frameworks/logos/preact.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M23.757 0l20.756 11.984V35.95L23.758 47.935 3 35.951V11.984L23.757 0z" fill="#673AB8"/><path d="M8.654 35.753c2.76 3.532 11.529.84 19.808-5.628S41.474 15.8 38.714 12.267s-11.529-.84-19.808 5.628S5.894 32.22 8.654 35.753zm1.178-.92c-.915-1.172-.515-3.472 1.229-6.366 1.836-3.048 4.952-6.413 8.766-9.393 3.814-2.98 7.833-5.19 11.235-6.234 3.23-.991 5.558-.823 6.473.348.916 1.172.516 3.471-1.228 6.366-1.836 3.048-4.952 6.413-8.766 9.393-3.814 2.98-7.833 5.19-11.235 6.233-3.23.992-5.558.824-6.474-.348z" fill="#fff"/><path d="M38.714 35.753c2.76-3.532-1.973-11.39-10.252-17.858-8.28-6.468-17.049-9.16-19.808-5.628-2.76 3.532 1.973 11.39 10.252 17.858 8.28 6.469 17.049 9.16 19.808 5.628zm-1.178-.92c-.916 1.17-3.244 1.339-6.474.347-3.402-1.044-7.42-3.254-11.235-6.233-3.814-2.98-6.93-6.345-8.766-9.393-1.744-2.895-2.144-5.194-1.229-6.366.916-1.171 3.243-1.34 6.474-.348 3.402 1.044 7.42 3.254 11.235 6.234 3.814 2.98 6.93 6.345 8.766 9.393 1.744 2.894 2.144 5.194 1.228 6.365z" fill="#fff"/><path d="M23.684 27.19a3.179 3.179 0 1 0 0-6.359 3.179 3.179 0 0 0 0 6.358z" fill="#fff"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(3)" d="M0 0H41.514V48H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
packages/frameworks/logos/react.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M24 28.631a4.278 4.278 0 1 0 0-8.556 4.278 4.278 0 0 0 0 8.556z" fill="#61DAFB"/><path d="M24 33.118c12.678 0 22.956-3.924 22.956-8.765 0-4.84-10.278-8.765-22.956-8.765-12.679 0-22.957 3.924-22.957 8.765 0 4.841 10.278 8.765 22.957 8.765z" stroke="#61DAFB"/><path d="M16.409 28.736c6.34 10.98 14.877 17.918 19.07 15.498 4.191-2.42 2.451-13.284-3.888-24.264C25.25 8.99 16.714 2.053 12.52 4.473 8.33 6.892 10.07 17.756 16.41 28.736z" stroke="#61DAFB"/><path d="M16.409 19.97c-6.34 10.98-8.08 21.843-3.887 24.264 4.192 2.42 12.73-4.518 19.069-15.498 6.34-10.98 8.08-21.843 3.887-24.264-4.192-2.42-12.73 4.519-19.069 15.498z" stroke="#61DAFB"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(0 3)" d="M0 0H48V42.706H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 874 B |
4
packages/frameworks/logos/riot.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="111" height="116" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 2l2-2h73c20 0 36 16 36 36v6l-2 2H89l-2-2v-6c0-7-5-12-12-12H25l-1 2v80l-2 1C10 106 0 96 0 84V2z" fill="#ED1846"/>
|
||||
<path d="M45 48l-1 1c1 13 11 23 23 23h16c2 0 4 1 4 4v30l2 1c12-1 22-11 22-23v-8c0-16-12-28-28-28H45z" fill="#ED1846"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 332 B |
1
packages/frameworks/logos/saber.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="50" height="50" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M25 49c13.255 0 24-10.745 24-24S38.255 1 25 1 1 11.745 1 25s10.745 24 24 24z" fill="#00838F" stroke="#00838F" stroke-width=".308"/><path fill-rule="evenodd" clip-rule="evenodd" d="M19.355 28.86l6.064-.508 1.14 2.633-3.913 3.882-3.29 4.626.433 5.617c-3.218-.786-5.361-1.56-6.43-2.324-1.068-.763-2.215-1.861-3.441-3.293l5.745-6.843h2.514l1.178-3.79z" fill="#FBB526"/><path fill-rule="evenodd" clip-rule="evenodd" d="M25.36 7.404a2.993 2.993 0 0 0-1.916 5.292v4.045h3.95v-4.15a2.993 2.993 0 0 0-2.035-5.187zm-1.318 2.992a1.317 1.317 0 1 1 2.634 0 1.317 1.317 0 0 1-2.634 0z" fill="#fff"/><path d="M27.373 37.265l-2.953 2.83 1.16 1.21 2.083-1.997 1.866.978 5.01.68.225-1.661-4.718-.64-2.673-1.4z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M2.736 25C2.736 12.704 12.704 2.736 25 2.736S47.264 12.704 47.264 25 37.296 47.264 25 47.264 2.736 37.296 2.736 25zM25 4.41C13.63 4.411 4.41 13.63 4.41 25a20.51 20.51 0 0 0 5.1 13.565l5.418-7.22h3.086l.255-2.69 3.259-.618v-9.62h-3.352V16.74h14.364v1.675H29.31V30.52l2.17.222 1.761 2.328h1.629l5.653 5.457A20.51 20.51 0 0 0 45.59 25c0-11.37-9.218-20.589-20.59-20.589zm7.43 30.364l-.023-.03h-2.293v-1.676h1.024l-.556-.735-4.404-.45-.974 2.587-2.52 1.545-.875-1.43 2.03-1.243 1.225-3.257.847.086-.694-1.129-5.398 1.024-.63 6.639-2.977 2.581-1.098-1.266 2.47-2.142.271-2.86h-2.088l-5.083 6.777A20.52 20.52 0 0 0 25 45.59a20.52 20.52 0 0 0 14.37-5.846l-5.178-4.998h-1.723l-.04.03zm-7.909-7.306l-1.556.296v-9.349h4.908v11.748l-1.834-2.983-.082.016v-3.993h-1.436v4.265z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
packages/frameworks/logos/sendgrid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="24" cy="24" r="24" fill="#2A4660"/><g clip-path="url(#clip0)"><path d="M28.187 28.006h-7.993V36h7.993v-7.994zm-7.993-7.994H12.2v7.994h7.994v-7.994z" fill="#99E1F4"/><path d="M20.194 28.006H12.2V36h7.994v-7.994z" fill="#1A82E2"/><path d="M36.2 20.012h-7.994v7.994H36.2v-7.994zM28.187 12h-7.993v7.994h7.993V12z" fill="#00B2E3"/><path d="M20.194 20.012v7.994h8.012v-7.994h-8.012z" fill="#009DD9"/><path d="M36.2 12h-7.994v7.994H36.2V12z" fill="#1A82E2"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(12 12)" d="M0 0H24V24H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 659 B |
4
packages/frameworks/logos/stencil.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<circle cx="24" cy="24" r="24" fill="#000"/>
|
||||
<path fill="#fff" d="M20.27 29H32l-6.34 7H14l6.27-7zM40 21H15.45L9 27h24.55L40 21zM23.32 12H35l-6.3 7H17l6.32-7z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 248 B |
9
packages/frameworks/logos/storybook.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="39" height="48" fill="none">
|
||||
<mask id="a" width="39" height="48" x="0" y="0" maskUnits="userSpaceOnUse">
|
||||
<path fill="#fff" d="M1.48 43.97L0 4.58A2.4 2.4 0 0 1 2.25 2.1L35.75 0a2.4 2.4 0 0 1 2.55 2.4v42.92a2.4 2.4 0 0 1-2.5 2.4L3.76 46.28a2.4 2.4 0 0 1-2.29-2.3z"/>
|
||||
</mask>
|
||||
<g mask="url(#a)">
|
||||
<path fill="#FF4785" d="M1.47 43.97L-.01 4.58A2.4 2.4 0 0 1 2.24 2.1L35.74 0a2.4 2.4 0 0 1 2.55 2.4v42.92a2.4 2.4 0 0 1-2.5 2.4L3.75 46.28a2.4 2.4 0 0 1-2.3-2.3z"/>
|
||||
<path fill="#fff" d="M28.26 5.87l.23-5.5L33.1 0l.2 5.68a.36.36 0 0 1-.58.29l-1.77-1.4-2.1 1.6a.36.36 0 0 1-.58-.3zm-5.88 12.12c0 .93 6.29.48 7.13-.17 0-6.36-3.41-9.7-9.66-9.7-6.24 0-9.74 3.4-9.74 8.48 0 8.86 11.96 9.03 11.96 13.87 0 1.35-.67 2.16-2.13 2.16-1.9 0-2.66-.97-2.57-4.28 0-.72-7.26-.94-7.48 0-.57 8.01 4.43 10.33 10.14 10.33 5.54 0 9.88-2.96 9.88-8.3 0-9.5-12.14-9.24-12.14-13.95 0-1.9 1.42-2.16 2.26-2.16.89 0 2.48.15 2.35 3.72z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 980 B |
1
packages/frameworks/logos/svelte.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="47" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M39.792 6.09C35.507-.027 27.044-1.84 20.924 2.048L10.177 8.88a12.297 12.297 0 0 0-5.57 8.237 12.922 12.922 0 0 0 1.28 8.315 12.313 12.313 0 0 0-1.844 4.596c-.619 3.47.19 7.043 2.244 9.91 4.287 6.119 12.75 7.931 18.869 4.042l10.747-6.831a12.295 12.295 0 0 0 5.57-8.237 12.927 12.927 0 0 0-1.28-8.315A12.31 12.31 0 0 0 42.037 16c.619-3.47-.19-7.043-2.245-9.91" fill="#FF3E00"/><path d="M19.873 40.52a8.55 8.55 0 0 1-9.165-3.388 7.866 7.866 0 0 1-1.35-5.962c.062-.339.148-.674.257-1.001l.202-.616.55.404a13.881 13.881 0 0 0 4.206 2.095l.4.121-.037.398a2.4 2.4 0 0 0 .433 1.594 2.575 2.575 0 0 0 2.76 1.022 2.37 2.37 0 0 0 .66-.29l10.75-6.833a2.233 2.233 0 0 0 1.011-1.492 2.377 2.377 0 0 0-.407-1.797 2.577 2.577 0 0 0-2.76-1.022 2.37 2.37 0 0 0-.66.289L22.62 26.65c-.675.428-1.411.75-2.183.956a8.55 8.55 0 0 1-9.166-3.388 7.866 7.866 0 0 1-1.35-5.962 7.394 7.394 0 0 1 3.35-4.954l10.75-6.834a7.844 7.844 0 0 1 2.185-.957 8.55 8.55 0 0 1 9.165 3.388 7.866 7.866 0 0 1 1.35 5.962c-.062.34-.148.674-.256 1.001l-.203.616-.55-.403a13.87 13.87 0 0 0-4.206-2.096l-.4-.121.037-.398a2.404 2.404 0 0 0-.433-1.594 2.575 2.575 0 0 0-2.76-1.022 2.37 2.37 0 0 0-.66.29l-10.75 6.833a2.229 2.229 0 0 0-1.01 1.492c-.112.63.034 1.277.406 1.797a2.577 2.577 0 0 0 2.76 1.023c.234-.063.457-.16.661-.29l4.102-2.607a7.834 7.834 0 0 1 2.183-.957 8.55 8.55 0 0 1 9.165 3.388 7.865 7.865 0 0 1 1.35 5.962 7.398 7.398 0 0 1-3.35 4.955l-10.75 6.833a7.842 7.842 0 0 1-2.185.958" fill="#fff"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(3.84)" d="M0 0H38.4V46.08H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
1
packages/frameworks/logos/umi.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="24" cy="24" r="24" fill="#1CA1FA"/><path d="M19.77 16.09h-2.625v11.086c0 3.656 2.613 6.234 6.843 6.234 4.254 0 6.856-2.578 6.856-6.234V16.09h-2.625v10.875c0 2.414-1.535 4.113-4.23 4.113-2.684 0-4.22-1.7-4.22-4.113V16.09z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 328 B |
4
packages/frameworks/logos/vanilla.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 24C0 37.2548 10.7452 48 24 48C37.2548 48 48 37.2548 48 24C48 10.7452 37.2548 0 24 0C10.7452 0 0 10.7452 0 24Z" fill="#F7DF1E"/>
|
||||
<path d="M27.6053 28.7181C28.5722 30.2968 29.8301 31.4571 32.0549 31.4571C33.9238 31.4571 35.1177 30.523 35.1177 29.2324C35.1177 27.6857 33.8911 27.1379 31.8339 26.2381L30.7063 25.7543C27.4514 24.3676 25.2891 22.6305 25.2891 18.9581C25.2891 15.5752 27.8667 13 31.8949 13C34.7627 13 36.8244 13.9981 38.3101 16.6114L34.7977 18.8667C34.0244 17.48 33.1901 16.9337 31.8949 16.9337C30.5737 16.9337 29.7364 17.7718 29.7364 18.8667C29.7364 20.2198 30.5745 20.7676 32.5097 21.6057L33.6373 22.0888C37.4697 23.7322 39.6335 25.4076 39.6335 29.1745C39.6335 33.2354 36.4434 35.4602 32.1592 35.4602C27.9703 35.4602 25.264 33.464 23.9398 30.8476L27.6053 28.7181ZM11.6716 29.109C12.3802 30.3661 13.0248 31.429 14.5745 31.429C16.0564 31.429 16.9912 30.8491 16.9912 28.5947V13.2575H21.5017V28.6556C21.5017 33.3261 18.7634 35.4518 14.7665 35.4518C11.155 35.4518 9.06362 33.5829 8 31.3318L11.6716 29.109Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
packages/frameworks/logos/vue.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M29.54 3L24 12.7 18.456 3H-.001l24 42L47.998 3H29.54z" fill="#41B883"/><path d="M29.54 3L24 12.7 18.456 3H9.599l14.4 25.2L38.398 3H29.54z" fill="#34495E"/></g><defs><clipPath id="clip0"><path fill="#fff" transform="translate(0 3)" d="M0 0H48V42H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 385 B |
BIN
packages/frameworks/logos/vuepress.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
4
packages/frameworks/logos/zola.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
|
||||
<circle cx="24" cy="24" r="24" fill="#191919"/>
|
||||
<path fill="#fff" d="M17.65 33h12.7v-2.26H21v-.2l9.14-12.66V16.1h-12.2v2.26h8.9v.2l-9.18 12.66V33z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 237 B |
6
packages/frameworks/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "@now/frameworks",
|
||||
"version": "0.0.2",
|
||||
"main": "frameworks.json",
|
||||
"license": "UNLICENSED"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/build-utils",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import minimatch from 'minimatch';
|
||||
import { valid as validSemver } from 'semver';
|
||||
import {
|
||||
Builder,
|
||||
Config,
|
||||
BuilderFunctions,
|
||||
DetectorResult,
|
||||
DetectorOutput,
|
||||
} from './types';
|
||||
import { PackageJson, Builder, Config, BuilderFunctions } from './types';
|
||||
|
||||
interface ErrorResponse {
|
||||
code: string;
|
||||
@@ -16,6 +10,13 @@ interface ErrorResponse {
|
||||
interface Options {
|
||||
tag?: 'canary' | 'latest' | string;
|
||||
functions?: BuilderFunctions;
|
||||
ignoreBuildScript?: boolean;
|
||||
projectSettings?: {
|
||||
framework?: string | null;
|
||||
devCommand?: string | null;
|
||||
buildCommand?: string | null;
|
||||
outputDirectory?: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
// Must be a function to ensure that the returned
|
||||
@@ -33,8 +34,13 @@ function getApiBuilders({ tag }: Pick<Options, 'tag'> = {}): Builder[] {
|
||||
];
|
||||
}
|
||||
|
||||
function hasDirectory(fileName: string, files: string[]) {
|
||||
return files.some(name => name.startsWith(`${fileName}/`));
|
||||
function hasDirectory(name: string, files: string[]) {
|
||||
return files.some(file => file.startsWith(`${name}/`));
|
||||
}
|
||||
|
||||
function hasBuildScript(pkg: PackageJson | undefined | null) {
|
||||
const { scripts = {} } = pkg || {};
|
||||
return Boolean(scripts && scripts['build']);
|
||||
}
|
||||
|
||||
function getApiFunctionBuilder(
|
||||
@@ -73,48 +79,80 @@ function getApiFunctionBuilder(
|
||||
}
|
||||
|
||||
function detectFrontBuilder(
|
||||
detectorResult: Partial<DetectorOutput>,
|
||||
pkg: PackageJson | null | undefined,
|
||||
builders: Builder[],
|
||||
files: string[],
|
||||
options: Options
|
||||
): Builder {
|
||||
const { tag } = options;
|
||||
const { tag, projectSettings = {} } = options;
|
||||
const withTag = tag ? `@${tag}` : '';
|
||||
|
||||
const { framework, buildCommand, outputDirectory } = detectorResult;
|
||||
|
||||
const frameworkSlug = framework ? framework.slug : null;
|
||||
let { framework } = projectSettings;
|
||||
|
||||
const config: Config = {
|
||||
zeroConfig: true,
|
||||
};
|
||||
|
||||
if (buildCommand) {
|
||||
config.buildCommand = buildCommand;
|
||||
if (framework) {
|
||||
config.framework = framework;
|
||||
}
|
||||
|
||||
if (outputDirectory) {
|
||||
config.outputDirectory = outputDirectory;
|
||||
if (projectSettings.devCommand) {
|
||||
config.devCommand = projectSettings.devCommand;
|
||||
}
|
||||
|
||||
if (projectSettings.buildCommand) {
|
||||
config.buildCommand = projectSettings.buildCommand;
|
||||
}
|
||||
|
||||
if (projectSettings.outputDirectory) {
|
||||
config.outputDirectory = projectSettings.outputDirectory;
|
||||
}
|
||||
|
||||
if (pkg) {
|
||||
const deps: PackageJson['dependencies'] = {
|
||||
...pkg.dependencies,
|
||||
...pkg.devDependencies,
|
||||
};
|
||||
|
||||
if (deps['next']) {
|
||||
framework = 'nextjs';
|
||||
}
|
||||
}
|
||||
|
||||
// All unused functions will be used for the frontend
|
||||
if (options.functions) {
|
||||
Object.entries(options.functions).forEach(([key, func]) => {
|
||||
// When the builder is not used yet we'll use it for the frontend
|
||||
if (
|
||||
builders.every(
|
||||
b => !(b.config && b.config.functions && b.config.functions[key])
|
||||
)
|
||||
) {
|
||||
config.functions = config.functions || {};
|
||||
if (!config.functions) config.functions = {};
|
||||
config.functions[key] = { ...func };
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (frameworkSlug === 'next') {
|
||||
if (framework === 'nextjs') {
|
||||
return { src: 'package.json', use: `@now/next${withTag}`, config };
|
||||
}
|
||||
|
||||
return { src: 'package.json', use: `@now/static-build${withTag}`, config };
|
||||
// Entrypoints for other frameworks
|
||||
const entrypoints = new Set([
|
||||
'package.json',
|
||||
'config.yaml',
|
||||
'config.toml',
|
||||
'config.json',
|
||||
'_config.yml',
|
||||
'config.yml',
|
||||
'config.rb',
|
||||
]);
|
||||
|
||||
const source = pkg
|
||||
? 'package.json'
|
||||
: files.find(file => entrypoints.has(file)) || 'package.json';
|
||||
|
||||
return { src: source, use: `@now/static-build${withTag}`, config };
|
||||
}
|
||||
|
||||
// Files that match a specific pattern will get ignored
|
||||
@@ -215,9 +253,7 @@ function checkUnusedFunctionsOnFrontendBuilder(
|
||||
) {
|
||||
return {
|
||||
code: 'unused_function',
|
||||
message:
|
||||
`The function for "${matchedFile}" can't be handled by any runtime. ` +
|
||||
`Please provide one with the "runtime" option.`,
|
||||
message: `The function for ${matchedFile} can't be handled by any builder`,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -324,7 +360,7 @@ function validateFunctions(files: string[], { functions = {} }: Options) {
|
||||
// to determine what builders to use
|
||||
export async function detectBuilders(
|
||||
files: string[],
|
||||
detectorResult: Partial<DetectorResult> | null = null,
|
||||
pkg?: PackageJson | undefined | null,
|
||||
options: Options = {}
|
||||
): Promise<{
|
||||
builders: Builder[] | null;
|
||||
@@ -346,13 +382,11 @@ export async function detectBuilders(
|
||||
|
||||
// Detect all builders for the `api` directory before anything else
|
||||
const builders = detectApiBuilders(files, options);
|
||||
const { projectSettings = {} } = options;
|
||||
const { outputDirectory, buildCommand, framework } = projectSettings;
|
||||
|
||||
if (detectorResult && detectorResult.buildCommand) {
|
||||
const frontendBuilder = detectFrontBuilder(
|
||||
detectorResult,
|
||||
builders,
|
||||
options
|
||||
);
|
||||
if (hasBuildScript(pkg) || buildCommand || framework) {
|
||||
const frontendBuilder = detectFrontBuilder(pkg, builders, files, options);
|
||||
builders.push(frontendBuilder);
|
||||
|
||||
const conflictError = checkConflictingFiles(files, builders);
|
||||
@@ -373,35 +407,46 @@ export async function detectBuilders(
|
||||
warnings,
|
||||
};
|
||||
}
|
||||
} else if (
|
||||
detectorResult &&
|
||||
detectorResult.outputDirectory &&
|
||||
hasDirectory(detectorResult.outputDirectory, files)
|
||||
) {
|
||||
builders.push({
|
||||
use: '@now/static',
|
||||
src: [...detectorResult.outputDirectory.split('/'), '**', '*']
|
||||
.filter(Boolean)
|
||||
.join('/'),
|
||||
config: { zeroConfig: true },
|
||||
});
|
||||
} else if (hasDirectory('public', files)) {
|
||||
builders.push({
|
||||
use: '@now/static',
|
||||
src: 'public/**/*',
|
||||
config: { zeroConfig: true },
|
||||
});
|
||||
} else if (
|
||||
builders.length > 0 &&
|
||||
files.some(f => !f.startsWith('api/') && f !== 'package.json')
|
||||
) {
|
||||
// Everything besides the api directory
|
||||
// and package.json can be served as static files
|
||||
builders.push({
|
||||
use: '@now/static',
|
||||
src: '!{api/**,package.json}',
|
||||
config: { zeroConfig: true },
|
||||
});
|
||||
} else {
|
||||
if (!options.ignoreBuildScript && pkg && builders.length === 0) {
|
||||
// We only show this error when there are no api builders
|
||||
// since the dependencies of the pkg could be used for those
|
||||
errors.push({
|
||||
code: 'missing_build_script',
|
||||
message:
|
||||
'Your `package.json` file is missing a `build` property inside the `scripts` property.' +
|
||||
'\nMore details: https://zeit.co/docs/v2/platform/frequently-asked-questions#missing-build-script',
|
||||
});
|
||||
return { errors, warnings, builders: null };
|
||||
}
|
||||
|
||||
// We allow a `public` directory
|
||||
// when there are no build steps
|
||||
const outDir = outputDirectory || 'public';
|
||||
|
||||
if (hasDirectory(outDir, files)) {
|
||||
builders.push({
|
||||
use: '@now/static',
|
||||
src: `${outDir}/**/*`,
|
||||
config: {
|
||||
zeroConfig: true,
|
||||
outputDirectory: outDir,
|
||||
},
|
||||
});
|
||||
} else if (
|
||||
builders.length > 0 &&
|
||||
files.some(f => !f.startsWith('api/') && f !== 'package.json')
|
||||
) {
|
||||
// Everything besides the api directory
|
||||
// and package.json can be served as static files
|
||||
builders.push({
|
||||
use: '@now/static',
|
||||
src: '!{api/**,package.json}',
|
||||
config: {
|
||||
zeroConfig: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
81
packages/now-build-utils/src/detect-framework.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { Framework, FrameworkDetectionItem } from '@now/frameworks';
|
||||
import { DetectorFilesystem } from './detectors/filesystem';
|
||||
|
||||
export interface DetectFrameworkOptions {
|
||||
fs: DetectorFilesystem;
|
||||
frameworkList: Framework[];
|
||||
}
|
||||
|
||||
async function matches(fs: DetectorFilesystem, framework: Framework) {
|
||||
const { detectors } = framework;
|
||||
|
||||
if (!detectors) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { every, some } = detectors;
|
||||
|
||||
if (every !== undefined && !Array.isArray(every)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (some !== undefined && !Array.isArray(some)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const check = async ({ file, matchContent }: FrameworkDetectionItem) => {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((await fs.exists(file)) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matchContent) {
|
||||
const regex = new RegExp(matchContent, 'gm');
|
||||
const content = await fs.readFile(file);
|
||||
|
||||
if (!regex.test(content.toString())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const result: boolean[] = [];
|
||||
|
||||
if (every) {
|
||||
const everyResult = await Promise.all(every.map(item => check(item)));
|
||||
result.push(...everyResult);
|
||||
}
|
||||
|
||||
if (some) {
|
||||
let someResult = false;
|
||||
|
||||
for (const item of some) {
|
||||
if (await check(item)) {
|
||||
someResult = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.push(someResult);
|
||||
}
|
||||
|
||||
return result.every(res => res === true);
|
||||
}
|
||||
|
||||
export async function detectFramework({
|
||||
fs,
|
||||
frameworkList,
|
||||
}: DetectFrameworkOptions): Promise<string | null> {
|
||||
for (const framework of frameworkList) {
|
||||
if (await matches(fs, framework)) {
|
||||
return framework.slug;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { parse as parsePath } from 'path';
|
||||
import { Route, Builder } from './types';
|
||||
import { Route, isHandler } from '@now/routing-utils';
|
||||
import { Builder } from './types';
|
||||
import { getIgnoreApiFilter, sortFiles } from './detect-builders';
|
||||
|
||||
function escapeName(name: string) {
|
||||
@@ -199,7 +200,8 @@ interface RoutesResult {
|
||||
|
||||
async function detectApiRoutes(
|
||||
files: string[],
|
||||
builders: Builder[]
|
||||
builders: Builder[],
|
||||
featHandleMiss: boolean
|
||||
): Promise<RoutesResult> {
|
||||
if (!files || files.length === 0) {
|
||||
return { defaultRoutes: null, error: null };
|
||||
@@ -212,14 +214,14 @@ async function detectApiRoutes(
|
||||
.sort(sortFiles)
|
||||
.sort(sortFilesBySegmentCount);
|
||||
|
||||
const defaultRoutes: Route[] = [];
|
||||
let defaultRoutes: Route[] = [];
|
||||
|
||||
for (const file of sortedFiles) {
|
||||
// We only consider every file in the api directory
|
||||
// as we will strip extensions as well as resolving "[segments]"
|
||||
if (
|
||||
!file.startsWith('api/') &&
|
||||
!builders.some(b => b.src === file && b.config!.functions)
|
||||
!builders.some(b => b.src === file && b.config && b.config.functions)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@@ -264,11 +266,32 @@ async function detectApiRoutes(
|
||||
}
|
||||
|
||||
// 404 Route to disable directory listing
|
||||
if (defaultRoutes.length) {
|
||||
defaultRoutes.push({
|
||||
status: 404,
|
||||
src: '/api(\\/.*)?$',
|
||||
});
|
||||
if (defaultRoutes.length > 0) {
|
||||
if (featHandleMiss) {
|
||||
defaultRoutes = [
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
src: '/api/(.+)\\.\\w+',
|
||||
dest: '/api/$1',
|
||||
check: true,
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '/api(/.*)?$',
|
||||
continue: true,
|
||||
},
|
||||
];
|
||||
} else if (
|
||||
defaultRoutes.some(
|
||||
route =>
|
||||
!isHandler(route) && route.dest && route.dest.startsWith('/api/')
|
||||
)
|
||||
) {
|
||||
defaultRoutes.push({
|
||||
status: 404,
|
||||
src: '/api(/.*)?$',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { defaultRoutes, error: null };
|
||||
@@ -286,16 +309,22 @@ function getPublicBuilder(builders: Builder[]): Builder | null {
|
||||
return builder || null;
|
||||
}
|
||||
|
||||
export function detectOutputDirectory(builders: Builder[]): string | null {
|
||||
// TODO: We eventually want to save the output directory to
|
||||
// builder.config.outputDirectory so it is only detected once
|
||||
const publicBuilder = getPublicBuilder(builders);
|
||||
return publicBuilder ? publicBuilder.src.replace('/**/*', '') : null;
|
||||
}
|
||||
|
||||
export async function detectRoutes(
|
||||
files: string[],
|
||||
builders: Builder[]
|
||||
builders: Builder[],
|
||||
featHandleMiss = false
|
||||
): Promise<RoutesResult> {
|
||||
const routesResult = await detectApiRoutes(files, builders);
|
||||
const publicBuilder = getPublicBuilder(builders);
|
||||
|
||||
if (routesResult.defaultRoutes && publicBuilder) {
|
||||
const directory = publicBuilder.src.replace('/**/*', '');
|
||||
const routesResult = await detectApiRoutes(files, builders, featHandleMiss);
|
||||
const directory = detectOutputDirectory(builders);
|
||||
|
||||
if (routesResult.defaultRoutes && directory && !featHandleMiss) {
|
||||
routesResult.defaultRoutes.push({
|
||||
src: '/(.*)',
|
||||
dest: `/${directory}/$1`,
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectAngular({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('@angular/cli');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'ng build',
|
||||
outputDirectory: 'dist',
|
||||
devCommand: 'ng serve --port $PORT',
|
||||
framework: {
|
||||
slug: '@angular/cli',
|
||||
version,
|
||||
},
|
||||
minNodeRange: '10.x',
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectBrunch({
|
||||
fs: { exists, getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('brunch');
|
||||
if (!version) return false;
|
||||
|
||||
const hasConfig = await exists('brunch-config.js');
|
||||
if (!hasConfig) return false;
|
||||
|
||||
return {
|
||||
buildCommand:
|
||||
(await getPackageJsonBuildCommand()) || 'brunch build --production',
|
||||
outputDirectory: 'public',
|
||||
devCommand: 'brunch watch --server --port $PORT',
|
||||
framework: {
|
||||
slug: 'brunch',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectCreateReactAppEjected({
|
||||
fs: { getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('react-dev-utils');
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
buildCommand: 'node scripts/build.js',
|
||||
outputDirectory: 'build',
|
||||
devCommand: 'node scripts/start.js',
|
||||
framework: {
|
||||
slug: 'react-dev-utils',
|
||||
version,
|
||||
},
|
||||
devVariables: { BROWSER: 'none' },
|
||||
routes: [
|
||||
{
|
||||
src: '/static/(.*)',
|
||||
headers: { 'cache-control': 's-maxage=31536000, immutable' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
src: '/service-worker.js',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
src: '/sockjs-node/(.*)',
|
||||
dest: '/sockjs-node/$1',
|
||||
},
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectCreateReactApp({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('react-scripts');
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'react-scripts build',
|
||||
outputDirectory: 'build',
|
||||
devCommand: 'react-scripts start',
|
||||
devVariables: { BROWSER: 'none' },
|
||||
framework: {
|
||||
slug: 'react-scripts',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
src: '/static/(.*)',
|
||||
headers: { 'cache-control': 's-maxage=31536000, immutable' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
src: '/service-worker.js',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
src: '/sockjs-node/(.*)',
|
||||
dest: '/sockjs-node/$1',
|
||||
},
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectDocusaurus({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('docusaurus');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'docusaurus-build',
|
||||
outputDirectory: 'build',
|
||||
devCommand: 'docusaurus-start --port $PORT',
|
||||
framework: {
|
||||
slug: 'docusaurus',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectEleventy({
|
||||
fs: { getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('@11ty/eleventy');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: 'npx @11ty/eleventy',
|
||||
outputDirectory: '_site',
|
||||
devCommand: 'npx @11ty/eleventy --serve --watch --port $PORT',
|
||||
framework: {
|
||||
slug: '@11ty/eleventy',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectEmber({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('ember-cli');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'ember build',
|
||||
outputDirectory: 'dist',
|
||||
devCommand: 'ember serve --port $PORT',
|
||||
framework: {
|
||||
slug: 'ember-cli',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
import yaml from 'js-yaml';
|
||||
import toml from '@iarna/toml';
|
||||
import { PackageJson } from '../types';
|
||||
|
||||
/**
|
||||
* `DetectorFilesystem` is an abstract class that represents a virtual filesystem
|
||||
* to perform read-only operations on in order to detect which framework is being
|
||||
@@ -27,18 +23,16 @@ import { PackageJson } from '../types';
|
||||
* functions. The easiest way to do this is to use the `=` syntax when defining
|
||||
* methods in this class definition.
|
||||
*/
|
||||
export default abstract class DetectorFilesystem {
|
||||
export abstract class DetectorFilesystem {
|
||||
protected abstract _readFile(name: string): Promise<Buffer>;
|
||||
protected abstract _exists(name: string): Promise<boolean>;
|
||||
|
||||
private existsCache: Map<string, Promise<boolean>>;
|
||||
private readFileCache: Map<string, Promise<Buffer>>;
|
||||
private readJsonCache: Map<string, Promise<any>>;
|
||||
|
||||
constructor() {
|
||||
this.existsCache = new Map();
|
||||
this.readFileCache = new Map();
|
||||
this.readJsonCache = new Map();
|
||||
}
|
||||
|
||||
public exists = async (name: string): Promise<boolean> => {
|
||||
@@ -58,84 +52,4 @@ export default abstract class DetectorFilesystem {
|
||||
}
|
||||
return p;
|
||||
};
|
||||
|
||||
public readJson = async <T>(name: string): Promise<T> => {
|
||||
let p = this.readJsonCache.get(name);
|
||||
if (!p) {
|
||||
p = this.readFile(name).then(d => JSON.parse(d.toString('utf8')));
|
||||
this.readJsonCache.set(name, p);
|
||||
}
|
||||
return p;
|
||||
};
|
||||
|
||||
public readFileOrNull = async (name: string): Promise<Buffer | null> => {
|
||||
return nullEnoent(this.readFile(name));
|
||||
};
|
||||
|
||||
public readJsonOrNull = async <T>(name: string): Promise<T | null> => {
|
||||
return nullEnoent(this.readJson<T>(name));
|
||||
};
|
||||
|
||||
public readPackageJson = async (): Promise<PackageJson | null> => {
|
||||
return await this.readJsonOrNull<PackageJson>('package.json');
|
||||
};
|
||||
|
||||
public readConfigFile = async <T>(...names: string[]): Promise<T | null> => {
|
||||
for (const name of names) {
|
||||
const data = await this.readFileOrNull(name);
|
||||
if (data) {
|
||||
const str = data.toString('utf8');
|
||||
if (name.endsWith('.json')) {
|
||||
return JSON.parse(str);
|
||||
} else if (name.endsWith('.toml')) {
|
||||
return (toml.parse(str) as unknown) as T;
|
||||
} else if (name.endsWith('.yaml') || name.endsWith('.yml')) {
|
||||
return yaml.safeLoad(str, { filename: name });
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
public hasDependency = async (name: string): Promise<boolean> => {
|
||||
const pkg = await this.readPackageJson();
|
||||
const { dependencies = {}, devDependencies = {} } = pkg || {};
|
||||
return name in dependencies || name in devDependencies;
|
||||
};
|
||||
|
||||
public isNpm = async (): Promise<boolean> => {
|
||||
return this.exists('package-lock.json');
|
||||
};
|
||||
|
||||
public getPackageJsonCommand = async (
|
||||
name: string
|
||||
): Promise<string | null> => {
|
||||
const pkg = await this.readPackageJson();
|
||||
const { scripts = {} } = pkg || {};
|
||||
return scripts[name] || null;
|
||||
};
|
||||
|
||||
public getPackageJsonBuildCommand = async (): Promise<string | null> => {
|
||||
const buildCommand = (await this.isNpm())
|
||||
? 'npm run build'
|
||||
: 'yarn run build';
|
||||
return (await this.getPackageJsonCommand('build')) ? buildCommand : null;
|
||||
};
|
||||
|
||||
public getDependencyVersion = async (name: string): Promise<string> => {
|
||||
const pkg = await this.readPackageJson();
|
||||
const { dependencies = {}, devDependencies = {} } = pkg || {};
|
||||
return dependencies[name] || devDependencies[name];
|
||||
};
|
||||
}
|
||||
|
||||
async function nullEnoent<T>(p: Promise<T>): Promise<T | null> {
|
||||
try {
|
||||
return await p;
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return null;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectGatsby({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('gatsby');
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'gatsby build',
|
||||
outputDirectory: 'public',
|
||||
devCommand: 'gatsby develop -p $PORT',
|
||||
framework: {
|
||||
slug: 'gatsby',
|
||||
version,
|
||||
},
|
||||
cachePattern: '.cache/**',
|
||||
};
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectGenericNodeProject({
|
||||
fs: { isNpm, getPackageJsonCommand },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const useNpm = await isNpm();
|
||||
const devCommand = await getPackageJsonCommand('dev');
|
||||
const buildCommand = await getPackageJsonCommand('build');
|
||||
|
||||
if (!buildCommand) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
buildCommand: `${useNpm ? 'npm' : 'yarn'} run build`,
|
||||
devCommand: `${useNpm ? 'npm' : 'yarn'} run ${
|
||||
devCommand ? 'dev' : 'build'
|
||||
}`,
|
||||
outputDirectory: 'public',
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectGridsome({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('gridsome');
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'gridsome build',
|
||||
outputDirectory: 'dist',
|
||||
devCommand: 'gridsome develop -p $PORT',
|
||||
framework: {
|
||||
slug: 'gridsom',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectHexo({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('hexo');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'hexo generate',
|
||||
outputDirectory: 'public',
|
||||
devCommand: 'hexo server --port $PORT',
|
||||
framework: {
|
||||
slug: 'hexo',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
/**
|
||||
* https://gohugo.io/getting-started/configuration/#configuration-file
|
||||
*/
|
||||
interface HugoConfig {
|
||||
publishDir?: string;
|
||||
}
|
||||
|
||||
export default async function detectHugo({
|
||||
fs: { readConfigFile },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const config = await readConfigFile<HugoConfig>(
|
||||
'config.toml',
|
||||
'config.yaml',
|
||||
'config.json'
|
||||
);
|
||||
if (!config) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
buildCommand: 'hugo',
|
||||
outputDirectory: config.publishDir || 'public',
|
||||
devCommand: 'hugo server -D -w -p $PORT',
|
||||
framework: {
|
||||
slug: 'hugo',
|
||||
version: 'latest',
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
import AggregateError from 'aggregate-error';
|
||||
import { Detector, DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
import angular from './angular';
|
||||
import brunch from './brunch';
|
||||
import createReactApp from './create-react-app';
|
||||
import createReactAppEjected from './create-react-app-ejected';
|
||||
import docusaurus from './docusaurus';
|
||||
import eleventy from './eleventy';
|
||||
import ember from './ember';
|
||||
import gatsby from './gatsby';
|
||||
import genericNodeProject from './generic-node-project';
|
||||
import gridsome from './gridsome';
|
||||
import hexo from './hexo';
|
||||
import hugo from './hugo';
|
||||
import jekyll from './jekyll';
|
||||
import middleman from './middleman';
|
||||
import next from './next';
|
||||
import polymer from './polymer';
|
||||
import preact from './preact';
|
||||
import saber from './saber';
|
||||
import sapper from './sapper';
|
||||
import stencil from './stencil';
|
||||
import svelte from './svelte';
|
||||
import umi from './umi';
|
||||
import vue from './vue';
|
||||
|
||||
export const pkgDetectors: Detector[] = [
|
||||
angular,
|
||||
brunch,
|
||||
createReactApp,
|
||||
createReactAppEjected,
|
||||
docusaurus,
|
||||
eleventy,
|
||||
ember,
|
||||
gatsby,
|
||||
gridsome,
|
||||
hexo,
|
||||
next,
|
||||
polymer,
|
||||
preact,
|
||||
saber,
|
||||
sapper,
|
||||
stencil,
|
||||
svelte,
|
||||
umi,
|
||||
vue,
|
||||
];
|
||||
|
||||
export const detectors: Detector[] = [hugo, jekyll, middleman];
|
||||
|
||||
export function firstTruthy<T>(promises: Promise<T>[]) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const errors: Array<Error> = [];
|
||||
let unresolved = promises.length;
|
||||
for (const p of promises) {
|
||||
p.then(v => {
|
||||
if (v || --unresolved === 0) {
|
||||
resolve(v);
|
||||
}
|
||||
}).catch(err => {
|
||||
errors.push(err);
|
||||
if (--unresolved === 0) {
|
||||
reject(new AggregateError(errors));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function detectDefaults(
|
||||
params: DetectorParameters
|
||||
): Promise<DetectorResult> {
|
||||
// The `package.json` detectors are run first, since they share the common
|
||||
// file read of `package.json` and are the most popular frameworks
|
||||
let d: Detector[] = params.pkgDetectors || pkgDetectors;
|
||||
let result: DetectorResult = await firstTruthy(
|
||||
d.map(detector => detector(params))
|
||||
);
|
||||
if (!result) {
|
||||
// If no `package.json` framework was detected then check the non-pkg ones
|
||||
d = params.detectors || detectors;
|
||||
result = await firstTruthy(d.map(detector => detector(params)));
|
||||
}
|
||||
if (!result) {
|
||||
result = await genericNodeProject(params);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
/**
|
||||
* https://jekyllrb.com/docs/configuration/options/
|
||||
*/
|
||||
interface JekyllConfig {
|
||||
destination?: string;
|
||||
}
|
||||
|
||||
export default async function detectJekyll({
|
||||
fs: { readConfigFile },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const config = await readConfigFile<JekyllConfig>('_config.yml');
|
||||
if (!config) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
buildCommand: 'jekyll build',
|
||||
outputDirectory: config.destination || '_site',
|
||||
devCommand: 'bundle exec jekyll serve --watch --port $PORT',
|
||||
framework: {
|
||||
slug: 'jekyll',
|
||||
version: 'latest',
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectMiddleman({
|
||||
fs: { exists },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const hasConfig = await exists('config.rb');
|
||||
if (!hasConfig) return false;
|
||||
|
||||
return {
|
||||
buildCommand: 'bundle exec middleman build',
|
||||
outputDirectory: 'build',
|
||||
devCommand: 'bundle exec middleman server -p $PORT',
|
||||
framework: {
|
||||
slug: 'middleman',
|
||||
version: 'latest',
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectNext({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('next');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'next build',
|
||||
outputDirectory: '.next/static',
|
||||
devCommand: 'next -p $PORT',
|
||||
framework: {
|
||||
slug: 'next',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectPolymer({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('polymer-cli');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'polymer build',
|
||||
outputDirectory: 'build',
|
||||
devCommand: 'polymer serve --port $PORT',
|
||||
framework: {
|
||||
slug: 'polymer-cli',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectPreact({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('preact-cli');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'preact build',
|
||||
outputDirectory: 'build',
|
||||
devCommand: 'preact watch --port $PORT',
|
||||
framework: {
|
||||
slug: 'preact-cli',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectSaber({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('saber');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'saber build',
|
||||
outputDirectory: 'public',
|
||||
devCommand: 'saber --port $PORT',
|
||||
routes: [
|
||||
{
|
||||
src: '/_saber/.*',
|
||||
headers: { 'cache-control': 'max-age=31536000, immutable' },
|
||||
},
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '.*',
|
||||
status: 404,
|
||||
dest: '404.html',
|
||||
},
|
||||
],
|
||||
framework: {
|
||||
slug: 'saber',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectSapper({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('sapper');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'sapper export',
|
||||
outputDirectory: '__sapper__/export',
|
||||
devCommand: 'sapper dev --port $PORT',
|
||||
framework: {
|
||||
slug: 'sapper',
|
||||
version,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectStencil({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('@stencil/core');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'stencil build',
|
||||
outputDirectory: 'www',
|
||||
devCommand: 'stencil build --dev --watch --serve --port $PORT',
|
||||
framework: {
|
||||
slug: '@stencil/core',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectSvelte({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('sirv-cli');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'rollup -c',
|
||||
outputDirectory: 'public',
|
||||
devCommand: 'sirv public --single --dev --port $PORT',
|
||||
framework: {
|
||||
slug: 'sirv-cli',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectUmiJS({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('umi');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand: (await getPackageJsonBuildCommand()) || 'umi build',
|
||||
outputDirectory: 'dist',
|
||||
devCommand: 'umi dev --port $PORT',
|
||||
framework: {
|
||||
slug: 'umi',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { DetectorParameters, DetectorResult } from '../types';
|
||||
|
||||
export default async function detectVue({
|
||||
fs: { getPackageJsonBuildCommand, getDependencyVersion },
|
||||
}: DetectorParameters): Promise<DetectorResult> {
|
||||
const version = await getDependencyVersion('@vue/cli-service');
|
||||
if (!version) return false;
|
||||
return {
|
||||
buildCommand:
|
||||
(await getPackageJsonBuildCommand()) || 'vue-cli-service build',
|
||||
outputDirectory: 'dist',
|
||||
devCommand: 'vue-cli-service serve --port $PORT',
|
||||
framework: {
|
||||
slug: '@vue/cli-service',
|
||||
version,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
src: '^/[^/]*\\.(js|txt|ico|json)',
|
||||
headers: { 'cache-control': 'max-age=300' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
src: '^/(img|js|css|fonts|media)/.*',
|
||||
headers: { 'cache-control': 'max-age=31536000, immutable' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '^.*',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -16,17 +16,19 @@ const allOptions: NodeVersion[] = [
|
||||
|
||||
const supportedOptions = allOptions.filter(o => !isDiscontinued(o));
|
||||
|
||||
// This version should match Fargate's default in the PATH
|
||||
// Today that is Node 8
|
||||
export const defaultSelection = supportedOptions.find(
|
||||
o => o.major === 8
|
||||
) as NodeVersion;
|
||||
export function getOldestNodeVersion(): NodeVersion {
|
||||
return allOptions[allOptions.length - 1];
|
||||
}
|
||||
|
||||
export function getLatestNodeVersion(): NodeVersion {
|
||||
return allOptions[0];
|
||||
}
|
||||
|
||||
export async function getSupportedNodeVersion(
|
||||
engineRange?: string,
|
||||
silent?: boolean
|
||||
): Promise<NodeVersion> {
|
||||
let selection = defaultSelection;
|
||||
let selection = getOldestNodeVersion();
|
||||
|
||||
if (!engineRange) {
|
||||
if (!silent) {
|
||||
|
||||
37
packages/now-build-utils/src/fs/read-config-file.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import yaml from 'js-yaml';
|
||||
import toml from '@iarna/toml';
|
||||
import { readFile } from 'fs-extra';
|
||||
|
||||
async function readFileOrNull(file: string) {
|
||||
try {
|
||||
const data = await readFile(file);
|
||||
return data;
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function readConfigFile<T>(files: string | string[]) {
|
||||
files = Array.isArray(files) ? files : [files];
|
||||
|
||||
for (const name of files) {
|
||||
const data = await readFileOrNull(name);
|
||||
|
||||
if (data) {
|
||||
const str = data.toString('utf8');
|
||||
if (name.endsWith('.json')) {
|
||||
return JSON.parse(str);
|
||||
} else if (name.endsWith('.toml')) {
|
||||
return (toml.parse(str) as unknown) as T;
|
||||
} else if (name.endsWith('.yaml') || name.endsWith('.yml')) {
|
||||
return yaml.safeLoad(str, { filename: name });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -39,6 +39,66 @@ export function spawnAsync(
|
||||
});
|
||||
}
|
||||
|
||||
export function execAsync(
|
||||
command: string,
|
||||
args: string[],
|
||||
opts: SpawnOptions = {}
|
||||
) {
|
||||
return new Promise<{ stdout: string; stderr: string; code: number }>(
|
||||
(resolve, reject) => {
|
||||
opts.stdio = 'pipe';
|
||||
|
||||
const stdoutList: Buffer[] = [];
|
||||
const stderrList: Buffer[] = [];
|
||||
|
||||
const child = spawn(command, args, opts);
|
||||
|
||||
child.stderr!.on('data', data => {
|
||||
stderrList.push(data);
|
||||
});
|
||||
|
||||
child.stdout!.on('data', data => {
|
||||
stdoutList.push(data);
|
||||
});
|
||||
|
||||
child.on('error', reject);
|
||||
child.on('close', (code, signal) => {
|
||||
if (code !== 0) {
|
||||
return reject(
|
||||
new Error(
|
||||
`Program "${command}" exited with non-zero exit code ${code} ${signal}.`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return resolve({
|
||||
code,
|
||||
stdout: Buffer.concat(stdoutList).toString(),
|
||||
stderr: Buffer.concat(stderrList).toString(),
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function spawnCommand(command: string, options: SpawnOptions = {}) {
|
||||
if (process.platform === 'win32') {
|
||||
return spawn('cmd.exe', ['/C', command], options);
|
||||
}
|
||||
|
||||
return spawn('sh', ['-c', command], options);
|
||||
}
|
||||
|
||||
export async function execCommand(command: string, options: SpawnOptions = {}) {
|
||||
if (process.platform === 'win32') {
|
||||
await spawnAsync('cmd.exe', ['/C', command], options);
|
||||
} else {
|
||||
await spawnAsync('sh', ['-c', command], options);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async function chmodPlusX(fsPath: string) {
|
||||
const s = await fs.stat(fsPath);
|
||||
const newMode = s.mode | 64 | 8 | 1; // eslint-disable-line no-bitwise
|
||||
@@ -90,8 +150,10 @@ export async function getNodeVersion(
|
||||
} else if (minNodeVersion) {
|
||||
range = minNodeVersion;
|
||||
silent = true;
|
||||
} else if (config && config.nodeVersion) {
|
||||
range = config.nodeVersion;
|
||||
silent = true;
|
||||
} else if (config && config.zeroConfig) {
|
||||
// Use latest node version zero config detected
|
||||
range = '10.x';
|
||||
silent = true;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@ import getWriteableDirectory from './fs/get-writable-directory';
|
||||
import glob from './fs/glob';
|
||||
import rename from './fs/rename';
|
||||
import {
|
||||
execAsync,
|
||||
spawnAsync,
|
||||
execCommand,
|
||||
spawnCommand,
|
||||
installDependencies,
|
||||
runPackageJsonScript,
|
||||
runNpmInstall,
|
||||
@@ -18,11 +21,9 @@ import {
|
||||
getNodeVersion,
|
||||
getSpawnOptions,
|
||||
} from './fs/run-user-scripts';
|
||||
import { getLatestNodeVersion } from './fs/node-version';
|
||||
import streamToBuffer from './fs/stream-to-buffer';
|
||||
import shouldServe from './should-serve';
|
||||
import { detectBuilders } from './detect-builders';
|
||||
import { detectRoutes } from './detect-routes';
|
||||
import DetectorFilesystem from './detectors/filesystem';
|
||||
import debug from './debug';
|
||||
|
||||
export {
|
||||
@@ -30,7 +31,6 @@ export {
|
||||
FileFsRef,
|
||||
FileRef,
|
||||
Lambda,
|
||||
DetectorFilesystem,
|
||||
createLambda,
|
||||
Prerender,
|
||||
download,
|
||||
@@ -38,24 +38,31 @@ export {
|
||||
getWriteableDirectory,
|
||||
glob,
|
||||
rename,
|
||||
execAsync,
|
||||
spawnAsync,
|
||||
installDependencies,
|
||||
runPackageJsonScript,
|
||||
execCommand,
|
||||
spawnCommand,
|
||||
runNpmInstall,
|
||||
runBundleInstall,
|
||||
runPipInstall,
|
||||
runShellScript,
|
||||
getNodeVersion,
|
||||
getLatestNodeVersion,
|
||||
getSpawnOptions,
|
||||
streamToBuffer,
|
||||
shouldServe,
|
||||
detectBuilders,
|
||||
detectRoutes,
|
||||
debug,
|
||||
isSymbolicLink,
|
||||
getLambdaOptionsFromFunction,
|
||||
};
|
||||
|
||||
export { detectDefaults } from './detectors';
|
||||
export { detectRoutes, detectOutputDirectory } from './detect-routes';
|
||||
export { detectBuilders } from './detect-builders';
|
||||
export { detectFramework } from './detect-framework';
|
||||
export { DetectorFilesystem } from './detectors/filesystem';
|
||||
export { readConfigFile } from './fs/read-config-file';
|
||||
|
||||
export * from './schemas';
|
||||
export * from './types';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import FileRef from './file-ref';
|
||||
import FileFsRef from './file-fs-ref';
|
||||
import DetectorFilesystem from './detectors/filesystem';
|
||||
|
||||
export interface Env {
|
||||
[name: string]: string | undefined;
|
||||
@@ -21,18 +20,6 @@ export interface Files {
|
||||
[filePath: string]: File;
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
src?: string;
|
||||
dest?: string;
|
||||
handle?: string;
|
||||
type?: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
continue?: boolean;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
[key: string]:
|
||||
| string
|
||||
@@ -52,6 +39,11 @@ export interface Config {
|
||||
zeroConfig?: boolean;
|
||||
import?: { [key: string]: string };
|
||||
functions?: BuilderFunctions;
|
||||
outputDirectory?: string;
|
||||
buildCommand?: string;
|
||||
devCommand?: string;
|
||||
framework?: string;
|
||||
nodeVersion?: string;
|
||||
}
|
||||
|
||||
export interface Meta {
|
||||
@@ -343,33 +335,3 @@ export interface NowHeaderKeyValue {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type Detector = (params: DetectorParameters) => Promise<DetectorResult>;
|
||||
|
||||
export interface DetectorParameters {
|
||||
fs: DetectorFilesystem;
|
||||
detectors?: Detector[];
|
||||
pkgDetectors?: Detector[];
|
||||
}
|
||||
|
||||
export interface DetectorOutput {
|
||||
buildCommand: string;
|
||||
outputDirectory: string;
|
||||
buildVariables?: Env;
|
||||
devCommand?: string;
|
||||
devVariables?: Env;
|
||||
minNodeRange?: string;
|
||||
cachePattern?: string;
|
||||
routes?: Route[];
|
||||
cleanUrls?: boolean;
|
||||
rewrites?: NowRewrite[];
|
||||
redirects?: NowRedirect[];
|
||||
headers?: NowHeader[];
|
||||
trailingSlash?: boolean;
|
||||
framework?: {
|
||||
slug: string;
|
||||
version: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type DetectorResult = DetectorOutput | false;
|
||||
|
||||
@@ -4,34 +4,13 @@ const {
|
||||
packAndDeploy,
|
||||
testDeployment,
|
||||
} = require('../../../test/lib/deployment/test-deployment');
|
||||
const {
|
||||
glob,
|
||||
detectBuilders,
|
||||
detectRoutes,
|
||||
DetectorFilesystem,
|
||||
detectDefaults,
|
||||
} = require('../');
|
||||
const { glob, detectBuilders, detectRoutes } = require('../');
|
||||
|
||||
jest.setTimeout(4 * 60 * 1000);
|
||||
|
||||
const builderUrl = '@canary';
|
||||
let buildUtilsUrl;
|
||||
|
||||
class LocalFilesystem extends DetectorFilesystem {
|
||||
constructor(dir) {
|
||||
super();
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
_exists(name) {
|
||||
return fs.pathExists(path.join(this.dir, name));
|
||||
}
|
||||
|
||||
_readFile(name) {
|
||||
return fs.readFile(path.join(this.dir, name));
|
||||
}
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const buildUtilsPath = path.resolve(__dirname, '..');
|
||||
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
|
||||
@@ -88,9 +67,7 @@ for (const builder of buildersToTestWith) {
|
||||
|
||||
it('Test `detectBuilders` and `detectRoutes`', async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', '01-zero-config-api');
|
||||
const detectorResult = await detectDefaults({
|
||||
fs: new LocalFilesystem(fixture),
|
||||
});
|
||||
const pkg = await fs.readJSON(path.join(fixture, 'package.json'));
|
||||
const fileList = await glob('**', fixture);
|
||||
const files = Object.keys(fileList);
|
||||
|
||||
@@ -133,7 +110,7 @@ it('Test `detectBuilders` and `detectRoutes`', async () => {
|
||||
},
|
||||
];
|
||||
|
||||
const { builders } = await detectBuilders(files, detectorResult);
|
||||
const { builders } = await detectBuilders(files, pkg);
|
||||
const { defaultRoutes } = await detectRoutes(files, builders);
|
||||
|
||||
const nowConfig = { builds: builders, routes: defaultRoutes, probes };
|
||||
@@ -151,9 +128,7 @@ it('Test `detectBuilders` and `detectRoutes`', async () => {
|
||||
|
||||
it('Test `detectBuilders` and `detectRoutes` with `index` files', async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', '02-zero-config-api');
|
||||
const detectorResult = await detectDefaults({
|
||||
fs: new LocalFilesystem(fixture),
|
||||
});
|
||||
const pkg = await fs.readJSON(path.join(fixture, 'package.json'));
|
||||
const fileList = await glob('**', fixture);
|
||||
const files = Object.keys(fileList);
|
||||
|
||||
@@ -217,7 +192,7 @@ it('Test `detectBuilders` and `detectRoutes` with `index` files', async () => {
|
||||
},
|
||||
];
|
||||
|
||||
const { builders } = await detectBuilders(files, detectorResult);
|
||||
const { builders } = await detectBuilders(files, pkg);
|
||||
const { defaultRoutes } = await detectRoutes(files, builders);
|
||||
|
||||
const nowConfig = { builds: builders, routes: defaultRoutes, probes };
|
||||
|
||||
1176
packages/now-build-utils/test/unit.builds-and-routes-detector.test.ts
vendored
Normal file
108
packages/now-build-utils/test/unit.detectors.test.ts
vendored
@@ -1,108 +0,0 @@
|
||||
import assert from 'assert';
|
||||
import { join } from 'path';
|
||||
import { readFile, pathExists } from 'fs-extra';
|
||||
import { detectDefaults, DetectorFilesystem } from '../src';
|
||||
import { firstTruthy } from '../src/detectors';
|
||||
|
||||
class LocalFilesystem extends DetectorFilesystem {
|
||||
private dir: string;
|
||||
|
||||
constructor(dir: string) {
|
||||
super();
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
_exists(name: string): Promise<boolean> {
|
||||
return pathExists(join(this.dir, name));
|
||||
}
|
||||
|
||||
_readFile(name: string): Promise<Buffer> {
|
||||
return readFile(join(this.dir, name));
|
||||
}
|
||||
}
|
||||
|
||||
test('firstTruthy() - truthy', async () => {
|
||||
const result = await firstTruthy([(async () => 0)(), (async () => 1)()]);
|
||||
assert.equal(result, 1);
|
||||
});
|
||||
|
||||
test('firstTruthy() - falsy', async () => {
|
||||
const result = await firstTruthy([(async () => 0)(), (async () => 0)()]);
|
||||
assert.equal(result, 0);
|
||||
});
|
||||
|
||||
test('firstTruthy() - one throws', async () => {
|
||||
const result = await firstTruthy([
|
||||
(async () => {
|
||||
throw new Error('bad');
|
||||
})(),
|
||||
(async () => 1)(),
|
||||
]);
|
||||
assert.equal(result, 1);
|
||||
});
|
||||
|
||||
test('firstTruthy() - all throws', async () => {
|
||||
let errors;
|
||||
try {
|
||||
await firstTruthy([
|
||||
(async () => {
|
||||
throw new Error('bad 1');
|
||||
})(),
|
||||
(async () => {
|
||||
throw new Error('bad 2');
|
||||
})(),
|
||||
]);
|
||||
} catch (_err) {
|
||||
errors = _err;
|
||||
}
|
||||
assert(errors);
|
||||
assert.equal(errors.name, 'AggregateError');
|
||||
const arr = Array.from(errors) as Error[];
|
||||
assert.equal(arr[0].message, 'bad 1');
|
||||
assert.equal(arr[1].message, 'bad 2');
|
||||
});
|
||||
|
||||
test('detectDefaults() - angular', async () => {
|
||||
const dir = join(__dirname, 'fixtures', '03-zero-config-angular');
|
||||
const fs = new LocalFilesystem(dir);
|
||||
const result = await detectDefaults({ fs });
|
||||
if (!result) throw new Error('Expected result');
|
||||
assert.equal(result.outputDirectory, 'dist');
|
||||
assert.deepEqual(result.buildCommand, 'yarn run build');
|
||||
});
|
||||
|
||||
test('detectDefaults() - brunch', async () => {
|
||||
const dir = join(__dirname, 'fixtures', '04-zero-config-brunch');
|
||||
const fs = new LocalFilesystem(dir);
|
||||
const result = await detectDefaults({ fs });
|
||||
if (!result) throw new Error('Expected result');
|
||||
assert.equal(result.outputDirectory, 'public');
|
||||
assert.deepEqual(result.buildCommand, 'yarn run build');
|
||||
});
|
||||
|
||||
test('detectDefaults() - hugo', async () => {
|
||||
const dir = join(__dirname, 'fixtures', '06-zero-config-hugo');
|
||||
const fs = new LocalFilesystem(dir);
|
||||
const result = await detectDefaults({ fs });
|
||||
if (!result) throw new Error('Expected result');
|
||||
assert.equal(result.outputDirectory, 'public');
|
||||
assert.deepEqual(result.buildCommand, 'hugo');
|
||||
});
|
||||
|
||||
test('detectDefaults() - jekyll', async () => {
|
||||
const dir = join(__dirname, 'fixtures', '07-zero-config-jekyll');
|
||||
const fs = new LocalFilesystem(dir);
|
||||
const result = await detectDefaults({ fs });
|
||||
if (!result) throw new Error('Expected result');
|
||||
assert.equal(result.outputDirectory, '_site');
|
||||
assert.deepEqual(result.buildCommand, 'jekyll build');
|
||||
});
|
||||
|
||||
test('detectDefaults() - middleman', async () => {
|
||||
const dir = join(__dirname, 'fixtures', '08-zero-config-middleman');
|
||||
const fs = new LocalFilesystem(dir);
|
||||
const result = await detectDefaults({ fs });
|
||||
if (!result) throw new Error('Expected result');
|
||||
assert.equal(result.outputDirectory, 'build');
|
||||
assert.deepEqual(result.buildCommand, 'bundle exec middleman build');
|
||||
});
|
||||
141
packages/now-build-utils/test/unit.framework-detector.test.ts
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
import path from 'path';
|
||||
import { readFileSync } from 'fs-extra';
|
||||
import { Framework } from '@now/frameworks';
|
||||
import { detectFramework, DetectorFilesystem } from '../src';
|
||||
|
||||
const frameworkList = JSON.parse(
|
||||
readFileSync(
|
||||
path.join(__dirname, '..', '..', 'frameworks', 'frameworks.json')
|
||||
).toString()
|
||||
) as Framework[];
|
||||
|
||||
class VirtualFilesystem extends DetectorFilesystem {
|
||||
private files: Map<string, Buffer>;
|
||||
|
||||
constructor(files: { [key: string]: string | Buffer }) {
|
||||
super();
|
||||
this.files = new Map();
|
||||
Object.entries(files).map(([key, value]) => {
|
||||
const buffer = typeof value === 'string' ? Buffer.from(value) : value;
|
||||
this.files.set(key, buffer);
|
||||
});
|
||||
}
|
||||
|
||||
async _exists(name: string): Promise<boolean> {
|
||||
return this.files.has(name);
|
||||
}
|
||||
|
||||
async _readFile(name: string): Promise<Buffer> {
|
||||
const file = this.files.get(name);
|
||||
|
||||
if (file === undefined) {
|
||||
throw new Error('File does not exist');
|
||||
}
|
||||
|
||||
if (typeof file === 'string') {
|
||||
return Buffer.from(file);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
describe('#detectFramework', () => {
|
||||
it('Do not detect anything', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'README.md': '# hi',
|
||||
'api/cheese.js': 'export default (req, res) => res.end("cheese");',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe(null);
|
||||
});
|
||||
|
||||
it('Detect Next.js', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
next: '9.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
|
||||
});
|
||||
|
||||
it('Detect Nuxt.js', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
nuxt: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
});
|
||||
|
||||
it('Detect Gatsby', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
gatsby: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('gatsby');
|
||||
});
|
||||
|
||||
it('Detect Hugo #1', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.yaml': 'config',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
});
|
||||
|
||||
it('Detect Hugo #2', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.json': 'config',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
});
|
||||
|
||||
it('Detect Hugo #3', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.toml': 'config',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
});
|
||||
|
||||
it('Detect Jekyll', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'_config.yml': 'config',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('jekyll');
|
||||
});
|
||||
|
||||
it('Detect Middleman', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.rb': 'config',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('middleman');
|
||||
});
|
||||
|
||||
it('Detect Scully', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'@angular/cli': 'latest',
|
||||
'@scullyio/init': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('scully');
|
||||
});
|
||||
});
|
||||
1005
packages/now-build-utils/test/unit.test.js
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "now",
|
||||
"version": "16.7.0",
|
||||
"version": "16.7.1",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Now",
|
||||
|
||||
@@ -239,7 +239,7 @@ export default async function main(ctx) {
|
||||
return 1;
|
||||
}
|
||||
if (deployment.version === 2) {
|
||||
output.error('Cannot scale a deployment containing builds');
|
||||
output.error('Cannot scale a Now 2.0 deployment');
|
||||
now.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import chalk from 'chalk';
|
||||
import execa from 'execa';
|
||||
import semver from 'semver';
|
||||
import pipe from 'promisepipe';
|
||||
@@ -8,7 +7,6 @@ import { extract } from 'tar-fs';
|
||||
import { createHash } from 'crypto';
|
||||
import { createGunzip } from 'zlib';
|
||||
import { join, resolve } from 'path';
|
||||
import { funCacheDir } from '@zeit/fun';
|
||||
import { PackageJson } from '@now/build-utils';
|
||||
import XDGAppPaths from 'xdg-app-paths';
|
||||
import {
|
||||
@@ -17,7 +15,6 @@ import {
|
||||
readFile,
|
||||
readJSON,
|
||||
writeFile,
|
||||
remove,
|
||||
} from 'fs-extra';
|
||||
import pkg from '../../../package.json';
|
||||
|
||||
@@ -296,6 +293,7 @@ export async function updateBuilders(
|
||||
if (!builderDir) {
|
||||
builderDir = await builderDirPromise;
|
||||
}
|
||||
|
||||
const packages = Array.from(packagesSet);
|
||||
const yarnPath = join(yarnDir, 'yarn');
|
||||
const buildersPkgPath = join(builderDir, 'package.json');
|
||||
|
||||
@@ -22,8 +22,6 @@ import {
|
||||
PackageJson,
|
||||
detectBuilders,
|
||||
detectRoutes,
|
||||
detectDefaults,
|
||||
DetectorFilesystem,
|
||||
} from '@now/build-utils';
|
||||
|
||||
import { once } from '../once';
|
||||
@@ -102,25 +100,6 @@ function sortBuilders(buildA: Builder, buildB: Builder) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
class DevDetectorFilesystem extends DetectorFilesystem {
|
||||
private dir: string;
|
||||
private files: string[];
|
||||
|
||||
constructor(dir: string, files: string[]) {
|
||||
super();
|
||||
this.dir = dir;
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
_exists(name: string): Promise<boolean> {
|
||||
return Promise.resolve(this.files.includes(name));
|
||||
}
|
||||
|
||||
_readFile(name: string): Promise<Buffer> {
|
||||
return fs.readFile(join(this.dir, name));
|
||||
}
|
||||
}
|
||||
|
||||
export default class DevServer {
|
||||
public cwd: string;
|
||||
public debug: boolean;
|
||||
@@ -498,6 +477,8 @@ export default class DevServer {
|
||||
return this.cachedNowConfig;
|
||||
}
|
||||
|
||||
const pkg = await this.getPackageJson();
|
||||
|
||||
// The default empty `now.json` is used to serve all files as static
|
||||
// when no `now.json` is present
|
||||
let config: NowConfig = this.cachedNowConfig || { version: 2 };
|
||||
@@ -545,18 +526,13 @@ export default class DevServer {
|
||||
|
||||
// no builds -> zero config
|
||||
if (!config.builds || config.builds.length === 0) {
|
||||
const detectorResult = await detectDefaults({
|
||||
fs: new DevDetectorFilesystem(this.cwd, files),
|
||||
});
|
||||
const { projectSettings } = config;
|
||||
|
||||
const { builders, warnings, errors } = await detectBuilders(
|
||||
files,
|
||||
detectorResult,
|
||||
{
|
||||
tag: getDistTag(cliVersion) === 'canary' ? 'canary' : 'latest',
|
||||
functions: config.functions,
|
||||
}
|
||||
);
|
||||
const { builders, warnings, errors } = await detectBuilders(files, pkg, {
|
||||
tag: getDistTag(cliVersion) === 'canary' ? 'canary' : 'latest',
|
||||
functions: config.functions,
|
||||
...(projectSettings ? { projectSettings } : {}),
|
||||
});
|
||||
|
||||
if (errors) {
|
||||
this.output.error(errors[0].message);
|
||||
@@ -602,6 +578,29 @@ export default class DevServer {
|
||||
return config;
|
||||
}
|
||||
|
||||
async getPackageJson(): Promise<PackageJson | null> {
|
||||
const pkgPath = join(this.cwd, 'package.json');
|
||||
let pkg: PackageJson | null = null;
|
||||
|
||||
this.output.debug('Reading `package.json` file');
|
||||
|
||||
try {
|
||||
pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'));
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
this.output.debug('No `package.json` file present');
|
||||
} else if (err.name === 'SyntaxError') {
|
||||
this.output.warn(
|
||||
`There is a syntax error in the \`package.json\` file: ${err.message}`
|
||||
);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
return pkg;
|
||||
}
|
||||
|
||||
async tryValidateOrExit(
|
||||
config: NowConfig,
|
||||
validate: (c: NowConfig) => string | null
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import chalk from 'chalk';
|
||||
import boxen from 'boxen';
|
||||
import { format } from 'util';
|
||||
import { Console } from 'console';
|
||||
|
||||
@@ -18,10 +19,32 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
}
|
||||
|
||||
function warn(str: string, slug: string | null = null) {
|
||||
log(chalk`{yellow.bold WARN!} ${str}`);
|
||||
if (slug !== null) {
|
||||
log(`More details: https://err.sh/now/${slug}`);
|
||||
const prevTerm = process.env.TERM;
|
||||
|
||||
if (!prevTerm) {
|
||||
// workaround for https://github.com/sindresorhus/term-size/issues/13
|
||||
process.env.TERM = 'xterm';
|
||||
}
|
||||
|
||||
print(
|
||||
boxen(
|
||||
chalk.bold.yellow('WARN! ') +
|
||||
str +
|
||||
(slug ? `\nMore details: https://err.sh/now/${slug}` : ''),
|
||||
{
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 1,
|
||||
right: 1,
|
||||
},
|
||||
borderColor: 'yellow',
|
||||
}
|
||||
)
|
||||
);
|
||||
print('\n');
|
||||
|
||||
process.env.TERM = prevTerm;
|
||||
}
|
||||
|
||||
function note(str: string) {
|
||||
@@ -59,7 +82,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
_times: new Map(),
|
||||
log(a: string, ...args: string[]) {
|
||||
debug(format(a, ...args));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
async function time(label: string, fn: Promise<any> | (() => Promise<any>)) {
|
||||
@@ -85,6 +108,6 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
debug,
|
||||
dim,
|
||||
time,
|
||||
note
|
||||
note,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -58,9 +58,7 @@ export default async function preferV2Deployment({
|
||||
)} is missing a ${cmd('start')} script. ${INFO}`;
|
||||
}
|
||||
} else if (!pkg && !hasDockerfile) {
|
||||
return `Deploying to Now 2.0, because no ${highlight(
|
||||
'Dockerfile'
|
||||
)} was found. ${INFO}`;
|
||||
return `Deploying to Now 2.0 automatically. ${INFO}`;
|
||||
}
|
||||
|
||||
if (client && projectName) {
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
"dependencies": {
|
||||
"gridsome": "^0.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "./hugo"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
@@ -6698,21 +6698,21 @@ string.prototype.padstart@^3.0.0:
|
||||
es-abstract "^1.4.3"
|
||||
function-bind "^1.0.2"
|
||||
|
||||
string.prototype.trimleft@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz#68b6aa8e162c6a80e76e3a8a0c2e747186e271ff"
|
||||
integrity sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=
|
||||
string.prototype.trimleft@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
|
||||
integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string.prototype.trimright@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz#ab4a56d802a01fbe7293e11e84f24dc8164661dd"
|
||||
integrity sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=
|
||||
string.prototype.trimright@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
|
||||
integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
|
||||
@@ -7307,21 +7307,21 @@ string.prototype.padstart@^3.0.0:
|
||||
es-abstract "^1.4.3"
|
||||
function-bind "^1.0.2"
|
||||
|
||||
string.prototype.trimleft@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz#68b6aa8e162c6a80e76e3a8a0c2e747186e271ff"
|
||||
integrity sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=
|
||||
string.prototype.trimleft@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
|
||||
integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string.prototype.trimright@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz#ab4a56d802a01fbe7293e11e84f24dc8164661dd"
|
||||
integrity sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=
|
||||
string.prototype.trimright@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
|
||||
integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
|
||||
@@ -1238,7 +1238,7 @@ deep-extend@^0.6.0:
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
||||
define-properties@^1.1.2:
|
||||
define-properties@^1.1.2, define-properties@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
|
||||
@@ -1660,7 +1660,7 @@ fsevents@^1.2.7:
|
||||
nan "^2.12.1"
|
||||
node-pre-gyp "^0.12.0"
|
||||
|
||||
function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
|
||||
function-bind@^1.1.0, function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
@@ -3305,21 +3305,21 @@ string-width@^1.0.1:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string.prototype.trimleft@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz#68b6aa8e162c6a80e76e3a8a0c2e747186e271ff"
|
||||
integrity sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=
|
||||
string.prototype.trimleft@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
|
||||
integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string.prototype.trimright@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz#ab4a56d802a01fbe7293e11e84f24dc8164661dd"
|
||||
integrity sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=
|
||||
string.prototype.trimright@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
|
||||
integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string_decoder@~0.10.31, string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
|
||||
@@ -5746,7 +5746,7 @@ fsevents@^2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
|
||||
integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==
|
||||
|
||||
function-bind@^1.0.2, function-bind@^1.1.1:
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
@@ -11917,21 +11917,21 @@ string.prototype.trim@^1.1.2:
|
||||
es-abstract "^1.13.0"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string.prototype.trimleft@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz#68b6aa8e162c6a80e76e3a8a0c2e747186e271ff"
|
||||
integrity sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=
|
||||
string.prototype.trimleft@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
|
||||
integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string.prototype.trimright@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz#ab4a56d802a01fbe7293e11e84f24dc8164661dd"
|
||||
integrity sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=
|
||||
string.prototype.trimright@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
|
||||
integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
|
||||
2
packages/now-cli/test/dev/fixtures/trigger-static-build/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
package.json
|
||||
yarn.lock
|
||||
@@ -311,6 +311,13 @@ CMD ["node", "index.js"]`,
|
||||
files: ['.gitignore', 'folder', 'index.js', 'test.html'],
|
||||
}),
|
||||
},
|
||||
'redirects-v2': {
|
||||
'now.json': JSON.stringify({
|
||||
version: 2,
|
||||
name: 'redirects-v2',
|
||||
redirects: [{ source: `/(.*)`, destination: 'https://example.com/$1' }],
|
||||
}),
|
||||
},
|
||||
'local-config-v2': {
|
||||
[`main-${session}.html`]: '<h1>hello main</h1>',
|
||||
[`test-${session}.html`]: '<h1>hello test</h1>',
|
||||
|
||||
22
packages/now-cli/test/integration.js
vendored
@@ -211,6 +211,26 @@ test('login', async t => {
|
||||
t.is(typeof token, 'string');
|
||||
});
|
||||
|
||||
test('deploy using only now.json with `redirects` defined', async t => {
|
||||
const target = fixture('redirects-v2');
|
||||
|
||||
const { exitCode, stderr, stdout } = await execa(
|
||||
binaryPath,
|
||||
[target, ...defaultArgs],
|
||||
{
|
||||
reject: false,
|
||||
}
|
||||
);
|
||||
|
||||
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
|
||||
|
||||
const i = stdout.lastIndexOf('https://');
|
||||
const url = stdout.slice(i);
|
||||
const res = await fetch(`${url}/foo/bar`, { redirect: 'manual' });
|
||||
const location = res.headers.get('location');
|
||||
t.is(location, 'https://example.com/foo/bar');
|
||||
});
|
||||
|
||||
test('deploy using --local-config flag v2', async t => {
|
||||
const target = fixture('local-config-v2');
|
||||
const configPath = path.join(target, 'now-test.json');
|
||||
@@ -915,7 +935,7 @@ test('ensure we render a warning for deployments with no files', async t => {
|
||||
// Ensure the warning is printed
|
||||
t.true(
|
||||
stderr.includes(
|
||||
'> WARN! There are no files (or only files starting with a dot) inside your deployment.'
|
||||
'WARN! There are no files (or only files starting with a dot) inside your deployment.'
|
||||
)
|
||||
);
|
||||
|
||||
|
||||