wip(new-design): Work on v3 for this package
This commit is contained in:
parent
3604cb918d
commit
3553c43633
40 changed files with 364 additions and 1753 deletions
|
@ -11,6 +11,6 @@ export const cli = async () => {
|
|||
// Get user input
|
||||
const choices = await getChoices()
|
||||
|
||||
// Create environment from template
|
||||
// Create environment
|
||||
createEnvironment(choices)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ export const config = {
|
|||
// Whether we're publishing next or latest tags
|
||||
tag: 'next',
|
||||
// Minimum node version
|
||||
node: 16,
|
||||
node: 18,
|
||||
// Site to download from
|
||||
fileUri: 'https://raw.githubusercontent.com',
|
||||
// Repository to download from
|
||||
|
@ -19,7 +19,7 @@ export const config = {
|
|||
'workbench',
|
||||
'errors',
|
||||
'i18n',
|
||||
'lab',
|
||||
'sde',
|
||||
'measurements',
|
||||
'optiongroups',
|
||||
'o_bella',
|
||||
|
@ -54,8 +54,6 @@ npm-debug.log*
|
|||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# e2e test results
|
||||
playwright-report
|
||||
`,
|
||||
fetch: {
|
||||
config: [
|
||||
|
@ -65,176 +63,161 @@ playwright-report
|
|||
},
|
||||
],
|
||||
sites: [
|
||||
'shared/utils.mjs',
|
||||
'shared/designs/index.js',
|
||||
'shared/config/freesewing.mjs',
|
||||
{
|
||||
from: 'sde/env.local',
|
||||
to: 'sde/.env.local',
|
||||
},
|
||||
'sde/i18n.config.mjs',
|
||||
'sde/next-i18next.config.js',
|
||||
'sde/next.config.mjs',
|
||||
'sde/package.json',
|
||||
'sde/postcss.config.js',
|
||||
'sde/site.config.mjs',
|
||||
'sde/tailwind.config.mjs',
|
||||
'sde/hooks/use-design.mjs',
|
||||
'sde/components/dynamic-org-docs.mjs',
|
||||
'sde/components/feeds.mjs',
|
||||
'sde/components/search.mjs',
|
||||
'sde/components/header/design-picker.mjs',
|
||||
'sde/components/header/index.mjs',
|
||||
'sde/components/navigation/modal-menu.mjs',
|
||||
'sde/components/layouts/bare.mjs',
|
||||
'sde/components/layouts/default.mjs',
|
||||
'sde/components/layouts/workbench.mjs',
|
||||
'sde/components/wrappers/page.mjs',
|
||||
'sde/design/from-bent/src/back.mjs',
|
||||
'sde/design/from-bent/src/front.mjs',
|
||||
'sde/design/from-bent/src/index.mjs',
|
||||
'sde/design/from-bent/src/top-sleeve.mjs',
|
||||
'sde/design/from-bent/src/under-sleeve.mjs',
|
||||
'sde/design/from-bent/i18n/de.json',
|
||||
'sde/design/from-bent/i18n/en.json',
|
||||
'sde/design/from-bent/i18n/es.json',
|
||||
'sde/design/from-bent/i18n/fr.json',
|
||||
'sde/design/from-bent/i18n/index.mjs',
|
||||
'sde/design/from-bent/i18n/nl.json',
|
||||
'sde/design/from-bent/i18n/uk.json',
|
||||
'sde/design/from-bella/en.json',
|
||||
'sde/design/from-bella/src/back.mjs',
|
||||
'sde/design/from-bella/src/front.mjs',
|
||||
'sde/design/from-bella/src/index.mjs',
|
||||
'sde/design/from-bella/i18n/de.json',
|
||||
'sde/design/from-bella/i18n/en.json',
|
||||
'sde/design/from-bella/i18n/es.json',
|
||||
'sde/design/from-bella/i18n/fr.json',
|
||||
'sde/design/from-bella/i18n/index.mjs',
|
||||
'sde/design/from-bella/i18n/nl.json',
|
||||
'sde/design/from-bella/i18n/uk.json',
|
||||
'sde/design/from-breanna/src/back.mjs',
|
||||
'sde/design/from-breanna/src/front.mjs',
|
||||
'sde/design/from-breanna/src/index.mjs',
|
||||
'sde/design/from-breanna/src/sleeve.mjs',
|
||||
'sde/design/from-breanna/i18n/de.json',
|
||||
'sde/design/from-breanna/i18n/en.json',
|
||||
'sde/design/from-breanna/i18n/es.json',
|
||||
'sde/design/from-breanna/i18n/fr.json',
|
||||
'sde/design/from-breanna/i18n/index.mjs',
|
||||
'sde/design/from-breanna/i18n/nl.json',
|
||||
'sde/design/from-breanna/i18n/uk.json',
|
||||
'sde/design/from-brian/i18n/de.json',
|
||||
'sde/design/from-brian/i18n/en.json',
|
||||
'sde/design/from-brian/i18n/es.json',
|
||||
'sde/design/from-brian/i18n/fr.json',
|
||||
'sde/design/from-brian/i18n/index.mjs',
|
||||
'sde/design/from-brian/i18n/nl.json',
|
||||
'sde/design/from-brian/i18n/uk.json',
|
||||
'sde/design/from-brian/src/back.mjs',
|
||||
'sde/design/from-brian/src/front.mjs',
|
||||
'sde/design/from-brian/src/index.mjs',
|
||||
'sde/design/from-brian/src/sleeve.mjs',
|
||||
'sde/design/from-titan/i18n/de.json',
|
||||
'sde/design/from-titan/i18n/en.json',
|
||||
'sde/design/from-titan/i18n/es.json',
|
||||
'sde/design/from-titan/i18n/fr.json',
|
||||
'sde/design/from-titan/i18n/index.mjs',
|
||||
'sde/design/from-titan/i18n/nl.json',
|
||||
'sde/design/from-titan/i18n/uk.json',
|
||||
'sde/design/from-titan/src/back.mjs',
|
||||
'sde/design/from-titan/src/front.mjs',
|
||||
'sde/design/from-titan/src/index.mjs',
|
||||
'sde/design/from-scratch/i18n/de.json',
|
||||
'sde/design/from-scratch/i18n/en.json',
|
||||
'sde/design/from-scratch/i18n/es.json',
|
||||
'sde/design/from-scratch/i18n/fr.json',
|
||||
'sde/design/from-scratch/i18n/index.mjs',
|
||||
'sde/design/from-scratch/i18n/nl.json',
|
||||
'sde/design/from-scratch/i18n/uk.json',
|
||||
'sde/design/from-scratch/src/index.mjs',
|
||||
'sde/design/from-scratch/src/scratch.mjs',
|
||||
'sde/design/tutorial/i18n/de.json',
|
||||
'sde/design/tutorial/i18n/en.json',
|
||||
'sde/design/tutorial/i18n/es.json',
|
||||
'sde/design/tutorial/i18n/fr.json',
|
||||
'sde/design/tutorial/i18n/index.mjs',
|
||||
'sde/design/tutorial/i18n/nl.json',
|
||||
'sde/design/tutorial/i18n/uk.json',
|
||||
'sde/design/tutorial/src/bib.mjs',
|
||||
'sde/design/tutorial/src/index.mjs',
|
||||
'sde/public/brands/algolia.svg',
|
||||
'sde/public/brands/bugsnag.svg',
|
||||
'sde/public/brands/crowdin.svg',
|
||||
'sde/public/brands/netlify.svg',
|
||||
'sde/public/brands/vercel.svg',
|
||||
'sde/pages/_app.mjs',
|
||||
'sde/pages/design.mjs',
|
||||
'sde/pages/index.mjs',
|
||||
'sde/pages/support.mjs',
|
||||
'sde/pages/code/index.mjs',
|
||||
'sde/pages/design/[design].mjs',
|
||||
'sde/pages/docs/index.mjs',
|
||||
'sde/pages/sde/en.yaml',
|
||||
'sde/pages/sde/index.mjs',
|
||||
'sde/pages/sets/[id].mjs',
|
||||
'sde/pages/signup/index.mjs',
|
||||
'sde/pages/patterns/index.mjs',
|
||||
'sde/pages/patterns/[id]/edit.mjs',
|
||||
'sde/pages/patterns/[id]/index.mjs',
|
||||
'sde/pages/signin/index.mjs',
|
||||
'sde/pages/signin/callback/[provider].mjs',
|
||||
'sde/pages/account/[platform].mjs',
|
||||
'sde/pages/account/bio.mjs',
|
||||
'sde/pages/account/compare.mjs',
|
||||
'sde/pages/account/consent.mjs',
|
||||
'sde/pages/account/control.mjs',
|
||||
'sde/pages/account/email.mjs',
|
||||
'sde/pages/account/export.mjs',
|
||||
'sde/pages/account/github.mjs',
|
||||
'sde/pages/account/img.mjs',
|
||||
'sde/pages/account/index.mjs',
|
||||
'sde/pages/account/language.mjs',
|
||||
'sde/pages/account/mfa.mjs',
|
||||
'sde/pages/account/newsletter.mjs',
|
||||
'sde/pages/account/password.mjs',
|
||||
'sde/pages/account/privacy.mjs',
|
||||
'sde/pages/account/reload.mjs',
|
||||
'sde/pages/account/remove.mjs',
|
||||
'sde/pages/account/restrict.mjs',
|
||||
'sde/pages/account/units.mjs',
|
||||
'sde/pages/account/username.mjs',
|
||||
'sde/pages/account/apikeys/[id].mjs',
|
||||
'sde/pages/account/apikeys/index.mjs',
|
||||
'sde/pages/account/bookmarks/[id].mjs',
|
||||
'sde/pages/account/bookmarks/index.mjs',
|
||||
'sde/pages/account/sets/[id].mjs',
|
||||
'sde/pages/account/sets/index.mjs',
|
||||
'sde/pages/account/patterns/index.mjs',
|
||||
'sde/pages/account/patterns/[id]/edit.mjs',
|
||||
'sde/pages/account/patterns/[id]/index.mjs',
|
||||
'shared/config/cloudflare.mjs',
|
||||
'shared/config/designs.mjs',
|
||||
'shared/config/freesewing.config.mjs',
|
||||
'shared/config/i18n.config.mjs',
|
||||
'shared/config/next.mjs',
|
||||
'shared/config/paypal.mjs',
|
||||
'shared/config/playwright.mjs',
|
||||
'shared/config/postcss.config.js',
|
||||
'shared/config/tailwind-force.html',
|
||||
'shared/config/tailwind.config.js',
|
||||
'shared/hooks/useGist.mjs',
|
||||
'shared/hooks/useLocalStorage.mjs',
|
||||
'shared/hooks/useTheme.mjs',
|
||||
'shared/mdx/compiler.mjs',
|
||||
'shared/mdx/loader.mjs',
|
||||
'shared/mdx/mdx-plugin-toc.mjs',
|
||||
'shared/mdx/remark-intro-plugin.mjs',
|
||||
'shared/strapi/loader.js',
|
||||
'shared/strapi/qa.mjs',
|
||||
'shared/themes/dark.js',
|
||||
'shared/themes/hax0r.js',
|
||||
'shared/themes/index.js',
|
||||
'shared/themes/lgbtq.js',
|
||||
'shared/themes/light.js',
|
||||
'shared/themes/runtime.mjs',
|
||||
'shared/styles/code.css',
|
||||
'shared/styles/globals.css',
|
||||
'shared/styles/svg-freesewing-draft.css',
|
||||
'shared/prebuild/contributors.mjs',
|
||||
'shared/prebuild/feed.mjs',
|
||||
'shared/prebuild/i18n-only.mjs',
|
||||
'shared/prebuild/i18n.mjs',
|
||||
'shared/prebuild/index.mjs',
|
||||
'shared/prebuild/lab.mjs',
|
||||
'shared/prebuild/md-intro.mjs',
|
||||
'shared/prebuild/mdx.mjs',
|
||||
'shared/prebuild/navigation.mjs',
|
||||
'shared/prebuild/patrons.mjs',
|
||||
'shared/prebuild/strapi.mjs',
|
||||
'shared/prebuild/og/index.mjs',
|
||||
'shared/components/breadcrumbs.mjs',
|
||||
'shared/components/code.mjs',
|
||||
'shared/components/copy-to-clipboard.mjs',
|
||||
'shared/components/docs-link.mjs',
|
||||
'shared/components/icons.mjs',
|
||||
'shared/components/json.mjs',
|
||||
'shared/components/lightbox.mjs',
|
||||
'shared/components/loader.mjs',
|
||||
'shared/components/modal.mjs',
|
||||
'shared/components/link.mjs',
|
||||
'shared/components/picker.mjs',
|
||||
'shared/components/popout.mjs',
|
||||
'shared/components/raw-span.mjs',
|
||||
'shared/components/ribbon.mjs',
|
||||
'shared/components/spinner.mjs',
|
||||
'shared/components/web-link.mjs',
|
||||
'shared/components/wordmark.mjs',
|
||||
'shared/components/worm.mjs',
|
||||
'shared/components/yaml.mjs',
|
||||
'shared/components/error/error-boundary.mjs',
|
||||
'shared/components/error/reset-buttons.mjs',
|
||||
'shared/components/error/view.mjs',
|
||||
'shared/components/icons/flip.js',
|
||||
'shared/components/icons/rotate.js',
|
||||
'shared/components/locale-picker/index.mjs',
|
||||
'shared/components/locale-picker/locales.de.yaml',
|
||||
'shared/components/locale-picker/locales.en.yaml',
|
||||
'shared/components/locale-picker/locales.es.yaml',
|
||||
'shared/components/locale-picker/locales.fr.yaml',
|
||||
'shared/components/locale-picker/locales.nl.yaml',
|
||||
'shared/components/logos/cc-by.mjs',
|
||||
'shared/components/logos/cc.mjs',
|
||||
'shared/components/logos/freesewing.mjs',
|
||||
'shared/components/logos/osi.mjs',
|
||||
'shared/components/mdx/figure.mjs',
|
||||
'shared/components/mdx/highlight.mjs',
|
||||
'shared/components/mdx/http.mjs',
|
||||
'shared/components/mdx/index.mjs',
|
||||
'shared/components/mdx/mermaid.mjs',
|
||||
'shared/components/mdx/prev-next.mjs',
|
||||
'shared/components/mdx/read-more.mjs',
|
||||
'shared/components/mdx/tabbed-example.mjs',
|
||||
'shared/components/mdx/tabs.mjs',
|
||||
'shared/components/mdx/youtube.mjs',
|
||||
'shared/components/navigation/aside.mjs',
|
||||
'shared/components/navigation/primary.mjs',
|
||||
'shared/components/robot/index.mjs',
|
||||
'shared/components/robot/poses.mjs',
|
||||
'shared/components/theme-picker/index.mjs',
|
||||
'shared/components/theme-picker/themes.de.yaml',
|
||||
'shared/components/theme-picker/themes.en.yaml',
|
||||
'shared/components/theme-picker/themes.es.yaml',
|
||||
'shared/components/theme-picker/themes.fr.yaml',
|
||||
'shared/components/theme-picker/themes.nl.yaml',
|
||||
'shared/components/wrappers/img.mjs',
|
||||
'shared/components/wrappers/mdx.mjs',
|
||||
'shared/components/wrappers/page.mjs',
|
||||
'shared/components/wrappers/toc.mjs',
|
||||
'shared/components/wrappers/workbench.mjs',
|
||||
'shared/components/workbench/gist.mjs',
|
||||
'shared/components/workbench/logs.mjs',
|
||||
'shared/components/workbench/preloaders.mjs',
|
||||
'shared/components/workbench/sample.mjs',
|
||||
'shared/components/workbench/edit/index.mjs',
|
||||
'shared/components/workbench/edit/gist-validator.mjs',
|
||||
'shared/components/workbench/exporting/export-handler.mjs',
|
||||
'shared/components/workbench/exporting/export-worker.js',
|
||||
'shared/components/workbench/exporting/index.mjs',
|
||||
'shared/components/workbench/exporting/pdf-maker.mjs',
|
||||
'shared/components/workbench/inputs/design-option-count.mjs',
|
||||
'shared/components/workbench/inputs/design-option-list.mjs',
|
||||
'shared/components/workbench/inputs/design-option-pct-deg.mjs',
|
||||
'shared/components/workbench/inputs/measurement.mjs',
|
||||
'shared/components/workbench/measurements/index.mjs',
|
||||
'shared/components/workbench/draft/circle.mjs',
|
||||
'shared/components/workbench/draft/defs.mjs',
|
||||
'shared/components/workbench/draft/error.mjs',
|
||||
'shared/components/workbench/draft/index.mjs',
|
||||
'shared/components/workbench/draft/part.mjs',
|
||||
'shared/components/workbench/draft/path.mjs',
|
||||
'shared/components/workbench/draft/point.mjs',
|
||||
'shared/components/workbench/draft/snippet.mjs',
|
||||
'shared/components/workbench/draft/stack.mjs',
|
||||
'shared/components/workbench/draft/svg.mjs',
|
||||
'shared/components/workbench/draft/text.mjs',
|
||||
'shared/components/workbench/draft/utils.mjs',
|
||||
'shared/components/workbench/layout/default.mjs',
|
||||
'shared/components/workbench/layout/cut/index.mjs',
|
||||
'shared/components/workbench/layout/cut/plugin-cut-layout.mjs',
|
||||
'shared/components/workbench/layout/cut/settings.mjs',
|
||||
'shared/components/workbench/layout/print/index.mjs',
|
||||
'shared/components/workbench/layout/print/orientation-picker.mjs',
|
||||
'shared/components/workbench/layout/print/pagesize-picker.mjs',
|
||||
'shared/components/workbench/layout/plugin-layout-part.mjs',
|
||||
'shared/components/workbench/layout/print/settings.mjs',
|
||||
'shared/components/workbench/layout/draft/buttons.mjs',
|
||||
'shared/components/workbench/layout/draft/index.mjs',
|
||||
'shared/components/workbench/layout/draft/stack.mjs',
|
||||
'shared/components/workbench/menu/index.mjs',
|
||||
'shared/components/workbench/menu/view.mjs',
|
||||
'shared/components/workbench/menu/design-options/index.mjs',
|
||||
'shared/components/workbench/menu/design-options/option-group.mjs',
|
||||
'shared/components/workbench/menu/design-options/option-input.mjs',
|
||||
'shared/components/workbench/menu/design-options/option-value.mjs',
|
||||
'shared/components/workbench/menu/design-options/option.mjs',
|
||||
'shared/components/workbench/menu/test-design-options/index.mjs',
|
||||
'shared/components/workbench/menu/test-design-options/option.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-bool.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-list.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-mm.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-nr.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-only.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-sa-bool.mjs',
|
||||
'shared/components/workbench/menu/core-settings/core-setting-sa-mm.mjs',
|
||||
'shared/components/workbench/menu/core-settings/index.mjs',
|
||||
'shared/components/workbench/menu/core-settings/setting.mjs',
|
||||
'shared/components/workbench/menu/xray/attributes.mjs',
|
||||
'shared/components/workbench/menu/xray/disable.mjs',
|
||||
'shared/components/workbench/menu/xray/index.mjs',
|
||||
'shared/components/workbench/menu/xray/list.mjs',
|
||||
'shared/components/workbench/menu/xray/log.mjs',
|
||||
'shared/components/workbench/menu/xray/path-ops.mjs',
|
||||
'shared/components/workbench/menu/xray/path.mjs',
|
||||
'shared/components/workbench/menu/xray/point.mjs',
|
||||
'shared/components/workbench/menu/xray/reset.mjs',
|
||||
'lab/components/about.mjs',
|
||||
'lab/components/design-picker.mjs',
|
||||
'lab/components/header.mjs',
|
||||
'lab/components/layouts/bare.mjs',
|
||||
'lab/components/layouts/lab.mjs',
|
||||
'lab/components/wrappers/layout.mjs',
|
||||
'lab/components/wrappers/page.mjs',
|
||||
'shared/config/tailwind.config.mjs',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ const nl = '\n'
|
|||
const tab = ' '
|
||||
const nlt = nl + tab
|
||||
|
||||
// Checks for node 16 or higher
|
||||
// Checks for node 18 or higher
|
||||
export const checkNodeVersion = () => {
|
||||
const node_version = process.version.slice(1).split('.')[0]
|
||||
if (parseInt(node_version) < config.node) {
|
||||
|
@ -47,68 +47,22 @@ export const checkNodeVersion = () => {
|
|||
}
|
||||
}
|
||||
|
||||
// Helper method to validate the design name
|
||||
const validateDesignName = (name) => {
|
||||
if (/^([a-z][a-z0-9_]*)$/.test(name)) return true
|
||||
else
|
||||
return ' 🙈 Please use only lowercase letters, digits, or underscores. Names must start with a lowercase letter. 🤷'
|
||||
}
|
||||
|
||||
// Gets user input to figure out what to do
|
||||
export const getChoices = async () => {
|
||||
const { template } = await prompts({
|
||||
type: 'select',
|
||||
name: 'template',
|
||||
message: 'What template would you like to use? 📑',
|
||||
choices: [
|
||||
{ title: 'Tutorial', value: 'tutorial', description: 'Setup the pattern design tutorial' },
|
||||
{ title: 'From Scratch', value: 'scratch', description: 'Create a design from scratch' },
|
||||
{
|
||||
title: 'Extend Brian',
|
||||
value: 'brian',
|
||||
description: 'Extend the Brian design (basic torso block for menswear)',
|
||||
},
|
||||
{
|
||||
title: 'Extend Bent',
|
||||
value: 'bent',
|
||||
description: 'Extend the Bent design (like brian with added two-part sleeve)',
|
||||
},
|
||||
{
|
||||
title: 'Extend Bella',
|
||||
value: 'bella',
|
||||
description: 'Extend the Bella design (womenswear torso block)',
|
||||
},
|
||||
{
|
||||
title: 'Extend Breanna',
|
||||
value: 'breanna',
|
||||
description: 'Extend the Breanna design (womenswear torso block - YMMV)',
|
||||
},
|
||||
{
|
||||
title: 'Extend Titan',
|
||||
value: 'titan',
|
||||
description: 'Extend the Titan design (gender-neutral trouser block)',
|
||||
},
|
||||
],
|
||||
initial: 0,
|
||||
})
|
||||
|
||||
let finalName = false // we're going to use this to track whether we stay in the naming loop
|
||||
let overwrite = true // should we overwrite existing files?
|
||||
const cwd = process.cwd()
|
||||
let name // name will go here
|
||||
let sideStep // allows to do something custom
|
||||
const cwd = process.cwd()
|
||||
|
||||
// while we're not finalized on a name
|
||||
while (finalName === false) {
|
||||
// request a name
|
||||
name =
|
||||
template === 'tutorial' && name === undefined
|
||||
? 'tutorial'
|
||||
: (
|
||||
name = (
|
||||
await prompts({
|
||||
type: 'text',
|
||||
name: 'name',
|
||||
message: 'What name would you like the design to have? 🏷️ ([a-z0-9_] only)',
|
||||
validate: validateDesignName,
|
||||
message: 'Give a folder name in which we can setup the development environment? 🏷️ ',
|
||||
})
|
||||
).name
|
||||
|
||||
|
@ -127,19 +81,28 @@ export const getChoices = async () => {
|
|||
const { nextStep } = await prompts({
|
||||
type: 'select',
|
||||
name: 'nextStep',
|
||||
message:
|
||||
'It looks like you already have a design by that name in progress. What should we do?',
|
||||
message: 'It looks like that folder already exists. What should we do?',
|
||||
choices: [
|
||||
{ title: 'Rename', value: 'rename', description: 'Choose a new name for this design' },
|
||||
{ title: 'Overwrite', value: 'overwrite', description: 'Overwrite the existing design' },
|
||||
{ title: 'Go back', value: 'rename', description: 'Choose a different folder name' },
|
||||
{
|
||||
title: 'Overwrite',
|
||||
value: 'overwrite',
|
||||
description: 'Overwrite the contents in the existing folder',
|
||||
},
|
||||
{
|
||||
title: 'Re-initialize',
|
||||
value: 'reinit',
|
||||
description:
|
||||
"Bring in a fresh workbench, but don't overwrite existing design files (useful for updating to the latest dev environment)",
|
||||
'Re-install depenencies, and update the development environment in this folder',
|
||||
},
|
||||
{
|
||||
title: 'Re-download',
|
||||
value: 'redownload',
|
||||
description: 'Update the development environment in this folder',
|
||||
},
|
||||
],
|
||||
})
|
||||
sideStep = nextStep
|
||||
|
||||
// if they said rename, we loop again. otherwise
|
||||
if (nextStep !== 'rename') {
|
||||
|
@ -160,7 +123,7 @@ export const getChoices = async () => {
|
|||
initial: 0,
|
||||
})
|
||||
|
||||
return { template, name, manager, overwrite }
|
||||
return { name, manager, overwrite, sideStep }
|
||||
}
|
||||
|
||||
const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1)
|
||||
|
@ -209,111 +172,6 @@ const copyFileOrTemplate = async (
|
|||
}
|
||||
}
|
||||
|
||||
// Template the package.json
|
||||
const copyPackageJson = async (config, choices) => {
|
||||
const packageJsonTemplate = await readFile(
|
||||
config.relativeFiles.templates['package.json'],
|
||||
'utf-8'
|
||||
)
|
||||
|
||||
await copyFileOrTemplate(packageJsonTemplate, config.dest, 'package.json', {
|
||||
name: choices.name,
|
||||
tag: config.tag,
|
||||
dependencies: config.templateData.dependencies,
|
||||
includeTests: choices.includeTests,
|
||||
})
|
||||
}
|
||||
|
||||
// Template the design index file
|
||||
const copyIndexFile = async (config, choices) => {
|
||||
// Template the index file
|
||||
const indexTemplate = await readFile(config.relativeFiles.templates['index'], 'utf-8')
|
||||
|
||||
// get the part names based on how they are given in the configuration
|
||||
const partNames = config.complexParts
|
||||
? config.templateData.parts.map((p) => p.part)
|
||||
: config.templateData.parts
|
||||
// write the file
|
||||
await copyFileOrTemplate(
|
||||
indexTemplate,
|
||||
config.dest,
|
||||
`${designSrcDir}/index.mjs`,
|
||||
{
|
||||
name: choices.name,
|
||||
Name: capitalize(choices.name),
|
||||
parts: partNames,
|
||||
},
|
||||
choices.overwrite
|
||||
)
|
||||
}
|
||||
|
||||
// Template the part files
|
||||
const copyPartFiles = async (config, choices) => {
|
||||
// Template the parts
|
||||
const partTemplate = await readFile(config.relativeFiles.templates.part, 'utf-8')
|
||||
// does this design inherit from another?
|
||||
const doesInherit = !config.templateData.noInheritance
|
||||
|
||||
// all part templates need these arguments
|
||||
const baseConfig = {
|
||||
name: choices.name, // the name of the design
|
||||
doesInherit, // whether it's an inherited design
|
||||
draftUses: {}, // what parameters need to be uncommented in the draft method (default none because part is always uncommented)
|
||||
}
|
||||
|
||||
// if it inherits, we also need the name of the design it inherits from
|
||||
if (doesInherit) {
|
||||
baseConfig.baseName = choices.template
|
||||
baseConfig.BaseName = capitalize(choices.template)
|
||||
}
|
||||
|
||||
// for each part
|
||||
return config.templateData.parts.map((p) => {
|
||||
// set up the arguments based on what's in the part's config
|
||||
const templateArgs = config.complexParts
|
||||
? {
|
||||
...baseConfig,
|
||||
...p,
|
||||
}
|
||||
: {
|
||||
...baseConfig,
|
||||
part: p,
|
||||
}
|
||||
|
||||
// add an uppercase version of the partName
|
||||
templateArgs.Part = capitalize(templateArgs.part)
|
||||
|
||||
// write the part file
|
||||
return copyFileOrTemplate(
|
||||
partTemplate,
|
||||
config.dest,
|
||||
`${designSrcDir}/${templateArgs.part}.mjs`,
|
||||
templateArgs,
|
||||
choices.overwrite
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Helper method to copy template files
|
||||
const copyAll = async (config, choices) => {
|
||||
let promises = []
|
||||
|
||||
// Copy shared files
|
||||
promises = promises.concat(
|
||||
config.relativeFiles.shared.map((from) => {
|
||||
if (choices.includeTests || !from.match(/e2e|playwright/))
|
||||
copyFileOrTemplate(config.source.shared, config.dest, from)
|
||||
})
|
||||
)
|
||||
|
||||
// template design files
|
||||
promises.push(copyPackageJson(config, choices))
|
||||
promises.push(copyIndexFile(config, choices))
|
||||
promises = promises.concat(copyPartFiles(config, choices))
|
||||
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
// Helper method to run [yarn|npm] install
|
||||
const installDependencies = async (config, choices) =>
|
||||
await execa(`${choices.manager} install`, {
|
||||
|
@ -322,22 +180,28 @@ const installDependencies = async (config, choices) =>
|
|||
})
|
||||
|
||||
// Helper method to download web environment
|
||||
const downloadLabFiles = async (config) => {
|
||||
const downloadFiles = async (config) => {
|
||||
const promises = []
|
||||
for (const dir in config.fetch) {
|
||||
promises.push(
|
||||
...config.fetch[dir].map(async (file) => {
|
||||
const to = typeof file === 'string' ? join(config.dest, file) : join(config.dest, file.to)
|
||||
const to =
|
||||
typeof file === 'string'
|
||||
? join(config.dest, file.slice(0, 4) === 'sde/' ? file.slice(4) : file)
|
||||
: join(config.dest, file.to)
|
||||
await ensureDir(to)
|
||||
try {
|
||||
const res = await axios.get(
|
||||
`${config.fileUri}/${config.repo}/${config.branch}/${dir}/${
|
||||
const url = `${config.fileUri}/${config.repo}/${config.branch}/${dir}/${
|
||||
typeof file === 'string' ? file : file.from
|
||||
}`
|
||||
try {
|
||||
const res = await axios.get(url)
|
||||
await writeFile(
|
||||
to,
|
||||
typeof res.data === 'object' ? JSON.stringify(res.data, null, 2) : res.data
|
||||
)
|
||||
await writeFile(to, res.data)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
if (err.response?.status === 404) console.log(`404: ${url}`)
|
||||
else console.log(err)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
@ -351,7 +215,7 @@ const initGitRepo = async (config, choices) => {
|
|||
await copyFileOrTemplate(config.gitignore, config.dest, '.gitignore', {}, choices.overwrite)
|
||||
|
||||
return execa(
|
||||
`git init -b main && git add . && git commit -m ":tada: Initialized ${choices.name} repository"`,
|
||||
`git init -b main && git add . && git commit -m ":tada: Initialized FreeSewing stand-alone development environment"`,
|
||||
{
|
||||
cwd: config.dest,
|
||||
shell: true,
|
||||
|
@ -360,13 +224,13 @@ const initGitRepo = async (config, choices) => {
|
|||
}
|
||||
|
||||
// Tips
|
||||
const showTips = (config, choices) => {
|
||||
const showTips = (config, choices) =>
|
||||
console.log(`
|
||||
All done 🤓 Your new design ${chalk.yellow.bold(
|
||||
choices.name
|
||||
)} was initialized in: ${chalk.green.bold(config.dest)}
|
||||
All done 🤓 Your FreeSewing development environment was initialized in: ${chalk.green.bold(
|
||||
config.dest
|
||||
)}
|
||||
|
||||
The code for your design is in the ${chalk.yellow.bold('design')} folder.
|
||||
The templates for various designs are in the ${chalk.yellow.bold('design')} folder.
|
||||
The other files and folders are the development environment. You can safely ignore those.
|
||||
|
||||
To start your development environment, follow these three steps:
|
||||
|
@ -377,41 +241,12 @@ const showTips = (config, choices) => {
|
|||
)}
|
||||
3) Now open your browser and navigate to ${chalk.green('http://localhost:8000/')}
|
||||
|
||||
${chalk.bold.yellow('🤔 More info & help')}
|
||||
${chalk.gray('≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡')}`)
|
||||
|
||||
if (choices.template === 'tutorial')
|
||||
console.log(`
|
||||
Our pattern design tutorial is available at: ${chalk.green(
|
||||
'https://freesewing.dev/tutorials/pattern-design'
|
||||
)}
|
||||
|
||||
It will walk your through the process step by step.
|
||||
If you get stuck, reach out to our community on Discord: ${chalk.green(
|
||||
'https://discord.freesewing.dev/'
|
||||
)}
|
||||
The ${chalk.bold('development-help')} channel is a good place to ask questions
|
||||
|
||||
Don't be shy to reach out. If something is not clear, that's on us, not on you.
|
||||
So your feedback really helps us improve our tutorial/documentation.
|
||||
|
||||
Thanks for giving FreeSewing a shot. We hope you'll 💜 it.
|
||||
Thanks for giving FreeSewing a shot. I hope you'll 💜 it.
|
||||
|
||||
Have fun 🤓
|
||||
|
||||
joost
|
||||
`)
|
||||
else
|
||||
console.log(`
|
||||
|
||||
FreeSewing's documentation for developers is available at: ${chalk.green(
|
||||
'https://freesewing.dev/'
|
||||
)}
|
||||
|
||||
Our community is on Discord: ${chalk.green('https://discord.freesewing.dev/')}
|
||||
The ${chalk.bold('development-help')} channel is a good place to ask for help if you get stuck
|
||||
|
||||
Happy hacking 🤓
|
||||
`)
|
||||
}
|
||||
|
||||
// Creates the environment based on the user's choices
|
||||
export const createEnvironment = async (choices) => {
|
||||
|
@ -423,88 +258,61 @@ export const createEnvironment = async (choices) => {
|
|||
shared: join(newDesignDir, `shared`),
|
||||
}
|
||||
|
||||
// Create target directory
|
||||
await mkdir(config.dest, { recursive: true })
|
||||
|
||||
// get the template files in a dictionary
|
||||
const templates = {}
|
||||
const templateFiles = await rdir(config.source.templates)
|
||||
templateFiles.forEach((file) => {
|
||||
const relativeName = relative(config.source.templates, file).replace(/(\.mjs)*\.mustache/, '')
|
||||
templates[relativeName] = file
|
||||
})
|
||||
|
||||
config.relativeFiles = {
|
||||
templates,
|
||||
shared: (await rdir(config.source.shared)).map((file) => relative(config.source.shared, file)),
|
||||
}
|
||||
|
||||
config.templateData = await import(pathToFileURL(config.source.templateData))
|
||||
// does this base have parts with a lot of attending config?
|
||||
config.complexParts = typeof config.templateData.parts[0] === 'object'
|
||||
|
||||
// Output a linebreak
|
||||
console.log()
|
||||
|
||||
// Copy/Template files
|
||||
// Download files from GitHub
|
||||
try {
|
||||
await oraPromise(copyAll(config, choices), {
|
||||
await oraPromise(downloadFiles(config), {
|
||||
text:
|
||||
chalk.white.bold('🟨⬜⬜⬜ Copying template files') +
|
||||
chalk.white.dim(' | Just a moment'),
|
||||
successText: chalk.white.bold('🟩⬜⬜⬜ Copied template files'),
|
||||
chalk.white.bold('🟧⬜⬜ Downloading components from GitHub') +
|
||||
chalk.white.dim(' | Almost there'),
|
||||
successText: chalk.white.bold('🟩⬜⬜ Downloaded components from GitHub'),
|
||||
failText: chalk.white.bold(
|
||||
'🟥⬜⬜⬜ Failed to copy template files | Development environment will not function'
|
||||
'🟥⬜⬜ Failed to download components from GitHub | The development environment will not function'
|
||||
),
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
/* no feedback here */
|
||||
}
|
||||
|
||||
if (!choices.sideStep) {
|
||||
// Create target directory
|
||||
await mkdir(config.dest, { recursive: true })
|
||||
|
||||
// Install dependencies
|
||||
try {
|
||||
await oraPromise(installDependencies(config, choices), {
|
||||
text:
|
||||
chalk.white.bold('🟩🟨⬜⬜ Installing dependencies') +
|
||||
chalk.white.bold('🟩🟧⬜ Installing dependencies') +
|
||||
chalk.white.dim(' | Please wait, this will take a while'),
|
||||
successText: chalk.white.bold('🟩🟩⬜⬜ Installed dependencies'),
|
||||
successText: chalk.white.bold('🟩🟩⬜ Installed dependencies'),
|
||||
failText: chalk.white.bold(
|
||||
'🟩🟥⬜⬜ Failed to install dependencies | Development environment will not function'
|
||||
'🟩🟥⬜ Failed to install dependencies | The development environment will not function'
|
||||
),
|
||||
})
|
||||
} catch (err) {
|
||||
/* no feedback here */
|
||||
}
|
||||
|
||||
// Fetch web components
|
||||
try {
|
||||
await oraPromise(downloadLabFiles(config), {
|
||||
text:
|
||||
chalk.white.bold('🟩🟩🟨⬜ Downloading web components') +
|
||||
chalk.white.dim(' | Almost there'),
|
||||
successText: chalk.white.bold('🟩🟩🟩⬜ Downloaded web components'),
|
||||
failText: chalk.white.bold(
|
||||
'🟩🟩🟥⬜ Failed to download web components | Development environment will not function'
|
||||
),
|
||||
})
|
||||
} catch (err) {
|
||||
/* no feedback here */
|
||||
}
|
||||
|
||||
if (!choices.sideStep) {
|
||||
// Initialize git repository
|
||||
try {
|
||||
await oraPromise(initGitRepo(config, choices), {
|
||||
text:
|
||||
chalk.white.bold('🟩🟩🟩⬜ Initializing git repository') +
|
||||
chalk.white.bold('🟩🟩🟧 Initializing git repository') +
|
||||
chalk.white.dim(' | You have git, right?'),
|
||||
successText: chalk.white.bold('🟩🟩🟩🟩 Initialized git repository'),
|
||||
successText: chalk.white.bold('🟩🟩🟩 Initialized git repository'),
|
||||
failText:
|
||||
chalk.white.bold('🟩🟩🟩🟥 Failed to initialize git repository') +
|
||||
chalk.white.dim(' | This does not stop you from developing your design'),
|
||||
chalk.white.bold('🟩🟩🟥 Failed to initialize git repository') +
|
||||
chalk.white.dim(' | This does not stop the development environment from functioning'),
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
|
||||
// All done. Show tips
|
||||
showTips(config, choices)
|
||||
|
|
|
@ -2,16 +2,25 @@ import rdir from 'recursive-readdir'
|
|||
import path from 'path'
|
||||
|
||||
const ignore = [
|
||||
'package.json',
|
||||
'node_modules',
|
||||
'.eslint',
|
||||
'.gitignore',
|
||||
'.md',
|
||||
'lab/components/header.js',
|
||||
'lab/components/help-us.js',
|
||||
'lab/components/search.js',
|
||||
'lab/components/footer.js',
|
||||
'.next',
|
||||
'prebuild.mjs',
|
||||
'prebuild',
|
||||
'public/locales',
|
||||
'shared/config/measurements.js',
|
||||
'sde/public/android-chrome-192x192.png',
|
||||
'sde/public/android-chrome-384x384.png',
|
||||
'sde/public/apple-touch-icon.png',
|
||||
'sde/public/browserconfig.xml',
|
||||
'sde/public/favicon-16x16.png',
|
||||
'sde/public/favicon-32x32.png',
|
||||
'sde/public/favicon.ico',
|
||||
'sde/public/mstile-150x150.png',
|
||||
'sde/public/safari-pinned-tab.svg',
|
||||
'sde/public/site.webmanifest',
|
||||
]
|
||||
|
||||
const getFiles = async (dir) => {
|
||||
|
@ -28,9 +37,9 @@ const getFiles = async (dir) => {
|
|||
|
||||
const doIt = async () => {
|
||||
let files = []
|
||||
const shared = await getFiles('../../sites/shared')
|
||||
const lab = await getFiles('../../sites/lab/components')
|
||||
console.log(JSON.stringify([...shared, ...lab], null, 2))
|
||||
const sde = await getFiles('../../sites/sde')
|
||||
const shared = await getFiles('../../sites/shared/config')
|
||||
console.log(JSON.stringify([...shared, ...sde], null, 2))
|
||||
}
|
||||
|
||||
doIt()
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test('Compiles and drafts', async ({ page }) => {
|
||||
await page.goto('http://localhost:8000/design')
|
||||
|
||||
await page.waitForSelector('main')
|
||||
if (await page.getByRole('heading', { name: 'Preload a set of measurements' }).isVisible()) {
|
||||
await page
|
||||
.getByRole('list')
|
||||
.filter({ hasText: 'Size 28Size 30Size 32Size 34Size 36Size 38Size 40Size 42Size 44Size 46' })
|
||||
.getByRole('button', { name: 'Size 36' })
|
||||
.click()
|
||||
await page.getByTitle('draftDesign').click()
|
||||
}
|
||||
|
||||
await expect(page.getByText('Something went wrong')).toHaveCount(0)
|
||||
await expect(page.getByText('Unhandled Runtime Error')).toHaveCount(0)
|
||||
await expect(page.getByTitle('Measurements')).toBeVisible()
|
||||
})
|
|
@ -1,145 +0,0 @@
|
|||
// Hooks
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { FreeSewingLogo } from 'shared/components/logos/freesewing.mjs'
|
||||
import { OsiLogo } from 'shared/components/logos/osi.mjs'
|
||||
import { CCLogo } from 'shared/components/logos/cc.mjs'
|
||||
import { CCByLogo } from 'shared/components/logos/cc-by.mjs'
|
||||
import { Ribbon } from 'shared/components/ribbon.mjs'
|
||||
import { WordMark } from 'shared/components/wordmark.mjs'
|
||||
import {
|
||||
DiscordIcon,
|
||||
FacebookIcon,
|
||||
GithubIcon,
|
||||
InstagramIcon,
|
||||
RedditIcon,
|
||||
TwitterIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
|
||||
// Classes
|
||||
const link = 'text-secondary font-bold hover:pointer hover:underline px-1'
|
||||
const accent = 'text-accent font-bold text-lg px-1 block sm:inline'
|
||||
const freesewing = 'px-1 text-lg font-bold block sm:inline'
|
||||
|
||||
// Keep these translations in the component because they're only used here
|
||||
const translations = {
|
||||
cc: (
|
||||
<span>
|
||||
Content on FreeSewing.org is available under{' '}
|
||||
<a className={link} href="https://creativecommons.org/licenses/by/4.0/">
|
||||
a Creative Commons license
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
mit: (
|
||||
<span>
|
||||
The FreeSewing source code is{' '}
|
||||
<a href="https://github.com/freesewing/freesewing" className={link}>
|
||||
available on Github
|
||||
</a>{' '}
|
||||
under{' '}
|
||||
<a href="https://opensource.org/licenses/MIT" className={link}>
|
||||
the MIT license
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
sponsors: (
|
||||
<>
|
||||
<span className={freesewing}>FreeSewing</span> is sponsored by these{' '}
|
||||
<span className={accent}>awesome companies</span>
|
||||
</>
|
||||
),
|
||||
}
|
||||
|
||||
const icon = { className: 'w-8 lg:w-12 h-8 lg:h-12' }
|
||||
const social = {
|
||||
Discord: {
|
||||
icon: <DiscordIcon {...icon} />,
|
||||
href: 'https://discord.freesewing.org/',
|
||||
},
|
||||
Instagram: {
|
||||
icon: <InstagramIcon {...icon} />,
|
||||
href: 'https://instagram.com/freesewing_org',
|
||||
},
|
||||
Facebook: {
|
||||
icon: <FacebookIcon {...icon} />,
|
||||
href: 'https://www.facebook.com/groups/627769821272714/',
|
||||
},
|
||||
Github: {
|
||||
icon: <GithubIcon {...icon} />,
|
||||
href: 'https://github.com/freesewing',
|
||||
},
|
||||
Reddit: {
|
||||
icon: <RedditIcon {...icon} />,
|
||||
href: 'https://www.reddit.com/r/freesewing/',
|
||||
},
|
||||
Twitter: {
|
||||
icon: <TwitterIcon {...icon} />,
|
||||
href: 'https://twitter.com/freesewing_org',
|
||||
},
|
||||
}
|
||||
|
||||
export const Footer = ({ app }) => {
|
||||
const { t } = useTranslation(['common', 'patrons'])
|
||||
|
||||
return (
|
||||
<footer className="bg-neutral">
|
||||
<Ribbon loading={app.loading} theme={app.theme} />
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 py-12 2xl:py-20 text-neutral-content px-4">
|
||||
{/* First col - CC & MIT */}
|
||||
<div className="mb-20 order-1 mt-20 2xl:mt-0 2xl:mb-0">
|
||||
<div className="max-w-md m-auto">
|
||||
<div>
|
||||
<CCLogo className="w-64 m-auto" />
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-center items-center mt-8">
|
||||
<CCByLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{translations.cc}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-center items-center mt-4">
|
||||
<OsiLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{translations.mit}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Second col - Social & Sponsors */}
|
||||
<div className="lg:col-span-2 -order-2 2xl:order-2 px-4 lg:px-0">
|
||||
{/* Social icons */}
|
||||
<div className="w-full sm:w-auto flex flex-row flex-wrap gap-4 lg:gap-8 items-center justify-center">
|
||||
{Object.keys(social).map((item) => (
|
||||
<Link
|
||||
key={item}
|
||||
href={social[item].href}
|
||||
className="hover:text-secondary hover:-mt-2 transition-all"
|
||||
title={item}
|
||||
>
|
||||
{social[item].icon}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Col 3 - Logo & Slogan */}
|
||||
<div className="w-full 4xl:w-auto xl:max-w-md mb-8 text-center order-3 mt-0 lg:mt-20 2xl:mt-0 2xl:mb-0">
|
||||
<div className="max-w-md m-auto">
|
||||
<FreeSewingLogo stroke="none" size={164} className="w-40 lg:w-64 m-auto m-auto" />
|
||||
<h5 className="lg:text-3xl mt-4">
|
||||
<WordMark />
|
||||
</h5>
|
||||
<p className="bold text-neutral-content text-normal lg:text-xl leading-5">
|
||||
{t('sloganCome')}
|
||||
<br />
|
||||
{t('sloganStay')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { ModalThemePicker } from 'shared/components/modal/theme-picker.mjs'
|
||||
import { ModalLocalePicker } from 'shared/components/modal/locale-picker.mjs'
|
||||
import { CloseIcon, MenuIcon, HelpIcon, DocsIcon } from 'shared/components/icons/close.js'
|
||||
import { Ribbon } from 'shared/components/ribbon.js'
|
||||
import { WordMark } from 'shared/components/wordmark.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
const btnClasses =
|
||||
'btn btn-ghost text-base font-medium btn-sm text-neutral-content ' +
|
||||
' capitalize hover:bg-transparent hover:text-secondary-focus'
|
||||
|
||||
export const Header = ({ app }) => {
|
||||
const { t } = useTranslation(['common'])
|
||||
|
||||
const [prevScrollPos, setPrevScrollPos] = useState(0)
|
||||
const [show, setShow] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const handleScroll = () => {
|
||||
const curScrollPos = typeof window !== 'undefined' ? window.pageYOffset : 0
|
||||
if (curScrollPos >= prevScrollPos) {
|
||||
if (show && curScrollPos > 20) setShow(false)
|
||||
} else setShow(true)
|
||||
setPrevScrollPos(curScrollPos)
|
||||
}
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [prevScrollPos, show])
|
||||
|
||||
return (
|
||||
<header
|
||||
className={`
|
||||
fixed top-0 left-0
|
||||
bg-neutral
|
||||
w-full
|
||||
z-30
|
||||
transition-transform
|
||||
${show ? '' : 'fixed top-0 left-0 -translate-y-20'}
|
||||
`}
|
||||
>
|
||||
<div>
|
||||
<div className="p-2 flex flex-row justify-between text-neutral-content">
|
||||
<div className="flex flex-row items-center">
|
||||
<button
|
||||
className={`
|
||||
btn btn-sm btn-ghost
|
||||
text-neutral-content bg-transparent
|
||||
hover:text-secondary-focus
|
||||
lg:hidden
|
||||
`}
|
||||
onClick={app.togglePrimaryMenu}
|
||||
>
|
||||
{app.primaryMenu ? <CloseIcon /> : <MenuIcon />}
|
||||
</button>
|
||||
<WordMark />
|
||||
<div className="hidden md:flex flex-row items-center">
|
||||
<a role="button" className={btnClasses} href="https://freesewing.dev/">
|
||||
<DocsIcon />
|
||||
<span className="ml-2">{t('docs')}</span>
|
||||
</a>
|
||||
<Link href="/support" role="button" className={btnClasses}>
|
||||
<>
|
||||
<HelpIcon />
|
||||
<span className="ml-2">{t('support')}</span>
|
||||
</>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:flex flex-row items-center gap-2">
|
||||
<ModalThemePicker app={app} />
|
||||
<ModalLocalePicker app={app} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Ribbon loading={app.loading} theme={app.theme} />
|
||||
</header>
|
||||
)
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import { AsideNavigation } from 'shared/components/navigation/aside.mjs'
|
||||
import { BeforeNav } from './lab'
|
||||
|
||||
export const DefaultLayout = ({ app, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
|
||||
return (
|
||||
<>
|
||||
<AsideNavigation app={app} slug={slug} before={<BeforeNav app={app} />} mobileOnly />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import React from 'react'
|
||||
import { AsideNavigation } from 'shared/components/navigation/aside.mjs'
|
||||
|
||||
export const HomeLayout = ({ app, title = false, children = [] }) => (
|
||||
<div className="max-w-7xl m-auto mt-32">
|
||||
{title && <h1 className="capitalize">{title}</h1>}
|
||||
<AsideNavigation app={app} mobileOnly />
|
||||
{children}
|
||||
</div>
|
||||
)
|
|
@ -1,44 +0,0 @@
|
|||
import { ModalThemePicker } from 'shared/components/modal/theme-picker.mjs'
|
||||
import { ModalLocalePicker } from 'shared/components/modal/locale-picker.mjs'
|
||||
|
||||
export const BeforeNav = ({ app }) => (
|
||||
<>
|
||||
<div className="md:hidden flex flex-row flex-wrap sm:flex-nowrap gap-2 mb-2">
|
||||
<ModalThemePicker app={app} />
|
||||
<ModalLocalePicker app={app} />
|
||||
</div>
|
||||
<div className="md:hidden flex flex-row flex-wrap sm:flex-nowrap gap-2 mb-2"></div>
|
||||
</>
|
||||
)
|
||||
|
||||
export const LabLayout = ({ app, AltMenu, children = [] }) => (
|
||||
<div className="py-24 lg:py-36 flex flex-row">
|
||||
<div className="w-full px-8">{children}</div>
|
||||
<aside
|
||||
className={`
|
||||
fixed top-0 right-0
|
||||
pt-20 pb-8 px-8
|
||||
md:pt-0
|
||||
md:relative md:transform-none
|
||||
h-screen w-screen
|
||||
bg-base-100
|
||||
md:bg-base-50
|
||||
md:flex
|
||||
md:sticky
|
||||
overflow-y-scroll
|
||||
z-20
|
||||
bg-base-100 text-base-content
|
||||
transition-all
|
||||
xl:w-1/4
|
||||
${app.primaryMenu ? '' : 'translate-x-[-100%]'} transition-transform
|
||||
md:flex-row
|
||||
md:w-80
|
||||
lg:w-96
|
||||
shrink-0
|
||||
`}
|
||||
>
|
||||
<BeforeNav app={app} />
|
||||
{AltMenu}
|
||||
</aside>
|
||||
</div>
|
||||
)
|
|
@ -1,4 +0,0 @@
|
|||
// Noop placeholder
|
||||
const Noop = () => null
|
||||
|
||||
export default Noop
|
|
@ -1,56 +0,0 @@
|
|||
import { useState } from 'react'
|
||||
// Locale and translation
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTheme } from 'shared/hooks/useTheme.mjs'
|
||||
|
||||
export const useApp = () => {
|
||||
// Load translation method
|
||||
const locale = useRouter().locale
|
||||
|
||||
// Persistent state
|
||||
const [theme, setTheme] = useTheme()
|
||||
|
||||
// React State
|
||||
const [primaryMenu, setPrimaryMenu] = useState(false)
|
||||
const [navigation, setNavigation] = useState({})
|
||||
const [slug, setSlug] = useState('/')
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
// State methods
|
||||
const togglePrimaryMenu = () => setPrimaryMenu(!primaryMenu)
|
||||
|
||||
return {
|
||||
// Static vars
|
||||
site: 'lab',
|
||||
|
||||
// i18n
|
||||
locale,
|
||||
|
||||
// State
|
||||
loading,
|
||||
navigation,
|
||||
primaryMenu,
|
||||
slug,
|
||||
theme,
|
||||
|
||||
// State setters
|
||||
setLoading,
|
||||
setNavigation,
|
||||
setPrimaryMenu,
|
||||
setSlug,
|
||||
setTheme,
|
||||
startLoading: () => {
|
||||
setLoading(true)
|
||||
setPrimaryMenu(false)
|
||||
}, // Always close menu when navigating
|
||||
stopLoading: () => setLoading(false),
|
||||
|
||||
// State handlers
|
||||
togglePrimaryMenu,
|
||||
|
||||
// Standalone is for the development environment
|
||||
standalone: true,
|
||||
}
|
||||
}
|
||||
|
||||
export default useApp
|
|
@ -1,13 +0,0 @@
|
|||
// See: https://github.com/isaachinman/next-i18next
|
||||
module.exports = {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'de', 'es', 'fr', 'nl'],
|
||||
defaultNS: 'common',
|
||||
},
|
||||
interpolation: {
|
||||
prefix: '{',
|
||||
suffix: '}',
|
||||
},
|
||||
localeStructure: '{lng}/{ns}',
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import path from 'path'
|
||||
import i18nConfig from './next-i18next.config.js'
|
||||
|
||||
const config = {
|
||||
i18n: i18nConfig.i18n,
|
||||
pageExtensions: ['mjs'],
|
||||
webpack: (config, options) => {
|
||||
// Aliases
|
||||
config.resolve.alias.shared = path.resolve('./shared/')
|
||||
config.resolve.alias.site = path.resolve('./lab/')
|
||||
config.resolve.alias.design = path.resolve('./design/')
|
||||
|
||||
return config
|
||||
},
|
||||
}
|
||||
export default config
|
|
@ -1,6 +0,0 @@
|
|||
import 'shared/styles/globals.css'
|
||||
import { appWithTranslation } from 'next-i18next'
|
||||
|
||||
const FreeSewingLab = ({ Component, pageProps }) => <Component {...pageProps} />
|
||||
|
||||
export default appWithTranslation(FreeSewingLab)
|
|
@ -1,26 +0,0 @@
|
|||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { Pattern } from 'design/src/index.mjs'
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { LabLayout } from 'site/components/layouts/lab.mjs'
|
||||
import { WorkbenchWrapper } from 'shared/components/wrappers/workbench.mjs'
|
||||
|
||||
const WorkbenchPage = () => {
|
||||
const app = useApp()
|
||||
|
||||
return (
|
||||
<PageWrapper app={app}>
|
||||
<WorkbenchWrapper {...{ app, design: Pattern, layout: LabLayout }} />
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default WorkbenchPage
|
||||
|
||||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useRouter } from 'next/router'
|
||||
import Link from 'next/link'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { HomeLayout } from 'site/components/layouts/home.mjs'
|
||||
import { FreeSewingIcon } from 'shared/components/icons.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import themes from 'shared/themes/index.js'
|
||||
|
||||
const translations = {
|
||||
sade: {
|
||||
en: `Stand-alone development environment`,
|
||||
nl: `Vrijstaande ontwikkeling omgeving`,
|
||||
},
|
||||
load: {
|
||||
en: `To your design`,
|
||||
nl: `Naar jouw ontwerp`,
|
||||
},
|
||||
tips: {
|
||||
en: (
|
||||
<Popout tip compact>
|
||||
Edit the files in the <strong>design</strong> folder, and we'll auto-update your design
|
||||
</Popout>
|
||||
),
|
||||
nl: (
|
||||
<Popout tip compact>
|
||||
Bewerk de bestanden in de <strong>design</strong> map, en we passen je ontwerp automatisch
|
||||
aan
|
||||
</Popout>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
const HomePage = () => {
|
||||
const app = useApp()
|
||||
const router = useRouter()
|
||||
const { t } = useTranslation(['common', 'patrons', 'locales', 'themes'])
|
||||
|
||||
return (
|
||||
<PageWrapper app={app} title={false} layout={HomeLayout}>
|
||||
<div className="text-center w-full pt-20 pb-10 max-w-4xl m-auto">
|
||||
<FreeSewingIcon className="w-96 m-auto" />
|
||||
<h1>FreeSewing</h1>
|
||||
<h4>{translations.sade[app.locale]}</h4>
|
||||
<Link href="/design" className="btn btn-primary btn-lg h-20 my-8 mb-12">
|
||||
<>
|
||||
<span role="image" className="text-4xl px-6">
|
||||
👉
|
||||
</span>
|
||||
<span className="text-xl px-2">{translations.load[app.locale]}</span>
|
||||
<span role="image" className="text-4xl px-6">
|
||||
👈
|
||||
</span>
|
||||
</>
|
||||
</Link>
|
||||
{translations.tips[app.locale]}
|
||||
</div>
|
||||
<div className="flex flex-row flex-wrap gap-4 w-full max-w-4xl m-auto justify-center">
|
||||
{router.locales.map((locale) => (
|
||||
<Link
|
||||
href={router.asPath}
|
||||
locale={locale}
|
||||
key={locale}
|
||||
className="btn btn-ghost text-base-content hover:bg-base-200"
|
||||
>
|
||||
<span className="text-base-content">{t(`locales:${locale}`)}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-row flex-wrap gap-4 w-full max-w-4xl m-auto justify-center mt-4">
|
||||
{Object.keys(themes).map((theme) => (
|
||||
<button
|
||||
key={theme}
|
||||
onClick={() => app.setTheme(theme)}
|
||||
className="btn btn-ghost hover:bg-base-200"
|
||||
>
|
||||
<span className="text-base-content">{t(`themes:${theme}Theme`)}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="py-20">
|
||||
<h2>{t('patrons:supportFreesewing')}</h2>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<div>
|
||||
<p className="max-w-3xl">{t('patrons:patronLead')}</p>
|
||||
<p className="max-w-3xl">{t('patrons:patronPitch')}</p>
|
||||
</div>
|
||||
<a className="btn btn-accent btn-lg ">
|
||||
<span role="image" className="text-4xl px-4">
|
||||
🥰
|
||||
</span>
|
||||
<span className="px-2">{t('patrons:becomeAPatron')}</span>
|
||||
<span role="image" className="text-4xl px-4">
|
||||
🙏🏻
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{/* here to force Tailwind inclusion of the w-8 h-8 classes */}
|
||||
<span className="w-8 h-8" />
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default HomePage
|
||||
|
||||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { DefaultLayout } from 'site/components/layouts/default.mjs'
|
||||
import { DiscordIcon, GithubIcon, CcIcon, HeartIcon, DocsIcon } from 'shared/components/icons/docs'
|
||||
|
||||
const gh = `<a class="text-secondary hover:text-secondary-focus"
|
||||
href="https://github.com/freesewing/freesewing">freesewing/freesewing</a>`
|
||||
const fsd = `<a class="text-secondary hover:text-secondary-focus"
|
||||
href="https://freesewing.dev">freesewing.dev</a>`
|
||||
|
||||
const translations = {
|
||||
discord: {
|
||||
en: `Our Discord server on is the best place to ask questions, or hang
|
||||
out with other members of the FreeSewing community.`,
|
||||
nl: `Onze Discord server is de best plek om vragen te stellen, hulp te ontvangen,
|
||||
of gewoon een leuke tijd te spenderen met andere leden van de FreeSewing gemeenschap.`,
|
||||
},
|
||||
github: {
|
||||
en: `For bug reports, please create an issue in the ${gh} repository on Github.
|
||||
This is also where you'll find all our source code.`,
|
||||
nl: `Een bug gevonden? Maak dan een issue aan in de ${gh} repository op Github.
|
||||
Dit is ook waar je al de FreeSewing broncode kan vinden.`,
|
||||
},
|
||||
cc: {
|
||||
en: `Every two weeks, there's the FreeSewing contributor call, which is when we discuss
|
||||
ongoing issues, future plans, and news big and small about FreeSewing and its community.`,
|
||||
nl: `Elke twee weken is er de FreeSewing contributor call (Engelstalig), waar de FreeSewing
|
||||
vrijwilligers de lopende zaken bespreken. Ook de plannen voor de toekomst en groot en klein
|
||||
nieuws over FreeSewing en de gemeenschap komen aan bod.`,
|
||||
},
|
||||
docs: {
|
||||
en: `Our documentation for developers hosted on ${fsd}. You can find guides and how-to's
|
||||
there, as well as reference documantation for FreeSewing's core API.
|
||||
<br /> <br />
|
||||
We stive to provide excellent documentation. So if something is not clear please, let us know.`,
|
||||
nl: `Onze documentatie voor ontwikkelaars is beschikbaar op ${fsd}. Je vindt er guides en how-to's,
|
||||
alsook de referentie documentatie voor FreeSewing's core API.
|
||||
<br /> <br />
|
||||
We streven ernaar om uitstekende documentatie te voorzien. Dus als er iets niet duidelijk is, laat
|
||||
het ons dan zeker weten.`,
|
||||
},
|
||||
}
|
||||
|
||||
const SupportPage = () => {
|
||||
const app = useApp()
|
||||
const { t } = useTranslation(['common', 'patrons'])
|
||||
return (
|
||||
<PageWrapper app={app} title={t('support')} layout={DefaultLayout}>
|
||||
<h2 className="border-0">Discord</h2>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<p className="max-w-3xl">{translations.discord[app.locale]}</p>
|
||||
<a className="btn btn-primary btn-lg w-96" href="https://discord.freesewing.org/">
|
||||
<DiscordIcon />
|
||||
<span className="ml-4">discord.freesewing.org</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h2 className="border-0">Github</h2>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<p
|
||||
className="max-w-3xl"
|
||||
dangerouslySetInnerHTML={{ __html: translations.github[app.locale] }}
|
||||
/>
|
||||
<a
|
||||
className="btn btn-primary btn-outline btn-lg w-96"
|
||||
href="https://github.com/freesewing/freesewing"
|
||||
>
|
||||
<GithubIcon />
|
||||
<span className="ml-4">github.com/freesewing</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h2 className="border-0">{t('docs')}</h2>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<p
|
||||
className="max-w-3xl"
|
||||
dangerouslySetInnerHTML={{ __html: translations.docs[app.locale] }}
|
||||
/>
|
||||
<a className="btn btn-primary btn-outline btn-lg w-96" href="https://freesewing.dev/">
|
||||
<DocsIcon />
|
||||
<span className="ml-4">www.FreeSewing.dev</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h2 className="border-0">Contributor Calls</h2>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<p
|
||||
className="max-w-3xl"
|
||||
dangerouslySetInnerHTML={{ __html: translations.cc[app.locale] }}
|
||||
/>
|
||||
<a
|
||||
className="btn btn-primary btn-outline btn-lg w-96"
|
||||
href="https://github.com/freesewing/freesewing/discussions?discussions_q=label%3A%22%3Atv%3A+fscc%22"
|
||||
>
|
||||
<CcIcon />
|
||||
<span className="ml-4">Contributor Calls</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="py-20">
|
||||
<h2 className="border-0">{t('patrons:supportFreesewing')}</h2>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<div>
|
||||
<p className="max-w-3xl">{t('patrons:patronLead')}</p>
|
||||
<p className="max-w-3xl">{t('patrons:patronPitch')}</p>
|
||||
</div>
|
||||
<a className="btn btn-accent btn-lg w-96">
|
||||
<HeartIcon className="fill-accent-content stroke-accent-content w-6 h-6" />
|
||||
<span className="ml-4">{t('patrons:becomeAPatron')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default SupportPage
|
||||
|
||||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
const { defineConfig, devices } = require('@playwright/test')
|
||||
|
||||
/**
|
||||
* @see https://playwright.dev/docs/test-configuration
|
||||
*/
|
||||
module.exports = defineConfig({
|
||||
testDir: './e2e',
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: 'html',
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
// baseURL: 'http://127.0.0.1:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
webServer: {
|
||||
command: 'yarn dev',
|
||||
url: 'http://127.0.0.1:8000',
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
|
||||
// {
|
||||
// name: 'firefox',
|
||||
// use: { ...devices['Desktop Firefox'] },
|
||||
// },
|
||||
|
||||
// {
|
||||
// name: 'webkit',
|
||||
// use: { ...devices['Desktop Safari'] },
|
||||
// },
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { ..devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
})
|
|
@ -1,5 +0,0 @@
|
|||
// Can't seem to make this work as ESM
|
||||
const config = require('./shared/config/postcss.config.js')
|
||||
|
||||
module.exports = config
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
import CopyToClipboard from 'shared/components/copy-to-clipboard'
|
||||
|
||||
const names = {
|
||||
json: 'JSON',
|
||||
yaml: 'YAML',
|
||||
}
|
||||
|
||||
const Highlight = (props) => {
|
||||
|
||||
let language = 'txt'
|
||||
if (props.language) language = props.language
|
||||
if (props.children?.props?.className) {
|
||||
language = props.children.props.className.split('-').pop()
|
||||
}
|
||||
const preProps = {
|
||||
className: `language-${language} hljs text-base lg:text-lg whitespace-pre overflow-scroll pr-4`
|
||||
}
|
||||
if (props.raw) preProps.dangerouslySetInnerHTML = { __html: props.raw }
|
||||
|
||||
return (
|
||||
<div className="hljs my-4">
|
||||
<div className={`
|
||||
flex flex-row justify-between
|
||||
text-xs uppercase font-bold text-neutral-content
|
||||
mt-1 border-b border-neutral-content border-opacity-25
|
||||
py-1 mb-2 lg:text-sm
|
||||
`}>
|
||||
<span> </span>
|
||||
<span>{names[language] ? names[language] : language}</span>
|
||||
<CopyToClipboard content={props.children} />
|
||||
</div>
|
||||
<pre {...preProps}>
|
||||
{props.children}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Highlight
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// Handle themes
|
||||
const themes = require('./shared/themes/index.js')
|
||||
|
||||
module.exports = {
|
||||
content: [
|
||||
'./pages/*.mjs',
|
||||
'./pages/**/*.mjs',
|
||||
'./shared/**/*.mjs',
|
||||
'./lab/**/*.mjs',
|
||||
// Legacy stuff, to be removed once everything is .mjs
|
||||
'./pages/*.js',
|
||||
'./pages/**/*.js',
|
||||
'./shared/**/*.js',
|
||||
'./lab/**/*.js',
|
||||
],
|
||||
plugins: [require('daisyui'), require('tailwindcss/nesting')],
|
||||
daisyui: {
|
||||
styled: true,
|
||||
themes: [themes],
|
||||
base: true,
|
||||
utils: true,
|
||||
logs: true,
|
||||
rtl: false,
|
||||
},
|
||||
theme: {
|
||||
extend: {
|
||||
aspectRatio: {
|
||||
'9/16': '9 / 16',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
export const parts = ['back', 'frontSideDart']
|
||||
export const dependencies = ['@freesewing/bella']
|
|
@ -1,2 +0,0 @@
|
|||
export const parts = ['back', 'front', 'topSleeve', 'underSleeve']
|
||||
export const dependencies = ['@freesewing/bent', '@freesewing/brian', '@freesewing/plugin-bust']
|
|
@ -1,2 +0,0 @@
|
|||
export const parts = ['back', 'front', 'sleeve']
|
||||
export const dependencies = ['@freesewing/breanna']
|
|
@ -1,2 +0,0 @@
|
|||
export const parts = ['back', 'front', 'sleeve']
|
||||
export const dependencies = ['@freesewing/brian', '@freesewing/plugin-bust']
|
|
@ -1,72 +0,0 @@
|
|||
export const noInheritance = true
|
||||
export const parts = [
|
||||
{
|
||||
part: 'box',
|
||||
// this part uses the pluginBundle
|
||||
pluginBundle: true,
|
||||
// options needs to be a string of the internals of the options object
|
||||
options: `size: { pct: 50, min: 10, max: 100 }`,
|
||||
// the draft method needs all of these parameters uncommented
|
||||
draftUses: {
|
||||
options: true,
|
||||
points: true,
|
||||
paths: true,
|
||||
Point: true,
|
||||
Path: true,
|
||||
complete: true,
|
||||
paperless: true,
|
||||
sa: true,
|
||||
snippets: true,
|
||||
Snippet: true,
|
||||
macro: true,
|
||||
},
|
||||
// the draft method
|
||||
draft: `// Add points to make a box
|
||||
const w = 500 * options.size
|
||||
points.topLeft = new Point(0, 0)
|
||||
points.topRight = new Point(w, 0)
|
||||
points.bottomLeft = new Point(0, w / 2)
|
||||
points.bottomRight = new Point(w, w / 2)
|
||||
|
||||
// Create a path for the box outline
|
||||
paths.seam = new Path()
|
||||
.move(points.topLeft)
|
||||
.line(points.bottomLeft)
|
||||
.line(points.bottomRight)
|
||||
.line(points.topRight)
|
||||
.line(points.topLeft)
|
||||
.close()
|
||||
.setClass('fabric')
|
||||
|
||||
// Complete?
|
||||
if (complete) {
|
||||
// Add a logo
|
||||
points.logo = points.topLeft.shiftFractionTowards(points.bottomRight, 0.5)
|
||||
snippets.logo = new Snippet('logo', points.logo)
|
||||
|
||||
// Add some text
|
||||
points.text = points.logo
|
||||
.shift(-90, w / 8)
|
||||
.addText('FreeSewing', 'center')
|
||||
|
||||
if (sa) {
|
||||
// Add seam allowance
|
||||
paths.sa = paths.seam.offset(sa).setClass('fabric sa')
|
||||
}
|
||||
}
|
||||
|
||||
// Add dimensions for paperless mode
|
||||
if (paperless) {
|
||||
macro('hd', {
|
||||
from: points.bottomLeft,
|
||||
to: points.bottomRight,
|
||||
y: points.bottomLeft.y + sa + 15,
|
||||
})
|
||||
macro('vd', {
|
||||
from: points.bottomRight,
|
||||
to: points.topRight,
|
||||
x: points.topRight.x + sa + 15,
|
||||
})
|
||||
}`,
|
||||
},
|
||||
]
|
|
@ -1,2 +0,0 @@
|
|||
export const parts = ['back', 'front']
|
||||
export const dependencies = ['@freesewing/titan', '@freesewing/snapseries']
|
|
@ -1,11 +0,0 @@
|
|||
export const noInheritance = true
|
||||
export const parts = [
|
||||
{
|
||||
part: 'bib',
|
||||
// no draft method
|
||||
draft: '',
|
||||
},
|
||||
]
|
||||
|
||||
// no additional dependencies
|
||||
export const dependencies = []
|
|
@ -1,38 +0,0 @@
|
|||
{{!
|
||||
// Change the Mustache delimiter from double curly braces to double dollar signs.
|
||||
// Dollar signs are allowed in EcmaScript identifier names,
|
||||
// which is helpful when running unrendered Mustache templates through eslint.
|
||||
//}}{{=$$ $$=}}
|
||||
// Import Design constructor
|
||||
import { Design } from '@freesewing/core'
|
||||
// Import parts
|
||||
$$#parts$$
|
||||
import { $$.$$ } from './$$.$$.mjs'
|
||||
$$/parts$$
|
||||
|
||||
// Create the new design
|
||||
const $$Name$$ = new Design({
|
||||
data: {
|
||||
/*
|
||||
* If you like, you can add any data you want to your design.
|
||||
* We'll add the name here as an example.
|
||||
*
|
||||
* If you don't use this,
|
||||
* you can remove this data key enterely.
|
||||
*/
|
||||
name: "$$ Name $$",
|
||||
},
|
||||
// A list of parts is all that is required.
|
||||
parts: [ $$parts$$ ],
|
||||
})
|
||||
|
||||
const Pattern = $$Name$$
|
||||
/*
|
||||
* Named exports
|
||||
*
|
||||
* We export the design itself as well as each part individually.
|
||||
* This allows us to re-use these parts in other designs.
|
||||
*/
|
||||
|
||||
export {$$#parts$$ $$.$$,$$/parts$$ $$Name$$, Pattern }
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
{{!
|
||||
// Change the Mustache delimiter from double curly braces to double dollar signs.
|
||||
// Dollar signs are allowed in EcmaScript identifier names,
|
||||
// which is helpful when running unrendered Mustache templates through eslint.
|
||||
//}}{{=$$ $$=}}
|
||||
{
|
||||
"name": "@freesewing/$$ name $$",
|
||||
"version": "0.0.1",
|
||||
"description": "A new FreeSewing design",
|
||||
"author": "Joost De Cock <joost@joost.at> (https://github.com/joostdecock)",
|
||||
"homepage": "https://freesewing.org/",
|
||||
"repository": "github:freesewing/freesewing",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/freesewing/freesewing/issues"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://freesewing.org/patrons/join"
|
||||
},
|
||||
"keywords": [
|
||||
"freesewing",
|
||||
"design",
|
||||
"diy",
|
||||
"fashion",
|
||||
"parametric design",
|
||||
"sewing",
|
||||
"sewing pattern"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
"scripts": {
|
||||
"dev": "next dev -p 8000",
|
||||
"build": "node build.js",
|
||||
"clean": "rimraf dist",
|
||||
"mbuild": "NO_MINIFY=1 node build.js",
|
||||
"test": "BABEL_ENV=production npx mocha tests/*.test.mjs --require @babel/register",
|
||||
"vbuild": "VERBOSE=1 node build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@freesewing/core": "$$ tag $$",
|
||||
$$ #dependencies $$
|
||||
"$$& . $$": "$$ tag $$",
|
||||
$$ /dependencies $$
|
||||
"@freesewing/plugin-bundle": "$$ tag $$"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@freesewing/plugin-annotations": "$$ tag $$",
|
||||
"@freesewing/plugin-flip": "$$ tag $$",
|
||||
"@freesewing/plugin-svgattr": "$$ tag $$",
|
||||
"@freesewing/plugin-theme": "$$ tag $$",
|
||||
"@freesewing/plugin-i18n": "$$ tag $$",
|
||||
"@freesewing/plugin-mirror": "$$ tag $$",
|
||||
"@freesewing/models": "$$ tag $$",
|
||||
"@headlessui/react": "^1.6.5",
|
||||
$$ #includeTests $$
|
||||
"@playwright/test": "^1.32.3",
|
||||
$$ /includeTests $$
|
||||
"js-yaml": "^4.1.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"axios": "^0.27.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-sizeme": "^3.0.2",
|
||||
"react-zoom-pan-pinch": "^2.1.3",
|
||||
"react-markdown": "^8.0.3",
|
||||
"roughjs": "^4.5.2",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"d3-dispatch": "^3.0.1",
|
||||
"d3-drag": "^3.0.0",
|
||||
"d3-selection": "^3.0.0",
|
||||
"daisyui": "^2.0.6",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.orderby": "^4.6.0",
|
||||
"lodash.set": "^4.3.2",
|
||||
"lodash.unset": "^4.5.2",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"next": "^13",
|
||||
"mermaid": "10.1.0",
|
||||
"next-i18next": "^11.0.0",
|
||||
"pdfkit": "^0.13.0",
|
||||
$$ #includeTests $$
|
||||
"playwright": "^1.32.3",
|
||||
$$ /includeTests $$
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
"react-hotkeys-hook": "^3.4.4",
|
||||
"react-swipeable": "^6.2.0",
|
||||
"react-timeago": "^7.1.0",
|
||||
"mocha": "^9.1.1",
|
||||
"chai": "^4.2.0",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"eslint-config-next": "12.1.6",
|
||||
"highlight.js": "^11.5.1",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-for": "^2.1.1",
|
||||
"svg-to-pdfkit": "^0.1.8",
|
||||
"tailwindcss": "^3.1.3",
|
||||
"tailwindcss-open-variant": "^1.0.0",
|
||||
"web-worker": "^1.2.0"
|
||||
},
|
||||
"files": [
|
||||
"dist/*",
|
||||
"README.md",
|
||||
"package.json"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"tag": "next"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=8.3.0"
|
||||
},
|
||||
"overrides": {
|
||||
"react-zoom-pan-pinch": {
|
||||
"react": "$react",
|
||||
"react-dom": "$react-dom"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{{!
|
||||
// Change the Mustache delimiter from double curly braces to double dollar signs.
|
||||
// Dollar signs are allowed in EcmaScript identifier names,
|
||||
// which is helpful when running unrendered Mustache templates through eslint.
|
||||
//}}{{=$$ $$=}}
|
||||
$$ #doesInherit $$
|
||||
import { $$ part $$ as $$ baseName $$$$ Part $$ } from '@freesewing/$$ baseName $$'
|
||||
|
||||
$$ /doesInherit $$
|
||||
$$ #pluginBundle $$
|
||||
import { pluginBundle } from '@freesewing/plugin-bundle'
|
||||
|
||||
$$ /pluginBundle $$
|
||||
function draft$$ Part $$ ({
|
||||
// Uncomment below to destructure what you need
|
||||
/*
|
||||
* Content constructors
|
||||
*/
|
||||
$$ ^draftUses.Path $$//$$ /draftUses.Path $$Path, // A Path constructor to create new paths
|
||||
$$ ^draftUses.Point $$//$$ /draftUses.Point $$Point, // A Point constructor to create new points
|
||||
$$ ^draftUses.Snippet $$//$$ /draftUses.Snippet $$Snippet, // A Snippet constructor to create new snippets
|
||||
/*
|
||||
* Content constainers
|
||||
*/
|
||||
$$ ^draftUses.paths $$//$$ /draftUses.paths $$paths, // Add a Path to your part by adding it to this object
|
||||
$$ ^draftUses.points $$//$$ /draftUses.points $$points, // Add a Points to your part by adding it to this object
|
||||
$$ ^draftUses.snippets $$//$$ /draftUses.snippets $$snippets, // Add a Snippet to your part by adding it to this object
|
||||
/*
|
||||
* Access to settings
|
||||
*/
|
||||
$$ ^draftUses.absoluteOptions $$//$$ /draftUses.absoluteOptions $$absoluteOptions, // Access to settings.absoluteOptions
|
||||
$$ ^draftUses.complete $$//$$ /draftUses.complete $$complete, // Access to settings.complete
|
||||
$$ ^draftUses.measurements $$//$$ /draftUses.measurements $$measurements, // Access to settings.measurements
|
||||
$$ ^draftUses.options $$//$$ /draftUses.options $$options, // Access to settings.options
|
||||
$$ ^draftUses.paperless $$//$$ /draftUses.paperless $$paperless, // Access to settings.paperless
|
||||
$$ ^draftUses.sa $$//$$ /draftUses.sa $$sa, // Access to settings.sa
|
||||
$$ ^draftUses.scale $$//$$ /draftUses.scale $$scale, // Access to settings.scale
|
||||
/*
|
||||
* Access to utilities
|
||||
*/
|
||||
$$ ^draftUses.getId $$//$$ /draftUses.getId $$getId, //See the getId documentation
|
||||
$$ ^draftUses.hide $$//$$ /draftUses.hide $$hide, //See the hide documentation
|
||||
$$ ^draftUses.log $$//$$ /draftUses.log $$log, //See the logging documentation
|
||||
$$ ^draftUses.macro $$//$$ /draftUses.macro $$macro, //See the macros documentation
|
||||
$$ ^draftUses.setHidden $$//$$ /draftUses.setHidden $$setHidden, //See the setHidden documentation
|
||||
$$ ^draftUses.store $$//$$ /draftUses.store $$store, //See the store documentation
|
||||
$$ ^draftUses.unhide $$//$$ /draftUses.unhide $$unhide, //See the unhide documentation
|
||||
$$ ^draftUses.units $$//$$ /draftUses.units $$units, //See the units documentation
|
||||
/$$ ^draftUses.utils $$//$$ /draftUses.utils $$utils, //See the utils documentation
|
||||
/*
|
||||
* Return value
|
||||
*/
|
||||
part, // Your draft method must return this
|
||||
}) {
|
||||
$$& draft $$
|
||||
$$ ^draft $$// Work your magic here $$ /draft $$
|
||||
return part
|
||||
}
|
||||
|
||||
export const $$ part $$ = {
|
||||
/*
|
||||
* name: Holds the name of this part.
|
||||
*
|
||||
* We STRONGLY recommend naming your parts in the format of
|
||||
* design.part to avoid naming conflicts when people re-use
|
||||
* parts across designs.
|
||||
*/
|
||||
name: '$$ name $$.$$ part $$',
|
||||
/*
|
||||
* draft: Holds the draft method for this part
|
||||
*
|
||||
* This should be a function that drafts and returns the part
|
||||
*
|
||||
* Documentation: https://freesewing.dev/reference/api/part/draft
|
||||
*/
|
||||
draft: draft$$ Part $$,
|
||||
after: [
|
||||
/*
|
||||
* after: Holds a list of parts that should be drafted prior to this part.
|
||||
*
|
||||
* You'll need to import these parts, just as with the from key above.
|
||||
*
|
||||
* If you don't have any parts to draft prior to this part,
|
||||
* you can remove this options key entirely.
|
||||
*
|
||||
* Documentation: https://freesewing.dev/reference/api/part/config/dependencies
|
||||
*/
|
||||
],
|
||||
/*
|
||||
* from: Holds the part you want to extend.
|
||||
*
|
||||
$$ #doesInherit $$
|
||||
* Since you opted to extend $$ BaseName $$, and this is the $$ part $$ part,
|
||||
* we're extending $$ BaseName $$'s $$ part $$ part here.
|
||||
* It was imported at the top of this file from @freesewing/$$ BaseName $$
|
||||
*
|
||||
$$ /doesInherit $$
|
||||
* Documentation: https://freesewing.dev/reference/api/part/config/dependencies
|
||||
*/
|
||||
$$ #doesInherit $$
|
||||
from: $$ baseName $$$$ Part $$,
|
||||
$$ /doesInherit $$
|
||||
$$ ^doesInherit $$
|
||||
from: false,
|
||||
$$ /doesInherit $$
|
||||
/* hide: */
|
||||
hide: {
|
||||
/*
|
||||
* self: Set this to true to hide the part.
|
||||
*
|
||||
* We've set this to false here to clarify its use.
|
||||
* If you don't want to hide this part,
|
||||
* you can remove the hide key entirely.
|
||||
*/
|
||||
self: false,
|
||||
/*
|
||||
* from: Set this to true to hide a part's from dependency.
|
||||
*
|
||||
$$ #doesInherit $$
|
||||
* We've set this to true here since you're extending $$ BaseName $$'s $$ part $$ part.
|
||||
$$ /doesInherit $$
|
||||
* If you don't want to hide this part's from dependency,
|
||||
* you can remove the from key entirely.
|
||||
*/
|
||||
from: $$ doesInherit $$,
|
||||
/*
|
||||
* after: Set this to true to hide any parts specified in the after setting
|
||||
*
|
||||
* We've set this to false here to clarify its use.
|
||||
* If you don't want to hide this part,
|
||||
* you can remove the hide key entirely.
|
||||
*/
|
||||
after: false
|
||||
},
|
||||
options: {
|
||||
/*
|
||||
* options: Holds (the configuration of) options for this part
|
||||
*
|
||||
* Declare options used in this part here.
|
||||
$$ #doesInherit $$
|
||||
* You only need to add additional options.
|
||||
* All options coming from $$ BaseName $$'s $$ part $$ part are already loaded.
|
||||
$$ /doesInherit $$
|
||||
*
|
||||
* If you don't have any options to add,
|
||||
* you can remove this options key entirely.
|
||||
*
|
||||
* Documentation: https://freesewing.dev/reference/api/part/config/options
|
||||
*/
|
||||
$$& options $$
|
||||
},
|
||||
measurements: [
|
||||
/*
|
||||
* measurements: Holds a list of measurements required by this part.
|
||||
*
|
||||
* Declare measurements required by this part here.
|
||||
$$ #doesInherit $$
|
||||
* You only need to add additional measurements.
|
||||
* All measurements coming from $$ BaseName $$'s $$ part $$ part are already loaded.
|
||||
$$ /doesInherit $$
|
||||
*
|
||||
* If you don't have any required measurements to add,
|
||||
* you can remove this measurements key entirely.
|
||||
*
|
||||
* Documentation: https://freesewing.dev/reference/api/part/config/measurements
|
||||
*/
|
||||
],
|
||||
optionalMeasurements: [
|
||||
/*
|
||||
* optionalMeasurements: Holds a list of measurements optional in this part.
|
||||
*
|
||||
* Declare measurements that are optional for this part here.
|
||||
*
|
||||
* If you don't have any optional measurements to add,
|
||||
* you can remove this optionalMeasurements key entirely.
|
||||
*
|
||||
* Documentation: https://freesewing.dev/reference/api/part/config/measurements
|
||||
*/
|
||||
],
|
||||
plugins: [
|
||||
/*
|
||||
* plugins: Holds a list of plugins this part relies on.
|
||||
*
|
||||
* Add all the plugins here that you need in this part.
|
||||
$$ #doesInherit $$
|
||||
* You only need to add additional plugins.
|
||||
* All plugins coming from $$ BaseName $$'s $$ part $$ part are already loaded.
|
||||
$$ /doesInherit $$
|
||||
*
|
||||
* If you don't have any plugins to add,
|
||||
* you can remove this plugins key entirely.
|
||||
*
|
||||
* Documentation: https://freesewing.dev/reference/api/part/config/plugins
|
||||
*/
|
||||
$$ #pluginBundle $$
|
||||
pluginBundle,
|
||||
$$ /pluginBundle $$
|
||||
]
|
||||
}
|
|
@ -1,11 +1,57 @@
|
|||
import configBuilder from '../shared/config/next.mjs'
|
||||
import i18nConfig from './next-i18next.config.js'
|
||||
import { banner } from '../../scripts/banner.mjs'
|
||||
import path from 'path'
|
||||
// Remark plugins
|
||||
import remarkFrontmatter from 'remark-frontmatter'
|
||||
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
import smartypants from 'remark-smartypants'
|
||||
|
||||
let config = configBuilder({ site: 'sde' })
|
||||
config.i18n = i18nConfig.i18n
|
||||
/*
|
||||
* This is the NextJS configuration
|
||||
*/
|
||||
const config = {
|
||||
experimental: {
|
||||
externalDir: true,
|
||||
},
|
||||
pageExtensions: ['mjs'],
|
||||
webpack: (config, options) => {
|
||||
// Fixes npm packages that depend on node modules
|
||||
if (!options.isServer) {
|
||||
config.resolve.fallback.fs = false
|
||||
config.resolve.fallback.path = false
|
||||
config.resolve.fallback.child_process = false
|
||||
}
|
||||
|
||||
// Say hi
|
||||
console.log(banner + '\n')
|
||||
// MDX support
|
||||
config.module.rules.push({
|
||||
test: /\.mdx?$/,
|
||||
use: [
|
||||
options.defaultLoaders.babel,
|
||||
{
|
||||
loader: '@mdx-js/loader',
|
||||
options: {
|
||||
providerImportSource: '@mdx-js/react',
|
||||
format: 'mdx',
|
||||
remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm, smartypants],
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Fix for nextjs bug #17806
|
||||
config.module.rules.push({
|
||||
test: /index.mjs$/,
|
||||
type: 'javascript/auto',
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
})
|
||||
|
||||
// Aliases
|
||||
config.resolve.alias.shared = path.resolve('./shared/')
|
||||
config.resolve.alias.site = path.resolve(`./`)
|
||||
|
||||
return config
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
|
|
@ -15,19 +15,61 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"cibuild": "yarn build",
|
||||
"dev": "next dev -p 8000",
|
||||
"develop": "next dev -p 8000",
|
||||
"i18n": "SITE=sde node --conditions=internal ../shared/prebuild/i18n-only.mjs",
|
||||
"lint": "next lint",
|
||||
"prebuild": "node --conditions=internal --experimental-json-modules ./prebuild.mjs",
|
||||
"start": "yarn prebuild && yarn dev",
|
||||
"wbuild": "next build",
|
||||
"prewbuild": "node --conditions=internal --experimental-json-modules ./prebuild.mjs"
|
||||
"lint": "next lint"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"@freesewing/core": "next",
|
||||
"@freesewing/core-plugins": "next",
|
||||
"@freesewing/brian": "next",
|
||||
"@freesewing/titan": "next",
|
||||
"@freesewing/bella": "next",
|
||||
"@freesewing/breanna": "next",
|
||||
"@headlessui/react": "1.7.17",
|
||||
"@mdx-js/loader": "2.3.0",
|
||||
"@mdx-js/mdx": "2.3.0",
|
||||
"@mdx-js/react": "2.3.0",
|
||||
"@mdx-js/runtime": "2.0.0-next.9",
|
||||
"@tailwindcss/typography": "0.5.9",
|
||||
"d3-dispatch": "3.0.1",
|
||||
"d3-drag": "3.0.0",
|
||||
"d3-selection": "3.0.0",
|
||||
"daisyui": "3.6.4",
|
||||
"i18next": "23.4.6",
|
||||
"lodash.get": "4.4.2",
|
||||
"lodash.orderby": "4.6.0",
|
||||
"lodash.set": "4.3.2",
|
||||
"next": "13.4.19",
|
||||
"next-i18next": "14.0.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-copy-to-clipboard": "5.1.0",
|
||||
"react-hotkeys-hook": "4.4.1",
|
||||
"react-i18next": "13.2.2",
|
||||
"react-markdown": "8.0.7",
|
||||
"react-swipeable": "7.0.1",
|
||||
"react-timeago": "7.1.0",
|
||||
"rehype-autolink-headings": "6.1.1",
|
||||
"rehype-highlight": "6.0.0",
|
||||
"rehype-sanitize": "5.0.1",
|
||||
"rehype-slug": "5.1.0",
|
||||
"rehype-stringify": "10.0.0",
|
||||
"remark-smartypants": "2.0.0",
|
||||
"remark-copy-linked-files": "git+https://git@github.com/joostdecock/remark-copy-linked-files",
|
||||
"remark-gfm": "3.0.1",
|
||||
"remark-mdx-frontmatter": "3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "10.4.15",
|
||||
"eslint-config-next": "13.4.19",
|
||||
"js-yaml": "4.1.0",
|
||||
"postcss": "8.4.29",
|
||||
"remark-extract-frontmatter": "3.2.0",
|
||||
"remark-mdx-frontmatter": "3.0.0",
|
||||
"tailwindcss": "3.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18",
|
||||
"npm": "9"
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
["plugin-bundle", "plugin-bust"]
|
Loading…
Add table
Add a link
Reference in a new issue