chore: Port FreeSewing.dev to docusaurus
The replaces the NextJS site powering FreeSewing.dev with a Docusaurus setup. It's part of my efforts to simplify FreeSewing's setup so we can focus on our core value proposition.
This commit is contained in:
parent
497633d1d3
commit
ab3204f9f1
692 changed files with 11037 additions and 20674 deletions
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
title: Contribute
|
||||
---
|
||||
|
||||
Looking to contribute to FreeSewing? That's wonderful.
|
||||
|
||||
## Ways to contribute
|
||||
|
||||
There are many ways to contribute, here's some examples:
|
||||
|
||||
<ReadMore root='howtos/ways-to-contribute' />
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
All FreeSewing contributors must respect and uphold our Code of Conduct:
|
||||
|
||||
<ReadMore root='guides/code-of-conduct' />
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
---
|
||||
title: Design
|
||||
---
|
||||
|
||||
If you are looking to use FreeSewing to design parametric sewing patterns,
|
||||
below are the most relevant materials on this site for you:
|
||||
|
||||
## Before you start
|
||||
|
||||
Outlines the minimal prerequisites you should understand before you dive in, including:
|
||||
|
||||
- <DocsLink slug="guides/prerequisites" />
|
||||
<ReadMore root="guides/prerequisites" />
|
||||
|
||||
## Pattern design best practices
|
||||
|
||||
In design as in code, there's often many different ways to accomplish the same
|
||||
result. We have a list of best practices that we recommend you follow. Even if
|
||||
in the end you make your own choices, we recommend you at least ready through
|
||||
them once. They include:
|
||||
|
||||
- <DocsLink slug="guides/best-practices" />
|
||||
<ReadMore root="guides/best-practices" />
|
||||
|
||||
## Design guide
|
||||
|
||||
We've so far been talking about *patterns* but what you're really be creating is a *design*.
|
||||
What the difference is, and what goes into a design to generate a pattern is explained in our design guide:
|
||||
|
||||
- <DocsLink slug="guides/designs" />
|
||||
<ReadMore root="guides/designs" />
|
||||
|
||||
## Pattern design tutorial
|
||||
|
||||
This is our pattern design tutorial. If you're new to designing patterns with
|
||||
FreeSewing, following the tutorial is the fastest way to get started:
|
||||
|
||||
- <DocsLink slug="tutorials/pattern-design" />
|
||||
<ReadMore root="tutorials/pattern-design" recurse />
|
||||
|
||||
## Plugin guide
|
||||
|
||||
FreeSewing can be extended with plugins. We provide a range of plugins that you can use.
|
||||
However, if you'd like to write your own plugins, you should also read the guide on how they work:
|
||||
|
||||
- <DocsLink slug="guides/plugins" />
|
||||
<ReadMore root="guides/plugins" />
|
||||
|
||||
## Common design challenges
|
||||
|
||||
This is a list of common challenges in designing parametric sewing patterns, and tips on how to tackle them:
|
||||
|
||||
- <DocsLink slug="howtos/design" />
|
||||
<ReadMore root="howtos/design" />
|
||||
|
||||
## Common code challenges
|
||||
|
||||
While designing patterns in code has a lot of benefits, there might be times
|
||||
where things that are intuitive on paper don't come naturally to you. This is
|
||||
a list of common code challenges and how to tackle them:
|
||||
|
||||
- <DocsLink slug="howtos/code" />
|
||||
<ReadMore root="howtos/code" />
|
||||
|
||||
## Core API
|
||||
|
||||
This is the reference documentation for FreeSewing's core library.
|
||||
This is where you can look up every possible API call with examples:
|
||||
|
||||
- <DocsLink slug="reference/api" />
|
||||
<ReadMore root="reference/api" />
|
||||
|
||||
## Macros
|
||||
|
||||
This is the reference documentation for macros provided by FreeSewing's own plugins:
|
||||
|
||||
- <DocsLink slug="reference/macros" />
|
||||
<ReadMore root="reference/macros" />
|
||||
|
||||
## Snippets
|
||||
|
||||
This is the reference documentation for snippets provided by FreeSewing's own plugins:
|
||||
|
||||
- <DocsLink slug="reference/snippets" />
|
||||
<ReadMore root="reference/snippets" />
|
||||
|
||||
## Plugins
|
||||
|
||||
This is the list of all plugins we provide:
|
||||
|
||||
- <DocsLink slug="reference/plugins" />
|
||||
<ReadMore root="reference/plugins" />
|
||||
|
||||
<Note>
|
||||
|
||||
##### Missing something?
|
||||
|
||||
If you are missing something or have questions not covered here, the `#pattern-design` channel
|
||||
on [discord.freesewing.org](https://discord.freesewing.org/) is the best place to ask questions.
|
||||
|
||||
</Note>
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
title: Pattern design best practices
|
||||
---
|
||||
|
||||
Here is a list of best practices when designing patterns:
|
||||
|
||||
<ReadMore />
|
|
@ -1,39 +0,0 @@
|
|||
---
|
||||
title: Construct paths counter-clockwise
|
||||
order: 70
|
||||
---
|
||||
|
||||
Construct your paths _counter-clockwise_ (anti-clockwise). You have to pick a direction anyway, and going
|
||||
counter-clockwise is a bit of a convention.
|
||||
|
||||
This applies both to naming points (specifically the control points of curves)
|
||||
and the order in which you define your points.
|
||||
|
||||
Obviously, the order in which you add points to your code needs to take a backseat
|
||||
to the logic of your code. But typically what you're doing is constructing an outline
|
||||
of (a part of) a garment.
|
||||
|
||||
So pick a point, and make your way around counter-clockwise.
|
||||
|
||||
When naming control points for curves, re-use the name of the point they are attached to
|
||||
and add `Cp1` to the control point before and `Cp2` to the control point after the point if,
|
||||
once again, you follow your path counter-clockwise.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
part.paths.seam = new Path()
|
||||
.move(points.hemCenter)
|
||||
.line(points.hemSide)
|
||||
.line(points.waistSide)
|
||||
.curve(points.waistSideCp2, points.armholeCp1, points.armhole)
|
||||
```
|
||||
|
||||
<Tip>
|
||||
|
||||
##### This convention helps with `Path.offset()` too
|
||||
|
||||
Constructing a path counter-clockwise will also ensure that the path offset goes outwards
|
||||
rather than inwards.
|
||||
|
||||
</Tip>
|
|
@ -1,84 +0,0 @@
|
|||
---
|
||||
title: Respect draft settings
|
||||
order: 40
|
||||
---
|
||||
|
||||
Apart from the pattern options that you configure for your pattern,
|
||||
all FreeSewing patterns have a set of [draft settings](/reference/settings) that can be tweaked
|
||||
by the user.
|
||||
|
||||
While many of these will automatically be handled by FreeSewing, there are some
|
||||
that you will need to take into account while developing your pattern. They are:
|
||||
|
||||
## Complete
|
||||
|
||||
The [`complete`](/reference/settings/complete) setting is a boolean that is either true or false.
|
||||
|
||||
Its goal is to determine whether we should draft a _complete_ pattern which
|
||||
includes elements such as seam allowance lines, labels, and markings for
|
||||
buttons and notches,
|
||||
or if the pattern should include the part outlines only.
|
||||
|
||||
It is your job when developing your pattern to ensure that the pattern
|
||||
checks the `complete` setting and includes or omits the appropriate elements
|
||||
based on the setting's value.
|
||||
|
||||
## Paperless
|
||||
|
||||
The [`paperless`](/reference/settings/paperless) setting is a boolean that is either true or false.
|
||||
|
||||
A _paperless_ pattern is a pattern that has extra dimension markings so
|
||||
users can trace or transfer the pattern onto fabric or paper without having
|
||||
the need to print it.
|
||||
|
||||
It is your job when developing your pattern to ensure that the pattern
|
||||
checks the `paperless` setting and includes or omits the dimensions
|
||||
based on the setting's value.
|
||||
|
||||
## Seam allowance
|
||||
|
||||
The [`sa`](/reference/settings/sa) setting is a number that controls the seam allowance width.
|
||||
|
||||
Unless `sa` is zero, patterns are drafted with seam allowance lines included.
|
||||
|
||||
It is your job when developing your pattern to ensure that the pattern
|
||||
checks the `sa` setting and includes or omits the seam allowance lines
|
||||
based on the setting's value.
|
||||
|
||||
<Tip>
|
||||
|
||||
##### Use a multiple of `sa` for your hem allowance
|
||||
|
||||
Resist the temptation to use an absolute value for any seam allowance,
|
||||
including at the hem.
|
||||
|
||||
Instead, always use a multiple of the `sa` value.
|
||||
This will help to ensure that the seam allowances will scale to appropriate
|
||||
values when the pattern is scaled up or down to giant or doll sizes.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Example
|
||||
|
||||
To respect the `complete`, `paperless`, and `sa` draft settings, structure your parts as such:
|
||||
|
||||
```js
|
||||
export default function(part) {
|
||||
let { complete, sa, paperless } = part.shorthand()
|
||||
// Your paths and points here
|
||||
|
||||
if (complete) {
|
||||
// Your snippets, text, helplines and so on here
|
||||
|
||||
if (sa) {
|
||||
// Your seam allowance here
|
||||
}
|
||||
|
||||
if (paperless) {
|
||||
// Your dimensions
|
||||
}
|
||||
}
|
||||
|
||||
return part
|
||||
}
|
||||
```
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
title: Re-use CSS classes
|
||||
order: 30
|
||||
---
|
||||
|
||||
While you can style your pattern however you want, try to re-use the
|
||||
[CSS class names](/reference/css) that
|
||||
are in use in our default `@freesewing/plugin-theme` plugin.
|
||||
|
||||
Doing so will ensure consistent styling for patterns.
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
title: Re-use measurements
|
||||
order: 10
|
||||
---
|
||||
|
||||
When designing patterns, re-use the measurements that are already in use as much as possible.
|
||||
Nobody wins when every pattern requires its own set of measurements, or names
|
||||
certain measurements differently.
|
||||
|
||||
<Tip>
|
||||
|
||||
###### See our measurements page for standard measurement names
|
||||
|
||||
The [measurements reference page](/reference/measurements/)
|
||||
contains all our standard measurement names.
|
||||
|
||||
</Tip>
|
|
@ -1,11 +0,0 @@
|
|||
---
|
||||
title: Re-use options
|
||||
order: 20
|
||||
---
|
||||
|
||||
The same arguments for re-using measurements are also (somewhat) true for options.
|
||||
|
||||
While your pattern may require some very specific
|
||||
options, there's probably a bunch that are similar to other patterns. Re-use those names.
|
||||
|
||||
As in, `bicepsEase` exists. So don't go creating an `upperArmEase` option.
|
|
@ -1,34 +0,0 @@
|
|||
---
|
||||
title: Use percentage options where possible
|
||||
order: 50
|
||||
---
|
||||
|
||||
When designing patterns, you should refrain from using absolute values.
|
||||
|
||||
That 6 cm ease you add might be fine for all scenarios you tested.
|
||||
But, then somebody comes around who is twice your size or who is making clothes for a doll,
|
||||
and things will go off the rails.
|
||||
|
||||
Don't be tempted to add absolute values to your patterns, as they don't scale.
|
||||
Instead, embrace percentages as options.
|
||||
By using values that are percentages of measurements, the values will scale
|
||||
and continue to work as the measurements scale up or down.
|
||||
|
||||
<Tip>
|
||||
|
||||
##### Use the doll and giant tests
|
||||
|
||||
To check how well your pattern scales, you can
|
||||
use the _doll_ and _giant_ tests by sampling the pattern for 3 measurements sets:
|
||||
|
||||
1. A set of measurements from an average person (the person)
|
||||
2. A set of measurements 1/10th of an average person (the doll)
|
||||
3. A set of measurements 3 times that of an average person (the giant)
|
||||
|
||||
A well-designed pattern will scale a factor 10 down or 3 up and still hold its shape.
|
||||
If your pattern makes assumptions about size, these tests will show that.
|
||||
|
||||
FreeSewing's development environment provides these tests out of the box,
|
||||
so you can see their results at the click of a button.
|
||||
|
||||
</Tip>
|
|
@ -1,30 +0,0 @@
|
|||
---
|
||||
title: Use translation keys, not text
|
||||
order: 60
|
||||
---
|
||||
|
||||
Don't insert literal text in your patterns. Instead, insert a key that can then be translated.
|
||||
|
||||
For example, if you want to put "_Finish with bias tape_" on your pattern, don't be
|
||||
tempted to do this:
|
||||
|
||||
```js
|
||||
path.seam.attr("data-text", "Finish with bias tape");
|
||||
```
|
||||
|
||||
That (English) string is now hard-coded in your pattern. As FreeSewing supports
|
||||
translation out of the box, it would be a real shame not to make use of it.
|
||||
|
||||
Instead, insert a key to identify the string:
|
||||
|
||||
```js
|
||||
path.seam.attr("data-text", "finishWithBiasTape");
|
||||
```
|
||||
|
||||
This way, different strings for different languages can be associated with
|
||||
the key, allowing translated text to be used.
|
||||
|
||||
You can find and browse the translations and available translation keys for each design in the design's
|
||||
[i18n folder on GitHub][1].
|
||||
|
||||
[1]: https://github.com/freesewing/freesewing/tree/develop/designs/aaron/i18n
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
title: Code of Conduct
|
||||
---
|
||||
|
||||
All FreeSewing contributors must respect and uphold our Code of Conduct:
|
||||
|
||||
<ReadMore />
|
||||
|
||||
<Note>
|
||||
|
||||
##### Attribution
|
||||
|
||||
This Code of Conduct is an almost verbatim copy of the [Contributor Covenant][homepage], version 2.0,
|
||||
available at [http://contributor-covenant.org/version/2/0][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
|
||||
[version]: http://contributor-covenant.org/version/2/0/
|
||||
|
||||
</Note>
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
title: Correction
|
||||
order: 10
|
||||
---
|
||||
|
||||
##### Community Impact
|
||||
|
||||
Use of inappropriate language or other behavior
|
||||
deemed unprofessional or unwelcome in the community.
|
||||
|
||||
##### Consequence
|
||||
|
||||
A private, written warning from community leaders,
|
||||
providing clarity around the nature of the violation and an
|
||||
explanation of why the behavior was inappropriate.
|
||||
|
||||
A public apology may be requested.
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
title: Enforcement Guidelines
|
||||
order: 60
|
||||
---
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines
|
||||
in determining the consequences for any action they deem
|
||||
in violation of FreeSewing's Code of Conduct:
|
||||
|
||||
<ReadMore />
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Permanent ban
|
||||
order: 40
|
||||
---
|
||||
|
||||
##### Community Impact
|
||||
|
||||
Demonstrating a pattern of violation of
|
||||
community standards, including sustained inappropriate behavior,
|
||||
harassment of an individual, or aggression toward or
|
||||
disparagement of classes of individuals.
|
||||
|
||||
##### Consequence
|
||||
|
||||
A permanent ban from any sort of public interaction within the community.
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
title: Temporary ban
|
||||
order: 30
|
||||
---
|
||||
|
||||
##### Community Impact
|
||||
|
||||
A serious violation of community standards,
|
||||
including sustained inappropriate behavior.
|
||||
|
||||
##### Consequence
|
||||
|
||||
A temporary ban from any sort of interaction or
|
||||
public communication with the community for a specified period
|
||||
of time.
|
||||
|
||||
No public or private interaction with the people
|
||||
involved, including unsolicited interaction with those enforcing
|
||||
the Code of Conduct, is allowed during this period.
|
||||
|
||||
Violating these terms may lead to a permanent ban.
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
title: Warning
|
||||
order: 20
|
||||
---
|
||||
|
||||
##### Community Impact
|
||||
|
||||
A violation through a single incident or series of actions.
|
||||
|
||||
##### Consequence
|
||||
|
||||
A warning with consequences for continued behavior.
|
||||
|
||||
No interaction with the people involved, including unsolicited
|
||||
interaction with those enforcing the Code of Conduct, for a
|
||||
specified period of time. This includes avoiding interactions
|
||||
in community spaces as well as external channels like social
|
||||
media.
|
||||
|
||||
Violating these terms may lead to a temporary or permanent ban.
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
title: Enforcement responsibilities
|
||||
order: 30
|
||||
---
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards
|
||||
of acceptable behavior and will take appropriate and fair corrective action
|
||||
in response to any behavior that they deem inappropriate, threatening,
|
||||
offensive, or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, and will communicate reasons
|
||||
for moderation decisions when appropriate.
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Enforcement
|
||||
order: 50
|
||||
---
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior
|
||||
may be reported to the community leaders responsible for enforcement:
|
||||
|
||||
- Joost De Cock (joost@joost.at)
|
||||
- Sorcha Ní Dhubhghaill (nidhubhs@gmail.com)
|
||||
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and
|
||||
security of the reporter of any incident.
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Our pledge
|
||||
order: 10
|
||||
---
|
||||
|
||||
We as members, contributors, and leaders of the FreeSewing community pledge
|
||||
to make participation in our community a harassment-free experience for everyone.
|
||||
|
||||
Everyone, regardless of age, body size, visible or invisible disability,
|
||||
ethnicity, sex characteristics, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
title: Our standards
|
||||
order: 20
|
||||
---
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others’ private information, such as a physical or email address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
@ -1,11 +0,0 @@
|
|||
---
|
||||
title: Scope
|
||||
order: 40
|
||||
---
|
||||
|
||||
This Code of Conduct applies within all FreeSewing community spaces and also applies
|
||||
when an individual is officially representing the FreeSewing community in public spaces.
|
||||
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed representative
|
||||
at an online or offline event.
|
|
@ -1,3 +0,0 @@
|
|||
---
|
||||
title: Content guides
|
||||
---
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: MDX Guide
|
||||
---
|
||||
|
||||
<Fixme>Explain MDX content</Fixme>
|
|
@ -1,70 +0,0 @@
|
|||
---
|
||||
title: Sanity Content Guide
|
||||
---
|
||||
|
||||
FreeSewing uses Sanity content needs to be edited/written by non-technical contributors,
|
||||
and for images uploaded by users, such as for their profile image and so on.
|
||||
|
||||
<Tldr>
|
||||
|
||||
You can manage FreeSewing's Sanity content at
|
||||
[cms.freesewing.org](https://cms.freesewing.org/)
|
||||
</Tldr>
|
||||
|
||||
By *content that needs to be edited/written by non-technical contributors* we mean:
|
||||
|
||||
- Newsletter posts
|
||||
- Blog posts in all languages
|
||||
- Showcase posts in all languages
|
||||
|
||||
## Why we use Sanity
|
||||
|
||||
The (historical) reason that we use a (headless) CMS for this lies with **the
|
||||
showcase posts**. Our documentation is still hosted in git as MDX, and
|
||||
historically this was also the case for our blog posts and showcase posts.
|
||||
|
||||
However, while documentation is written by contributors who are familiar with
|
||||
how we work, and blog posts are typically written by Joost, showcase posts are
|
||||
often provided by users of the site for whom submitting a pull request is a
|
||||
steep learning curve.
|
||||
|
||||
So for this reason, we started using an external CMS to host the showcase
|
||||
posts. And, since blog posts and showcase posts are so similar, we decided to
|
||||
use this platform for both. Later, we added newsletter content to this list
|
||||
because this too is sometimes provided by people not so familiar with the git
|
||||
workflow.
|
||||
|
||||
Prior to version 3, we used a self-hosted version of
|
||||
[Strapi](https://strapi.io/) for this. And while that did what we needed,
|
||||
self-hosting adds workload to people and our backend systems, so it's not
|
||||
without its drawbacks. Then, with the release of Strapi v4, they dropped
|
||||
support for MongoDB, which was the database we are using, so we were stuck on
|
||||
v3 of Strapi.
|
||||
|
||||
So for FreeSewing v3 we started looking for alternatives, and after trying
|
||||
various solutions Sanity came out as the best solution for our needs. It's a
|
||||
SaaS solution -- which is nice because it means we don't have to host anything
|
||||
-- but the flip side of the coin is that as a communal open source project, we
|
||||
obviously cannot afford it.
|
||||
|
||||
Fortunately for us, the same reasons that mean we don't have any money also
|
||||
mean that Sanity took pity on us, and they agreed to waive their fees and let
|
||||
us use their service free of charge. So, Sanity is now a FreeSewing sponsor,
|
||||
and since everything is in place already, we also use them to host user images
|
||||
because honestly it's a really nice service.
|
||||
|
||||
## How to manage Sanity content
|
||||
|
||||
As Sanity is a headless CMS, you essentially have to talk to the API to manage
|
||||
your content.
|
||||
|
||||
Fear not though, we don't expect you to do that. The Sanity Studio is a
|
||||
web-based frontend that allows you to manage the content in a web environment,
|
||||
and we have an instance of it deployed at https://cms.freeseiwng.org/ that is
|
||||
pre-configured to manage FreeSewing's content.
|
||||
|
||||
## For developers
|
||||
|
||||
If you're looking to learn more about how to interact with the Sanity API,
|
||||
please refer to [the Sanity reference documentation](/reference/sites/sanity).
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 152 KiB |
|
@ -1,404 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="317.5mm"
|
||||
height="178.59377mm"
|
||||
viewBox="0 0 317.5 178.59377"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||
sodipodi:docname="docs.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker1229"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend">
|
||||
<path
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1227"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker1201"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mstart">
|
||||
<path
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1199"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path844"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path841"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="631.61926"
|
||||
inkscape:cy="447.13138"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2132"
|
||||
inkscape:window-x="1080"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(492.12497,-18.620489)">
|
||||
<rect
|
||||
style="opacity:1;fill:#5b21b6;fill-opacity:1;stroke:none;stroke-width:3.62117767;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect815"
|
||||
width="317.5"
|
||||
height="178.59377"
|
||||
x="-492.12497"
|
||||
y="18.620489"
|
||||
rx="3.4404027"
|
||||
ry="3.8114519" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.70005989px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
x="-328.29581"
|
||||
y="63.211033"
|
||||
id="text819"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan817"
|
||||
x="-328.29581"
|
||||
y="63.211033"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#ffffff;stroke-width:2.15250444">Guides</tspan></text>
|
||||
<text
|
||||
id="text823"
|
||||
y="99.14698"
|
||||
x="-328.29581"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.70005989px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#ffffff;stroke-width:2.15250444"
|
||||
y="99.14698"
|
||||
x="-328.29581"
|
||||
id="tspan821"
|
||||
sodipodi:role="line">Howtos</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.70005989px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
x="-328.29581"
|
||||
y="156.04854"
|
||||
id="text827"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan825"
|
||||
x="-328.29581"
|
||||
y="156.04854"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#ffffff;stroke-width:2.15250444">Reference</tspan></text>
|
||||
<text
|
||||
id="text831"
|
||||
y="78.169304"
|
||||
x="-350.03833"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.70005989px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:end;text-anchor:end;fill:#ffffff;stroke-width:2.15250444"
|
||||
y="78.169304"
|
||||
x="-350.03833"
|
||||
id="tspan829"
|
||||
sodipodi:role="line">Tutorials</tspan></text>
|
||||
<path
|
||||
style="opacity:0.66500005;fill:none;stroke:#ffffff;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
|
||||
d="M -333.37497,35.54476 V 180.28998"
|
||||
id="path833"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1197"
|
||||
d="M -198.20312,107.38283 H -468.54681"
|
||||
style="opacity:0.66600001;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker1201);marker-end:url(#marker1229)" />
|
||||
<text
|
||||
id="text3411"
|
||||
y="29.591507"
|
||||
x="-333.36511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.84702301px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;opacity:0.66600001;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:2.15250444"
|
||||
y="29.591507"
|
||||
x="-333.36511"
|
||||
id="tspan3409"
|
||||
sodipodi:role="line">discovering</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.84702301px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;opacity:0.66600001;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
x="-107.90753"
|
||||
y="-479.78055"
|
||||
id="text3715"
|
||||
transform="rotate(-90)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3713"
|
||||
x="-107.90753"
|
||||
y="-479.78055"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:2.15250444">learning</tspan></text>
|
||||
<text
|
||||
transform="rotate(-90)"
|
||||
id="text3719"
|
||||
y="-181.55731"
|
||||
x="-107.90753"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.84702301px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;opacity:0.66600001;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:2.15250444"
|
||||
y="-181.55731"
|
||||
x="-107.90753"
|
||||
id="tspan3717"
|
||||
sodipodi:role="line">working</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.84702301px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;opacity:0.66600001;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
x="-333.36511"
|
||||
y="191.93228"
|
||||
id="text4191"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4189"
|
||||
x="-333.36511"
|
||||
y="191.93228"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:2.15250444">double-checking</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.9861412px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.15250444"
|
||||
x="-352.35159"
|
||||
y="146.07664"
|
||||
id="text4195"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4193"
|
||||
x="-352.35159"
|
||||
y="146.07664"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:end;text-anchor:end;fill:#ffffff;stroke-width:2.15250444">Discord & Github</tspan></text>
|
||||
<g
|
||||
id="g4217"
|
||||
transform="rotate(-4.9299968,-205.7308,220.23688)">
|
||||
<text
|
||||
transform="rotate(5.0638764)"
|
||||
id="text4207"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
inkscape:transform-center-y="1.5321792"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
id="tspan4205"
|
||||
sodipodi:role="line">I want to learn about...</tspan></text>
|
||||
<text
|
||||
inkscape:transform-center-y="1.5321792"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
id="text4211"
|
||||
transform="rotate(5.0638764)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4209"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">I want to learn about...</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="rotate(-4.9299968,227.67374,431.71495)"
|
||||
id="g4227">
|
||||
<text
|
||||
inkscape:transform-center-y="1.5321792"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
id="text4221"
|
||||
transform="rotate(5.0638764)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4219"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">I want to do this common thing</tspan></text>
|
||||
<text
|
||||
transform="rotate(5.0638764)"
|
||||
id="text4225"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
inkscape:transform-center-y="1.5321792"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
id="tspan4223"
|
||||
sodipodi:role="line">I want to do this common thing...</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="rotate(-4.9299968,-110.62565,2101.3475)"
|
||||
id="g4237">
|
||||
<text
|
||||
inkscape:transform-center-y="1.5321792"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
id="text4231"
|
||||
transform="rotate(5.0638764)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4229"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">What even is this thing???</tspan></text>
|
||||
<text
|
||||
transform="rotate(5.0638764)"
|
||||
id="text4235"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
inkscape:transform-center-y="1.5321792"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
id="tspan4233"
|
||||
sodipodi:role="line">What even is this thing???</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="rotate(-4.9299968,1191.8402,500.31153)"
|
||||
id="g4247">
|
||||
<text
|
||||
inkscape:transform-center-y="1.5321792"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
id="text4241"
|
||||
transform="rotate(5.0638764)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4239"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">What was that parameter again...</tspan></text>
|
||||
<text
|
||||
transform="rotate(5.0638764)"
|
||||
id="text4245"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
inkscape:transform-center-y="1.5321792"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
id="tspan4243"
|
||||
sodipodi:role="line">What was that parameter again...</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4257"
|
||||
transform="rotate(-4.9299968,1107.691,1893.1223)">
|
||||
<text
|
||||
transform="rotate(5.0638764)"
|
||||
id="text4251"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
xml:space="preserve"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
inkscape:transform-center-y="1.5321792"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:#6d28d9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
y="59.988617"
|
||||
x="-282.07816"
|
||||
id="tspan4249"
|
||||
sodipodi:role="line">I'm stuck; Help!</tspan></text>
|
||||
<text
|
||||
inkscape:transform-center-y="1.5321792"
|
||||
inkscape:transform-center-x="0.49090944"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.59147549px;line-height:1.25;font-family:'Ubuntu Mono';-inkscape-font-specification:'Ubuntu Mono';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
id="text4255"
|
||||
transform="rotate(5.0638764)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4253"
|
||||
x="-282.07816"
|
||||
y="59.988617"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Pacifico;-inkscape-font-specification:Pacifico;fill:#fde047;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">I'm stuck; Help!</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 22 KiB |
|
@ -1,41 +0,0 @@
|
|||
---
|
||||
title: How we structure our documentation
|
||||
---
|
||||
|
||||
Whether you're writing documentation for FreeSewing or merely trying
|
||||
to find what you are looking for, understanding how we structure our
|
||||
documentation can help you find your feet and figure out what goes where.
|
||||
|
||||
## Types of documentation
|
||||
|
||||
Our documentation is divided into four different types:
|
||||
|
||||
- [**Tutorials**](/tutorials) are lessons that lead you through a series of steps to complete a project.
|
||||
- [**Guides**](/guides) tell a story to further your understanding of a specific topic.
|
||||
- [**Howtos**](/howtos) give you concrete steps to solve a common problem or challenge.
|
||||
- [**Reference**](/reference) holds technical descriptions of the underlying technology and how to make use of it.
|
||||
|
||||
Each time you write documentation, you have to ask yourself: Is it a tutorial? Is it a Guide?
|
||||
Is it a Howto? Or, is it Reference documentation?
|
||||
|
||||
If you find it hard to answer that question, the illustration below might help you figure out
|
||||
where your documentation should go based on what it's trying to accomplish:
|
||||
|
||||

|
||||
|
||||
- Write a **Tutorial** is your aim is to help people learn the platform
|
||||
- Write a **Guide** if your aim is to further people's understanding of a topic by going a bit deeper
|
||||
- Write a **Howto** if your aim is to help people accomplish a task
|
||||
- Write **Reference** documentation to detail how things work under the hood
|
||||
- Refer people to **Discord** or **GitHub** for things that are not (yet) covered in our documentation
|
||||
|
||||
<Note>
|
||||
|
||||
##### Based on a talk by Daniele Procida
|
||||
|
||||
This structure is loosely based
|
||||
on [this talk by Daniele Procida](https://www.youtube.com/watch?v=t4vKPhjcMZg) at
|
||||
PyCon AU 2017.
|
||||
|
||||
</Note>
|
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
title: Guides
|
||||
order: zbb
|
||||
---
|
||||
|
||||
You can find a list of all FreeSewing guides below:
|
||||
|
||||
## Main sections
|
||||
|
||||
<ReadMore />
|
||||
|
||||
<Related>
|
||||
|
||||
##### What makes a guide a guide?
|
||||
|
||||
Guides tell a story to further your understanding of a specific topic.
|
||||
|
||||
Guides and Howtos are on a spectrum with Howtos being terse _do-this-then-that_ recipes, whereas
|
||||
guides take more time to explain in-depth what is being done and why.
|
||||
|
||||
For more details, refer to [How we structure our documentation](/guides/docs).
|
||||
|
||||
</Related>
|
||||
|
||||
## Full list
|
||||
|
||||
<ReadMore recurse />
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
---
|
||||
title: Code and code blocks
|
||||
order: 80
|
||||
---
|
||||
|
||||
Especially for our developer documentation, there's a lot of times we include source code
|
||||
in the documentation.
|
||||
You can make these look pretty by using a code block.
|
||||
|
||||
The basic use is to wrap your code in three backtick characters on a line:
|
||||
|
||||
````markdown
|
||||
```
|
||||
let me = 'you'
|
||||
```
|
||||
````
|
||||
|
||||
Gives you:
|
||||
|
||||
```text
|
||||
let me = 'you'
|
||||
```
|
||||
|
||||
This is a generic code block. But we also support syntax highlighting.
|
||||
To do so, add the language specifier after the opening backticks:
|
||||
|
||||
````markdown
|
||||
```js
|
||||
let me = 'you'
|
||||
```
|
||||
````
|
||||
|
||||
To get:
|
||||
|
||||
```js
|
||||
let me = 'you'
|
||||
```
|
||||
|
||||
The following language codes are supported:
|
||||
|
||||
- `js` for JavaScript code
|
||||
- `markdown` for Markdown
|
||||
- `html` for HTML
|
||||
- `svg` for SVG
|
||||
- `bash` for Bash or shell scripts
|
||||
- `mdx` for MDX
|
||||
- `jsx` for JSX
|
||||
- `json` for JSON
|
||||
|
||||
<Note>
|
||||
|
||||
Note that `mermaid` code blocks will be rendered as
|
||||
[Mermaid](https://mermaid.js.org/) diagrams. Refer to the docs on [custom
|
||||
tags](/guides/markdown/custom-components#mermaid) for an example.
|
||||
</Note>
|
||||
|
|
@ -1,850 +0,0 @@
|
|||
---
|
||||
title: Custom tags
|
||||
order: 90
|
||||
---
|
||||
|
||||
The way we render Markdown on our websites is through the use of
|
||||
[MDX](https://mdxjs.com/). This allows us to extend Markdown with our own
|
||||
tags. These tags are custom React components.
|
||||
|
||||
Such custom components allow us to put things in Markdown content that would
|
||||
typically require a lot more complexity.
|
||||
|
||||
Below is a list of custom tags that we support in our Markdown-based
|
||||
documentation, both for freesewing.dev as freesewing.org.
|
||||
|
||||
## Summary and Availability
|
||||
|
||||
This is a summary of the available custom tags and where each tag
|
||||
can be used.
|
||||
- **sde** tags can be used in the standalone development environment
|
||||
(provided by the [new-design](/reference/packages/new-design) package).
|
||||
- **dev** and **org** tags can be used on the
|
||||
freesewing.dev and freesewing.org sites, respectively.
|
||||
- For convenience, tags with similar functionality have been grouped together.
|
||||
|
||||
### Text popouts
|
||||
|
||||
These are markdown tags used to display text in a colored _popout_ box,
|
||||
to make the text stand out and to quickly convey what type of
|
||||
information is being presented.
|
||||
|
||||
| Tag | sde | dev | org |
|
||||
| ------: | :---: | :---: | :---: |
|
||||
| [Comment](#comment) | X | X | X |
|
||||
| [Fixme](#fixme) | X | X | X |
|
||||
| [Link](#link) | X | X | X |
|
||||
| [Note](#note) | X | X | X |
|
||||
| [Related](#related) | X | X | X |
|
||||
| [Tip](#tip) | X | X | X |
|
||||
| [Tldr](#tldr) | X | X | X |
|
||||
| [Warning](#warning) | X | X | X |
|
||||
|
||||
### Features and Formatting
|
||||
|
||||
These tags provide special features or ways to format content.
|
||||
|
||||
| Tag | sde | dev | org |
|
||||
| --------------------: | :---: | :---: | :---: |
|
||||
| [ControlTip](#controltip) | | X | X |
|
||||
| [DocsTitle](#docstitle) | | X | X |
|
||||
| [DocsLink](#docslink) | | X | X |
|
||||
| [Example](#example) | | X | X |
|
||||
| [Legend](#legend) | | | X* |
|
||||
| [MeasieImage](#measieimage) | | | X* |
|
||||
| [(Mermaid)](#mermaid) | | X | X |
|
||||
| [Method](#method) | | X | |
|
||||
| [StatusCode](#statuscode) | | X | |
|
||||
| [Tab](#tab) | | X | X |
|
||||
| [Tabs](#tabs) | | X | X |
|
||||
| [Youtube](#youtube) | | X | X |
|
||||
|
||||
<Note>
|
||||
|
||||
- **Legend** is available to use only on the
|
||||
[Pattern Notation Guide](https://freesewing.org/docs/about/notation) and
|
||||
[On the Fold](https://freesewing.org/docs/sewing/on-the-fold)
|
||||
documentation pages.
|
||||
|
||||
- **MeasieImage** is available to use only on the immediate subpages in the
|
||||
[Measurements](https://freesewing.org/docs/measurements)
|
||||
section of the documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
### Documentation Generators
|
||||
|
||||
These tags generate documentation-related content related to designs
|
||||
and documentation files.
|
||||
This prevents the need to write and edit the documentation manually,
|
||||
making it easier to write and to maintain when changes occur.
|
||||
|
||||
| Tag | sde | dev | org |
|
||||
| -----------------: | :---: | :---: | :---: |
|
||||
| [DesignInfo](#designinfo) | | | X* |
|
||||
| [DesignMeasurements](#designmeasurements) | | | X* |
|
||||
| [DesignOptions](#designoptions) | | | X* |
|
||||
| [ReadMore](#readmore) | X | X | X |
|
||||
|
||||
<Note>
|
||||
|
||||
- **DesignInfo** is available to use only on an individual design's
|
||||
main documentation page, for example
|
||||
[Aaron A-Shirt](https://freesewing.org/docs/designs/aaron).
|
||||
|
||||
- **DesignMeasurements** is available to use only on an individual design's
|
||||
Required Measurements documentation page, for example
|
||||
[Aaron A-Shirt: Required Measurements](https://freesewing.org/docs/designs/aaron/measurements).
|
||||
|
||||
- **DesignMeasurements** is available to use only on an individual design
|
||||
Design Options documentation page, for example
|
||||
[Aaron A-Shirt: Design Options](https://freesewing.org/docs/designs/aaron/options).
|
||||
|
||||
</Note>
|
||||
|
||||
***
|
||||
|
||||
## Details
|
||||
|
||||
All custom tags are listed alphabetically below.
|
||||
|
||||
### Comment
|
||||
|
||||
Use a **Comment** when you want to illustrate something that is a personal opinion
|
||||
or advice rather than the sort more neutral voice used throughout
|
||||
our documentation.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `by` | yes | | Name of the commenter |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Comment by="joost">MDX is essentially Markdown + (React) components</Comment>
|
||||
<Comment hideable by="Ben F.">
|
||||
It can be helpful to be able to hide long comments that might take up
|
||||
too much space on the page _(hideable)_
|
||||
</Comment>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Comment by="joost">MDX is essentially Markdown + (React) components</Comment>
|
||||
<Comment hideable by="Ben F.">
|
||||
It can be helpful to hide long comments that might take up too much
|
||||
space on the page _(hideable)_
|
||||
</Comment>
|
||||
</Tab>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### ControlTip
|
||||
|
||||
The **ControlTip** tag provides a popout box containing pre-written,
|
||||
formatted text describing the
|
||||
[User Experience](https://freesewing.org/account/control)
|
||||
account setting and explaining what it does.
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<ControlTip />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<ControlTip />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### DesignInfo
|
||||
|
||||
**DesignInfo** generates a detailed web page for a given FreeSewing
|
||||
design with information including line drawings, example photos,
|
||||
required measurements, design options, and links to documentation.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `design` | yes | | Name of the design |
|
||||
| `docs` | | `false` | Generates content suitable for a documentation page |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
(Please see the
|
||||
[Aaron A-Shirt documentation](https://freesewing.org/docs/designs/aaron)
|
||||
page for an example of this tag.)
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<DesignInfo design='aaron' docs />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
Because design documentation pages are the only place this tag can
|
||||
be used, you should always include the `docs` attribute when using
|
||||
this tag.
|
||||
(Omitting it will generate different content, less suited for
|
||||
documentation.)
|
||||
</Note>
|
||||
|
||||
### DesignMeasurements
|
||||
|
||||
**DesignMeasurements** generates a list of required and optional
|
||||
measurements for a given FreeSewing design.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `design` | yes | | Name of the design |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
(Please see
|
||||
[Aaron A-Shirt: Requirement Measurements](https://freesewing.org/docs/designs/aaron/measurements)
|
||||
for an example of this tag.)
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<DesignMeasurements design='aaron' />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### DesignOptions
|
||||
|
||||
**DesignOptions** generates a list of design options and settings
|
||||
for a given FreeSewing design.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `design` | yes | | Name of the design |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
(Please see
|
||||
[Aaron A-Shirt: Design Options](https://freesewing.org/docs/designs/aaron/options)
|
||||
for an example of this tag.)
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<DesignOptions design='aaron' />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### DocsLink
|
||||
|
||||
The **DocsLink** tag creates a formatted link from a given slug
|
||||
(a relative URL path).
|
||||
It also looks up the title of the linked web page and uses it as
|
||||
the link text.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `slug` | yes | | Relative path for the link |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<DocsLink slug='guides/markdown' />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<DocsLink slug='guides/markdown' />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### DocsTitle
|
||||
|
||||
The **DocsTitle** tag looks up the title of a web page from a
|
||||
given slug (a relative URL path) and provides the title as formatted
|
||||
text.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `slug` | yes | | Relative path of the link |
|
||||
| `className` | | | CSS classes to style the text |
|
||||
| `format` | | defaultFormater | Formatter used to format the text |
|
||||
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<DocsTitle slug='guides/markdown' />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<DocsTitle slug='guides/markdown' />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
The **Example** tag allows you to embed a FreeSewing code example and have it rendered in the browser.
|
||||
Specifically, you should write a [draft method](/reference/api/part/draft) which will then be rendered.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `caption` | | | The caption to go under the example |
|
||||
| `tutorial` | | `false` | Set this to show the Code tab first, rather than the default Preview tab. Also, additional options are made available for use in pattern examples |
|
||||
| `previewFirst` | | `false` | Set this to always show the Preview tab first, regardless of the value of `tutorial` |
|
||||
| `withHead` | | `false` | Set this to include a head measurement (for tutorial pattern examples) |
|
||||
| `paperless` | | `false` | Set this to enable paperless mode |
|
||||
| `settings` | | | A YAML string of settings to take into account |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Example caption="Example of the Path.curve() method">
|
||||
```js
|
||||
({ Point, points, Path, paths, part }) => {
|
||||
|
||||
points.from = new Point(10, 20)
|
||||
points.cp1 = new Point(40, 0)
|
||||
points.cp2 = new Point(60, 40)
|
||||
points.to = new Point(90, 20)
|
||||
|
||||
paths.line = new Path()
|
||||
.move(points.from)
|
||||
.curve(points.cp1, points.cp2, points.to)
|
||||
.setText("Path.curve()", "text-sm center fill-note")
|
||||
|
||||
return part
|
||||
}
|
||||
```
|
||||
</Example>
|
||||
</Tab>
|
||||
<Tab>
|
||||
````markdown
|
||||
<Example caption="Example of the Path.curve() method">
|
||||
```js
|
||||
({ Point, points, Path, paths, part }) => {
|
||||
|
||||
points.from = new Point(10, 20)
|
||||
points.cp1 = new Point(40, 0)
|
||||
points.cp2 = new Point(60, 40)
|
||||
points.to = new Point(90, 20)
|
||||
|
||||
paths.line = new Path()
|
||||
.move(points.from)
|
||||
.curve(points.cp1, points.cp2, points.to)
|
||||
.setText("Path.curve()", "text-sm center fill-note")
|
||||
|
||||
return part
|
||||
}
|
||||
```
|
||||
</Example>
|
||||
````
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Fixme
|
||||
|
||||
Use **Fixme** to indicate something needs attention/work but you don't have time
|
||||
or can't fix it now.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Fixme>
|
||||
##### ToDo
|
||||
- Include link to roadmap
|
||||
- Fix style for text outside paragraphs
|
||||
</Fixme>
|
||||
<Fixme compact>Proofread documentation _(compact)_</Fixme>
|
||||
<Fixme hideable>
|
||||
Proofread it a second time _(hideable)_
|
||||
</Fixme>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Fixme>
|
||||
##### ToDo
|
||||
- Include link to roadmap
|
||||
- Fix style for text outside paragraphs
|
||||
</Fixme>
|
||||
<Fixme compact>Proofread documentation _(compact)_</Fixme>
|
||||
<Fixme hideable>
|
||||
Proofread it a second time _(hideable)_
|
||||
</Fixme>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Legend
|
||||
|
||||
The **Legend** tag is used to display parts from a pattern of the
|
||||
Legend design (a non-public design in the FreeSewing repository
|
||||
created to provide examples of pattern features).
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `part` | yes | | The Legend part to display |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
(Please see
|
||||
[On the fold](https://freesewing.org/docs/sewing/on-the-fold)
|
||||
for an example of this tag, used to display the _cut-on-fold_ indicator
|
||||
on that page.)
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Legend part='cutonfold' />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Link
|
||||
|
||||
Use **Link** for URLs.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Link>
|
||||
https://freesewing.org/
|
||||
</Link>
|
||||
<Link compact>https://freesewing.org/ _(compact)_</Link>
|
||||
<Link hideable>https://freesewing.org/ _(hideable)_</Link>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Link>
|
||||
https://freesewing.org
|
||||
</Link>
|
||||
<Link compact>https://freesewing.org/ _(compact)_</Link>
|
||||
<Link hideable>https://freesewing.org/ _(hideable)_</Link>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### MeasieImage
|
||||
|
||||
**MeasieImage** will show images of a FreeSewing measurement.
|
||||
The name of the directory in which the tag is used is the
|
||||
measurement which will be shown.
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
(Please see
|
||||
[Biceps circumference](https://freesewing.org/docs/measurements/biceps)
|
||||
for an example of this tag, used to display the image showing the
|
||||
biceps circumference measurement.
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<MeasieImage />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### (Mermaid)
|
||||
|
||||
There is no actual "Mermaid" custom tag.
|
||||
However, by using a fenced [code block](/guides/markdown/code-blocks)
|
||||
and specifying the `mermaid` language, you can generate
|
||||
[Mermaid](https://mermaid.js.org/) diagrams. Like this:
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
```mermaid
|
||||
graph LR;
|
||||
A--> B & C & D;
|
||||
B--> A & E;
|
||||
C--> A & E;
|
||||
D--> A & E;
|
||||
E--> B & C & D;
|
||||
```
|
||||
</Tab>
|
||||
<Tab>
|
||||
````markdown
|
||||
```mermaid
|
||||
graph LR;
|
||||
A--> B & C & D;
|
||||
B--> A & E;
|
||||
C--> A & E;
|
||||
D--> A & E;
|
||||
E--> B & C & D;
|
||||
```
|
||||
````
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Method
|
||||
|
||||
**Method** is used to format HTTP methods.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `get` | | `false` | Display the HTTP `GET` method |
|
||||
| `post` | | `false` | Display the HTTP `POST` method |
|
||||
| `put` | | `false` | Display the HTTP `PUT` method |
|
||||
| `delete` | | `false` | Display the HTTP `DELETE` method |
|
||||
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Method get /><br />
|
||||
<Method post />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Method get /><br />
|
||||
<Method post />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
|
||||
- It is required that you provide one of the `get`, `post`, `put`,
|
||||
or `delete` attributes when using **Method**.
|
||||
- If more than one of those attributes is provided, only the first
|
||||
one that gets processed will be used.
|
||||
|
||||
</Note>
|
||||
|
||||
### Note
|
||||
|
||||
Use **Note** to add something that stands out to draw attention.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Note>
|
||||
##### Also available in black
|
||||
This style also comes in black, which we can all agree is the superior color
|
||||
</Note>
|
||||
<Note compact>And in pink _(compact)_</Note>
|
||||
<Note hideable>Yet another note _(hideable)_</Note>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Note>
|
||||
##### Also available in black
|
||||
This style also comes in black, which we can all agree is the superior color
|
||||
</Note>
|
||||
<Note compact>And in pink _(compact)_</Note>
|
||||
<Note hideable>Yet another note _(hideable)_</Note>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### ReadMore
|
||||
|
||||
The **ReadMore** tag allows you to insert a list of child-pages.
|
||||
The list is automatically generated from the pages in the subdirectories
|
||||
of the documentation page's directory.
|
||||
This tag is typically used on overview pages, such as our [Markdown guide](/guides/markdown) page.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `asMenu` | | `false` | Start from the parent directory |
|
||||
| `depth` | | 99 | Maximum levels to recurse |
|
||||
| `recurse` | |`false` | Include all child-pages and sub-child-pages in the entire directory tree |
|
||||
| `root` | | `false` | Start from the root directory |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<ReadMore asMenu />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<ReadMore asMenu />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Related
|
||||
|
||||
Use **Related** to add something that is relevant to the current topic.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Related>
|
||||
This snippet is provided by [the annotations plugin](/reference/plugins/annotations)
|
||||
</Related>
|
||||
<Related compact>See [snippets](/reference/snippets) _(compact)_</Related>
|
||||
<Related hideable>
|
||||
See [snippets](/reference/snippets) _(hideable)_
|
||||
</Related>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Related>
|
||||
This snippet is provided by [the annotations plugin](/reference/plugins/annotations)
|
||||
</Related>
|
||||
<Related compact>See [snippets](/reference/snippets) _(compact)_</Related>
|
||||
<Related hideable>
|
||||
See [snippets](/reference/snippets) _(hideable)_
|
||||
</Related>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### StatusCode
|
||||
|
||||
**StatusCode** is used to format HTTP response status codes.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `status` | yes | | The HTTP response status code to format |
|
||||
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<StatusCode status='200' /><br />
|
||||
<StatusCode status='401' />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<StatusCode status='200' /><br />
|
||||
<StatusCode status='401' />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Tab
|
||||
|
||||
**Tabs** and **Tab** tags are used to present content in a tabbed view.
|
||||
This is a view where only the active tab content is shown, with
|
||||
content in other tabs hidden.
|
||||
Selecting a different tab shows its contents while hiding
|
||||
the others.
|
||||
|
||||
The **Tab** tag is used to add content for a tab.
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Tabs tabs="one, two">
|
||||
<Tab>
|
||||
Content for tab one.
|
||||
</Tab>
|
||||
<Tab>
|
||||
This is tab two content.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Tabs tabs="one, two">
|
||||
<Tab>
|
||||
Content for tab one.
|
||||
</Tab>
|
||||
<Tab>
|
||||
Content for tab two.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
|
||||
- The content of **Tabs** is individual **Tab** tags.
|
||||
- The content of **Tab** is content for that tab.
|
||||
- There should be one **Tab** for every tab defined in the `tabs` attribute of **Tabs**.
|
||||
|
||||
</Note>
|
||||
|
||||
### Tabs
|
||||
|
||||
**Tabs** and **Tab** tags are used to present content in a tabbed view.
|
||||
This is a view where only the active tab content is shown, with
|
||||
content in other tabs hidden.
|
||||
Selecting a different tab shows its contents while hiding
|
||||
the others.
|
||||
|
||||
The **Tabs** tag is used to set up the tabbed view.
|
||||
It specifies how many tabs are in the view and what their names
|
||||
are.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `tabs` | yes | | Comma-separated list of tab names |
|
||||
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Tabs tabs="one, two">
|
||||
<Tab>
|
||||
Content for tab one.
|
||||
</Tab>
|
||||
<Tab>
|
||||
This is tab two content.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Tabs tabs="one, two">
|
||||
<Tab>
|
||||
Content for tab one.
|
||||
</Tab>
|
||||
<Tab>
|
||||
Content for tab two.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
|
||||
- The content of **Tabs** is individual **Tab** tags.
|
||||
- The content of **Tab** is content for that tab.
|
||||
- There should be one **Tab** for every tab defined in the `tabs` attribute of **Tabs**.
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
### Tip
|
||||
|
||||
Use **Tip** for, you know, tips.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Tip>
|
||||
The notches on the shoulder and sleeve parts are used to help with
|
||||
alignment when attaching the sleeve.
|
||||
</Tip>
|
||||
<Tip compact>Align the notches so they match _(compact)_</Tip>
|
||||
<Tip hideable>
|
||||
Yet another tip _(hideable)_
|
||||
</Tip>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Tip>
|
||||
The notches on the shoulder and sleeve parts are used to help with
|
||||
alignment when attaching the sleeve.
|
||||
</Tip>
|
||||
<Tip compact>Align the notches so they match _(compact)_</Tip>
|
||||
<Tip hideable>
|
||||
Yet another tip _(hideable)_
|
||||
</Tip>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Tldr
|
||||
|
||||
"TL;DR" stands for "Too long; didn't read", and the **Tldr** tag used
|
||||
to provide a short summary for readers who might not want to read
|
||||
the full text.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Tldr>
|
||||
This page lists all the custom tags you can use.
|
||||
</Tldr>
|
||||
<Tldr compact>This page lists custom tags _(compact)_</Tldr>
|
||||
<Tldr hideable>
|
||||
Yet another TL;DR summary _(hideable)_
|
||||
</Tldr>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Tldr>
|
||||
This page lists all the custom tags you can use.
|
||||
</Tldr>
|
||||
<Tldr compact>This page lists custom tags _(compact)_</Tldr>
|
||||
<Tldr hideable>
|
||||
Yet another TL;DR summary _(hideable)_
|
||||
</Tldr>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Warning
|
||||
|
||||
Use **Warning** when you want to warn the reader of potential danger or unintended side-effects.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ---------: | :-------: | ------- | ----------- |
|
||||
| `compact` | | `false` | Renders compact variant |
|
||||
| `hideable` | | `false` | Allows popout to be hidden |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
<Warning>
|
||||
##### Please make a backup
|
||||
Following these instructions will remove all your data
|
||||
</Warning>
|
||||
<Warning compact>Take it slow _(compact)_</Warning>
|
||||
<Warning hideable>
|
||||
Yet another warning _(hideable)_
|
||||
</Warning>
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
<Warning>
|
||||
##### Please make a backup
|
||||
Following these instructions will remove all your data
|
||||
</Warning>
|
||||
<Warning compact>Take it slow _(compact)_</Warning>
|
||||
<Warning hideable>
|
||||
Yet another warning _(hideable)_
|
||||
</Warning>
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### YouTube
|
||||
|
||||
The **YouTube** tag will embed YouTube videos or YouTube playlists responsively.
|
||||
|
||||
| Attribute | Required? | Default | Description |
|
||||
| ----:| :---: | ------- | ----------- |
|
||||
| `id` | yes | | ID of the YouTube video or playlist |
|
||||
| `playlist` | | `false` | Set this when embedding a playlist |
|
||||
|
||||
<Tabs tabs="example, markdown">
|
||||
<Tab>
|
||||
#### Video
|
||||
<YouTube id='Rz6ShSftDlI' />
|
||||
#### Playlist
|
||||
<YouTube id='PL1gv5yv3DoZOFSXz7yydeV1H8m6pfwstn' playlist />
|
||||
</Tab>
|
||||
<Tab>
|
||||
```markdown
|
||||
### Video
|
||||
<YouTube id='Rz6ShSftDlI' />
|
||||
### Playlist
|
||||
<YouTube id='PL1gv5yv3DoZOFSXz7yydeV1H8m6pfwstn' playlist />
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
title: Markdown guide
|
||||
order: 900
|
||||
---
|
||||
|
||||
Markdown is a lightweight markup language with plain text formatting syntax.
|
||||
It is designed to be easily readable by humans and computers alike.
|
||||
|
||||
Markdown is often used to format documentation, online comments,
|
||||
or anywhere where you want rich text while using a plain text editor.
|
||||
|
||||
In this guide, we'll look at the following topics:
|
||||
|
||||
<ReadMore />
|
||||
|
||||
This will be enough to get you started. If you'd like to learn more,
|
||||
visit [markdownguide.org](https://www.markdownguide.org/).
|
|
@ -1,146 +0,0 @@
|
|||
---
|
||||
title: Avoiding frequent mistakes
|
||||
order: zzz
|
||||
---
|
||||
|
||||
Some things to keep in mind when working in Markdown are:
|
||||
|
||||
## Use remark-jargon for glossary terms
|
||||
|
||||
There is no need to add a _glossary_ section to documentation.
|
||||
We use a plugin called [rehype-jargon][rj] to explain terms.
|
||||
Information can be found at the link.
|
||||
|
||||
[rj]: https://github.com/freesewing/freesewing/blob/develop/packages/rehype-jargon/README.md
|
||||
|
||||
## Let lists be lists
|
||||
|
||||
Please make sure to use Markdown proper, doing things such as hardcoding
|
||||
numbers for lists and using `·` for bulleted lists won't be rendered
|
||||
properly and will be styled differently.
|
||||
Using Markdown in the same way for everything ensures the site and
|
||||
documentation look clean and professional. You can use a Markdown editor
|
||||
like [StackEdit](https://stackedit.io/) to preview your text.
|
||||
|
||||
<Note>
|
||||
GitHub itself also allows working in Markdown and will give you a handy preview!
|
||||
</Note>
|
||||
|
||||
## Create links with meaningful link text
|
||||
|
||||
When adding links please do not create them using a structure like:
|
||||
"Link [here][yt]". Instead use relevant terms for the link text.
|
||||
An example of meaningful link text is this link to a
|
||||
[famous 80s pop song video][yt].
|
||||
|
||||
[yt]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
||||
|
||||
## Make sure your links lead where you think they do
|
||||
|
||||
### Linking within the same website
|
||||
|
||||
When you are linking within freesewing.dev or freesewing.org you can use a relative link from
|
||||
the site root.
|
||||
Use:
|
||||
|
||||
```text
|
||||
/guides/markdown/frequent-mistakes
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
```text
|
||||
https://freesewing.dev/guides/markdown/frequent-mistakes
|
||||
```
|
||||
|
||||
### Linking images
|
||||
|
||||
Images can be put in the same folder you are working on with a link
|
||||
to the filename. For example:
|
||||
|
||||
```markdown
|
||||
This is [a picture of a banana](banana.jpg)
|
||||
```
|
||||
|
||||
## Avoid ambiguity when listing a number of steps
|
||||
|
||||
If you're writing documentation that involves steps, please do not mix levels
|
||||
of steps. Steps written out in documentation are there to facilitate brainless
|
||||
execution. Don't be afraid to repeat yourself.
|
||||
|
||||
If you use substeps we want those substeps to take away ambiguity rather
|
||||
than introduce it into your instructions. In the next example the substep
|
||||
introduces something that ought to be done before the previous steps.
|
||||
This creates confusion about when that step ought to be executed.
|
||||
|
||||
An example of what not to do:
|
||||
|
||||
```md
|
||||
1. cut collar
|
||||
2. cut collar stand
|
||||
3. sew collar stand to collar
|
||||
1. sewing staystitch collar and collar stand
|
||||
4. sew collar stand to neckline
|
||||
```
|
||||
|
||||
## Be mindful of white space and whitespace characters
|
||||
|
||||
Markdown syntax for white space in text is a little unintuitive.
|
||||
|
||||
- If you want a line break after a line but no white space between it and
|
||||
the next line, you need to add two space characters at the end of the
|
||||
first line.
|
||||
|
||||
- If you want a paragraph break with white space between the two lines,
|
||||
you need to add at least one blank line after the first line.
|
||||
|
||||
- If you don't have two space characters at the end of the first line or
|
||||
any blank lines between it and the second line, then no white space or
|
||||
line break will be generated.
|
||||
Instead, the two lines will be part of the same continuous paragraph in the
|
||||
resulting page even though they are on two separate lines in your document.
|
||||
|
||||
It may be helpful to experiment and keep checking the preview or resulting
|
||||
page to see how things look. Not all the empty lines and white space in your
|
||||
document will render in the preview or result.
|
||||
|
||||
## Using custom tag components
|
||||
|
||||
When you're using custom tag components you want to leave an empty line before
|
||||
and after the tags.
|
||||
|
||||
```markdown
|
||||
Lorem ipsum dolor sit amet,
|
||||
|
||||
<Note>
|
||||
consectetur adipisci elit,
|
||||
</Note>
|
||||
|
||||
sed eiusmod tempor incidunt ut labore et dolore magna aliqua.
|
||||
```
|
||||
|
||||
If you're using any Markdown syntax within a custom component you want to also
|
||||
leave an empty line at the start and end of your component.
|
||||
|
||||
```markdown
|
||||
Lorem ipsum dolor sit amet,
|
||||
|
||||
<Note>
|
||||
|
||||
*consectetur adipisci elit,*
|
||||
|
||||
</Note>
|
||||
|
||||
sed eiusmod tempor incidunt ut labore et dolore magna aliqua.
|
||||
```
|
||||
|
||||
## Don't be shy to ask a friend
|
||||
|
||||
Learning a new language can be intimidating, whether its JavaScript, Norse, or
|
||||
Markdown, but everyone in the Freesewing community is glad you're here and
|
||||
helping us make the site even more awesome.
|
||||
|
||||
If you get lost or have a question about how to do something, feel free to come
|
||||
[ask on the Discord](https://discord.freesewing.org/).
|
||||
We've all had to learn Markdown at some point and would be
|
||||
delighted to pass knowledge on.
|
|
@ -1,26 +0,0 @@
|
|||
---
|
||||
title: Headings
|
||||
order: 40
|
||||
---
|
||||
|
||||
Prefix your line with a number of `#` characters to determine the header level.
|
||||
|
||||
```md
|
||||
### This is a H3 heading
|
||||
|
||||
#### This is a H4 heading
|
||||
|
||||
##### This is a H5 heading
|
||||
```
|
||||
|
||||
### This is a H3 heading
|
||||
|
||||
#### This is a H4 heading
|
||||
|
||||
##### This is a H5 heading
|
||||
|
||||
<Note>
|
||||
|
||||
Keep in mind that you should never use an H1 element, for that will be the page title.
|
||||
|
||||
</Note>
|
|
@ -1,27 +0,0 @@
|
|||
---
|
||||
title: Images
|
||||
order: 70
|
||||
---
|
||||
|
||||
Images are like links, but you prefix them with an exclamation mark.
|
||||
|
||||
The part between square brackets is the image alt text.
|
||||
|
||||
Between the curly brackets you place the location of the image file
|
||||
followed by a space and the image title between quotes.
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
<Tip>
|
||||
|
||||
##### Images go in the same folder as your Markdown file
|
||||
|
||||
The convention is to always place your images in the same folder as the
|
||||
text where you are including the image. That way, you just need to specify
|
||||
the image name, and not the path to its location.
|
||||
|
||||
</Tip>
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
title: Italics and bold
|
||||
order: 30
|
||||
---
|
||||
|
||||
```md
|
||||
You can make text *italic* or **bold**
|
||||
by wrapping it in 1 or 2 asterisk respectively.
|
||||
```
|
||||
|
||||
You can make text _italic_ or **bold** by wrapping it in 1 or 2 asterisk respectively:
|
||||
|
||||
```md
|
||||
Alternatively, you can also use underscores to mark _italic_ or __bold__.
|
||||
```
|
||||
|
||||
Alternatively, you can also use underscores to mark _italic_ or **bold**.
|
|
@ -1,84 +0,0 @@
|
|||
---
|
||||
title: Using jargon and terms
|
||||
---
|
||||
|
||||
Jargon or terms is anything that could throw off new users.
|
||||
Rather than create a glossary on every page, we use MDX to manage
|
||||
jargon/terms for us. This page shows you how to use it.
|
||||
|
||||
<Tip compact>Think of jargon as glossary terms</Tip>
|
||||
|
||||
## Defining terms
|
||||
|
||||
To define a term, we need to establish a link between the term itself, and the documentation page that defines it.
|
||||
|
||||
In the most common scenario, the term is the title of the page.
|
||||
For example, the title of this page is `Using jargon and terms`:
|
||||
|
||||
```mdx
|
||||
---
|
||||
title: Using jargon and terms
|
||||
---
|
||||
```
|
||||
|
||||
If we wanted to make it available as jargon, we only need to add the `jargon` frontmatter:
|
||||
|
||||
```mdx
|
||||
---
|
||||
title: Using jargon and terms
|
||||
jargon: true
|
||||
---
|
||||
```
|
||||
|
||||
## Multiple terms for the same page
|
||||
|
||||
We can add additional terms that point to the same page by setting the `terms` in frontmatter to a comma-seperated list of terms.
|
||||
|
||||
For example to make both `jargon` and `term` point to this page, we can do this:
|
||||
|
||||
|
||||
```mdx
|
||||
---
|
||||
title: Using jargon and terms
|
||||
jargon: true
|
||||
terms: jargon, term
|
||||
---
|
||||
```
|
||||
|
||||
## Terminology per site
|
||||
|
||||
The following pages show a list of all terminology per site:
|
||||
|
||||
| Site | Terminology List |
|
||||
| ---- | ---------------- |
|
||||
| FreeSewing.dev | [/reference/terminology](/reference/terms) |
|
||||
| FreeSewing.org | [/docs/about/terminology](https://freesewing.org/docs/about/terms) |
|
||||
|
||||
All of the terms listed in the pages above can be used in the markdown/mdx
|
||||
content of those websites.
|
||||
|
||||
## Using jargon terms in MDX content
|
||||
|
||||
To use jargon inside MDX content (like the markdown of our documentation, blog
|
||||
posts, and so on), it's sufficient to emphasize the term:
|
||||
|
||||
```md
|
||||
We are migrating from _cjs_ to _esm_ modules
|
||||
```
|
||||
|
||||
Which renders as:
|
||||
|
||||
We are migrating from _cjs_ to _esm_ modules
|
||||
|
||||
## Using jargon terms outside MDX content
|
||||
|
||||
Outside MDX content -- more precisely, in React components -- you can achieve the same effect with the `Term` component:
|
||||
|
||||
```mjs
|
||||
import { Term } from 'site/components/jargon.mjs'
|
||||
|
||||
export const MyComponent = () => (
|
||||
<p>Look, it works here too: <Term>esm</Term></p>
|
||||
)
|
||||
```
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Line breaks
|
||||
order: 20
|
||||
---
|
||||
|
||||
If you want to force a line break but not a new paragraph,
|
||||
simply leave 2 spaces at the end of the line.
|
||||
|
||||
```md
|
||||
Like
|
||||
this.
|
||||
```
|
||||
|
||||
Like
|
||||
this.
|
|
@ -1,39 +0,0 @@
|
|||
---
|
||||
title: Links
|
||||
order: 60
|
||||
---
|
||||
|
||||
Links combine square brackets for the link text with round brackets for the destination.
|
||||
|
||||
```md
|
||||
[Like this](https://freesewing.org)
|
||||
```
|
||||
|
||||
[Like this](https://freesewing.org)
|
||||
|
||||
An alternative notation allows you to include the links as such:
|
||||
|
||||
```md
|
||||
See [the reference documentation][1] on [freesewing.dev][2]
|
||||
|
||||
[1]: https://freesewing.dev/reference
|
||||
[2]: https://freesewing.dev/reference
|
||||
```
|
||||
|
||||
See [the reference documentation][1] on [freesewing.dev][2]
|
||||
|
||||
[1]: https://freesewing.dev/reference
|
||||
|
||||
[2]: https://freesewing.dev/reference
|
||||
|
||||
You don't have to use numbers, but can also use named references.
|
||||
|
||||
```md
|
||||
We moved the Markdown content to [our monorepo][monorepo]
|
||||
|
||||
[monorepo]: https://github.com/freesewing/freesewing
|
||||
```
|
||||
|
||||
We moved the Markdown content to [our monorepo][monorepo]
|
||||
|
||||
[monorepo]: https://github.com/freesewing/freesewing
|
|
@ -1,32 +0,0 @@
|
|||
---
|
||||
title: Lists
|
||||
order: 50
|
||||
---
|
||||
|
||||
To make a list, just do as you would in plain text:
|
||||
|
||||
```md
|
||||
- a bullet
|
||||
- list
|
||||
- a sublist
|
||||
- item
|
||||
```
|
||||
|
||||
- a bullet
|
||||
- list
|
||||
- a sublist
|
||||
- item
|
||||
|
||||
If you want an numbered list, just write numbers.
|
||||
They don't even have to be the correct numbers:
|
||||
|
||||
```md
|
||||
|
||||
1. Item 1
|
||||
2. Item 2
|
||||
2. Item 3
|
||||
```
|
||||
|
||||
1. Item 1
|
||||
2. Item 2
|
||||
3. Item 3
|
|
@ -1,36 +0,0 @@
|
|||
---
|
||||
title: Tables
|
||||
order: 70
|
||||
---
|
||||
|
||||
If you need them, you can create tables too, using a structure as shown below:
|
||||
|
||||
```md
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight |
|
||||
| Mixture | Two or more substances that are not chemically united, such as air |
|
||||
| Solution | A uniform mixture of varying proportions of a solvent and a solute |
|
||||
```
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight |
|
||||
| Mixture | Two or more substances that are not chemically united, such as air |
|
||||
| Solution | A uniform mixture of varying proportions of a solvent and a solute |
|
||||
|
||||
You can change the alignment of the columns by using a colon (`:`) on the line below the column title:
|
||||
|
||||
```md
|
||||
| Align-right | Align-center |
|
||||
| -----------:|:------------:|
|
||||
| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight |
|
||||
| Mixture | Two or more substances that are not chemically united, such as air |
|
||||
| Solution | A uniform mixture of varying proportions of a solvent and a solute |
|
||||
```
|
||||
|
||||
| Align-right | Align-center |
|
||||
| -----------:|:------------:|
|
||||
| Compound | A substance composed of two or more elements. Chemically combined in definite proportions by weight |
|
||||
| Mixture | Two or more substances that are not chemically united, such as air |
|
||||
| Solution | A uniform mixture of varying proportions of a solvent and a solute |
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: Text and paragraphs
|
||||
order: 10
|
||||
---
|
||||
|
||||
For the most part, you can just write as you would in any other format.
|
||||
|
||||
```md
|
||||
You can just start writing.
|
||||
|
||||
An empty line starts a new paragraph.
|
||||
```
|
||||
|
||||
You can just start writing.
|
||||
|
||||
An empty line starts a new paragraph.
|
|
@ -1,23 +0,0 @@
|
|||
---
|
||||
title: Plugin guide
|
||||
---
|
||||
|
||||
Plugins allow you to extend FreeSewing with new features and functionality.
|
||||
A FreeSewing plugin can extend FreeSewing in 3 different ways:
|
||||
|
||||
- It can [provide macros](/guides/plugins/macros), which are a way to automate a number of steps into a
|
||||
single command.
|
||||
- It can [hook into the pattern](/guides/plugins/hooks), which allows you to manipulate the pattern or
|
||||
interact with it at various stages of it's lifecycle.
|
||||
- It can [provide store methods](/guides/plugins/store), which allows you to add new ways to handle data
|
||||
in the pattern, including providing a custom logger.
|
||||
|
||||
We have [a list of plugins](/reference/plugins/) that we maintain, but
|
||||
if you can't find what you're looking for, you can write your own plugin.
|
||||
|
||||
If you plan on doing that or if you would like to understand how plugins work,
|
||||
this guide is for you.
|
||||
|
||||
We'll cover the following topics:
|
||||
|
||||
<ReadMore />
|
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
title: Lifecycle hook methods
|
||||
order: 110
|
||||
---
|
||||
|
||||
FreeSewing plugins can provide hooks, which is a way to hook into the pattern's
|
||||
lifecycle.
|
||||
|
||||
## Signature
|
||||
|
||||
To provide one or more hooks, your plugin should have a `hooks` property that
|
||||
is an object where the keys are the lifecycle hook name and the value holds a
|
||||
method. When the lifecycle hook is triggered, your method will be called.
|
||||
|
||||
```mjs
|
||||
const myPlugin = {
|
||||
name: 'example',
|
||||
version: '0.0.1',
|
||||
hooks: {
|
||||
hookName: function (obj, data = {}) {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to attach multiple methods to the same lifecycle hook, you can pass
|
||||
them as an array:
|
||||
|
||||
```mjs
|
||||
const myPlugin = {
|
||||
name: 'example',
|
||||
version: '0.0.1',
|
||||
hooks: {
|
||||
hookName: [
|
||||
function one (obj, data = {}) { },
|
||||
function two (obj, data = {}) { }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
All lifecycle methods will receive two parameters:
|
||||
|
||||
- An object relevant to the lifecycle hook. See the [hooks API reference](/reference/hooks/) for details.
|
||||
- Data passed when the hook was registered (optional)
|
||||
|
||||
## Notes
|
||||
|
||||
Refer to the [hooks API reference](/reference/hooks/) for a list of all
|
||||
available lifecycle hooks.
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
title: Loading plugins
|
||||
order: 140
|
||||
---
|
||||
|
||||
Plugins can be loaded at build time and added to the design.
|
||||
Or, they can be added at run time and added to an instantiated pattern.
|
||||
|
||||
To load a plugin at build time, it should be added to [the `plugins` key of the part configuration](/reference/api/part/config/plugins).
|
||||
|
||||
To load a plugin at run time, it should be loaded with a call to [`Pattern.use()`](/reference/api/pattern/use).
|
||||
|
||||
Please refer to the relevant documentation for more details.
|
|
@ -1,46 +0,0 @@
|
|||
---
|
||||
title: Macro methods
|
||||
order: 120
|
||||
---
|
||||
|
||||
FreeSewing plugins can provide macros, which is a way to automate multiple
|
||||
steps into a single command.
|
||||
|
||||
## Signature
|
||||
|
||||
To provide one or more macros, your plugin should have a `macros` property that
|
||||
is an object where the keys are the macro name, and the value holds a method to
|
||||
run when the macro is executed.
|
||||
|
||||
```mjs
|
||||
const myPlugin = {
|
||||
name: 'example',
|
||||
version: '0.0.1',
|
||||
macros: {
|
||||
example: function(so, { log }) {
|
||||
log.info('Running the example macro')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
All macros receive two arguments:
|
||||
|
||||
- `so`: A plain object holding configuration object passed to the macro
|
||||
- `props`: The same object as passed to the [`Part.draft()`](/reference/api/part/draft) method that you can destructure
|
||||
|
||||
<Note>
|
||||
###### Macros take only 1 argument
|
||||
|
||||
When writing a macro, keep in mind that all information that needs to be passed
|
||||
to a macro needs to be contained in a single argument.
|
||||
|
||||
Typically, you use a single plain object to configure the macro.
|
||||
|
||||
</Note>
|
||||
|
||||
## Return value
|
||||
|
||||
Macros do not need to return anything. If they do, it will be ignored.
|
|
@ -1,57 +0,0 @@
|
|||
---
|
||||
title: Store methods
|
||||
order: 130
|
||||
---
|
||||
|
||||
FreeSewing plugins can provide store methods, which facilitate data handling
|
||||
within a pattern.
|
||||
|
||||
## Signature
|
||||
|
||||
To provide one or more store methods, your plugin should have a `store` property that
|
||||
is an array where each member is itself an array with two members:
|
||||
|
||||
- The first member holds the key to attach the method to (in dot notation)
|
||||
- The second member holds the method to attach
|
||||
|
||||
```mjs
|
||||
const myPlugin = {
|
||||
name: 'example',
|
||||
version: '0.0.1',
|
||||
store: [
|
||||
[
|
||||
'log.panic',
|
||||
function(store, ...params) {
|
||||
store.setIfUnset('logs.panic', new Array())
|
||||
store.push(...params)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
All store methods receive at least two arguments:
|
||||
|
||||
- `store`: The store object itself
|
||||
- `...params`: All additional plugins that were passed to the store method
|
||||
|
||||
## Overwriting store methods
|
||||
|
||||
You are allowed to overwrite existing store methods.
|
||||
As it happens, this is how you should implement a custom logging solution,
|
||||
by overwriting the logging methods under the store's `log` key,
|
||||
|
||||
However, the following store methods cannot be overwritten:
|
||||
|
||||
- `extend()`
|
||||
- `get()`
|
||||
- `push()`
|
||||
- `set()`
|
||||
- `setIfUnset()`
|
||||
- `unset()`
|
||||
|
||||
## Return value
|
||||
|
||||
Store methods do not need to return anything. If they do, it will be ignored.
|
|
@ -1,25 +0,0 @@
|
|||
---
|
||||
title: Plugin structure
|
||||
order: 100
|
||||
---
|
||||
|
||||
A FreeSewing plugin is a plain object with the following structure:
|
||||
|
||||
```mjs
|
||||
Object plugin = {
|
||||
String name,
|
||||
String version,
|
||||
Object hooks,
|
||||
Object macros,
|
||||
Array store,
|
||||
}
|
||||
```
|
||||
|
||||
A plugin **must** have the `name` and `version` properties.
|
||||
The other properties are optional, and they map to the three different functionalities macros can provide:
|
||||
|
||||
- [`hooks`](/guides/plugins/hooks): Holds an object with lifecycle hooks the plugin wants to hook into
|
||||
- [`macros`](/guides/plugins/macros): Holds and object with macros the plugin provides
|
||||
- [`store`](/guides/plugins/store): Holds and Array with store methods the plugin provides.
|
||||
|
||||
Click on the links above for more details on the structure of these properties.
|
|
@ -1,55 +0,0 @@
|
|||
---
|
||||
title: Understanding Bézier curves
|
||||
order: 50
|
||||
---
|
||||
|
||||
While lines on computers are easy to store with a start and end point,
|
||||
curves require more information.
|
||||
In FreeSewing — as in SVG and countless of other computer applications —
|
||||
curves are stored as [Bézier curves](https://en.wikipedia.org/wiki/B%C3%A9zier_curve),
|
||||
named after French engineer [Pierre Bézier](https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier) who
|
||||
popularized their use back in the 1960s.
|
||||
|
||||
In FreeSewing, we use so-called cubic Bézier curves which have:
|
||||
|
||||
- A start point
|
||||
- A first control point that’s linked to the start point
|
||||
- A second control point that’s linked to the end point
|
||||
- An end point
|
||||
|
||||
<Example caption="An example of a Bézier curve drawn by the Path.curve() method" settings="margin: 20">
|
||||
```js
|
||||
({ Point, points, Path, paths, part }) => {
|
||||
|
||||
points.from = new Point(10, 20)
|
||||
points.cp1 = new Point(40, 0)
|
||||
points.cp2 = new Point(60, 40)
|
||||
points.to = new Point(90, 20)
|
||||
|
||||
paths.line = new Path()
|
||||
.move(points.from)
|
||||
.curve(points.cp1, points.cp2, points.to)
|
||||
.setText("Path.curve()", "text-sm center fill-note")
|
||||
|
||||
return part
|
||||
}
|
||||
```
|
||||
</Example>
|
||||
|
||||
Bézier curves and their _handles_ or _control points_ are surprisingly intuitive.
|
||||
The following illustration does a great job at explaining how they are constructed:
|
||||
|
||||

|
||||
|
||||
You don't need to understand the mathematics behind Bézier Curves.
|
||||
As long as you intuitively _get_ how the control points influence the curve, you're good to go.
|
||||
|
||||
<Note>
|
||||
|
||||
###### More on Bézier curves
|
||||
|
||||
Wikipedia has a good [introduction to Bézier curves](https://en.wikipedia.org/wiki/B%C3%A9zier_curve).
|
||||
For a deep-dive into the subject, check out [A Primer on Bézier Curves](https://pomax.github.io/bezierinfo/) by
|
||||
[Pomax](https://github.com/Pomax).
|
||||
|
||||
</Note>
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
title: The coordinate system
|
||||
order: 30
|
||||
---
|
||||
|
||||
The coordinate system in FreeSewing -- and in SVG -- follows the same rules as text on a page.
|
||||
You start at the top-left, and as you go to the right, the X-coordinate will increase.
|
||||
As you go down the Y-coordinate will increase.
|
||||
|
||||
<Example caption="The coordinate system in an SVG document">
|
||||
```mjs
|
||||
({ Point, points, paths, Path, part }) => {
|
||||
points.origin = new Point(10, 10)
|
||||
points.x = new Point(100, 10)
|
||||
points.y = new Point(10, 50)
|
||||
points.textX = new Point(85, 20).addText('X', 'text-lg')
|
||||
points.textY = new Point(12, 43).addText('Y', 'text-lg')
|
||||
paths.coords = new Path()
|
||||
.move(points.y)
|
||||
.line(points.origin)
|
||||
.line(points.x)
|
||||
.addClass('mark')
|
||||
.attr('marker-start', 'url(#dimensionFrom)')
|
||||
.attr('marker-end', 'url(#dimensionTo)')
|
||||
|
||||
return part
|
||||
}
|
||||
```
|
||||
</Example>
|
||||
|
||||
The image above illustrates both the X-axis and Y-axis.
|
||||
On the X-axis, `20` is further to the right than `10`.
|
||||
On the Y-axis, `50` is lower than `20`.
|
||||
|
||||
<Note>
|
||||
|
||||
The Y-axis is inverted in many drawing programs, with the origin
|
||||
`(0,0)` being the lower left corner, rather than the upper left corner.
|
||||
|
||||
This is a common point of confusion so keep in mind that the Y-axis may
|
||||
not behave as you would have intuitively expected.
|
||||
|
||||
</Note>
|
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
title: Before you start
|
||||
---
|
||||
|
||||
Drawing lines and curves on paper is a skill most people have been practicing since kindergarten.
|
||||
In FreeSewing, we draw lines and curves with code, which is a bit more abstract
|
||||
but doesn't have to be complicated once you understand a few basic building blocks.
|
||||
|
||||
Understanding the concepts that are involved in designing sewing patterns in code will pay dividends later.
|
||||
That is why we recommend you familiarize yourself with the following topics:
|
||||
|
||||
<ReadMore />
|
||||
|
||||
<Note>
|
||||
|
||||
##### There's no need to know everything
|
||||
|
||||
FreeSewing sits at the intersection of the world of makers and developers.
|
||||
If your background is in development, you will need no explaining what SVG is but might not
|
||||
know much about designing sewing patterns.
|
||||
If on the other hand your background is in sewing or pattern design, you might wonder what
|
||||
the heck NodeJS is and why you should care.
|
||||
|
||||
Few people straddle both worlds, so as you start using FreeSewing, chances are
|
||||
you'll learn a few new things along the way.
|
||||
|
||||
And if you get stuck [our chatrooms on Discord](https://discord.freesewing.org/) are the best place to get help.
|
||||
</Note>
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
title: Scalable Vector Graphics
|
||||
order: 20
|
||||
---
|
||||
|
||||
Patterns are rendered as **SVG** — short
|
||||
for [Scalable Vector Graphics](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) —
|
||||
an XML-based vector image format and an open standard.
|
||||
While you don’t need to be an SVG expert, a basic understanding of the format
|
||||
will greatly help you to understand FreeSewing.
|
||||
|
||||
For example, the coordinate system and the way paths
|
||||
are structured are all related to the SVG drawing system, which is closely related
|
||||
to other 2D drawing technologies such as PostScript or PDF.
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
title: Units in FreeSewing
|
||||
order: 40
|
||||
---
|
||||
|
||||
FreeSewing uses _millimeter (mm)_ for all its internal units.
|
||||
We do support both imperial and metrics units, which are displayed
|
||||
as _cm_ or _inch_, but under the hood everything is handled in millimeter.
|
||||
|
||||
So as a pattern designer, you will work with mm.
|
||||
When you write `1`, that’s one millimeter. When you write `7.8`, that’s 7.8 mm.
|
||||
|
||||
While you can use cm or inch on the FreeSewing website, that is merely a layer of
|
||||
abstraction on top of the internal units, which are always mm.
|
|
@ -1,223 +0,0 @@
|
|||
---
|
||||
title: Translation guide
|
||||
---
|
||||
|
||||
Supporting multiple languages is one of the best way to promote inclusion and
|
||||
accessibility. Thanks to the efforts of our community, FreeSewing is proudly
|
||||
multilingual.
|
||||
|
||||
This translation guide covers everything you need to know to join the effort of
|
||||
translating FreeSewing into other languages.
|
||||
|
||||
## Supported Languages
|
||||
|
||||
FreeSewing is currently available in the following languages:
|
||||
|
||||
| Code | Language | Website |
|
||||
| ----:|:-------------- |:------- |
|
||||
| `de` | **German** | https://freesewing.org/de |
|
||||
| `en` | **English** | https://freesewing.org/ |
|
||||
| `es` | **Spanish** | https://freesewing.org/es |
|
||||
| `fr` | **French** | https://freesewing.org/fr |
|
||||
| `nl` | **Dutch** | https://freesewing.org/nl |
|
||||
| `uk` | **Ukrainian** | https://freesewing.org/uk |
|
||||
|
||||
<Note compact>
|
||||
English is the translation source language and the working language of the FreeSewing project
|
||||
</Note>
|
||||
|
||||
## Become a FreeSewing translator
|
||||
|
||||
To gain access as a FreeSewing translator, you will need an invite.
|
||||
You can request a translator invite with the link below.
|
||||
When you do, we will send you an email with all further instructions.
|
||||
|
||||
<Link compact>
|
||||
|
||||
###### [Request a FreeSewing translator invite](https://freesewing.org/translation/join)
|
||||
</Link>
|
||||
|
||||
<Tip>
|
||||
|
||||
We also have [a dedicated __Translation__ channel on
|
||||
Discord](https://discord.freesewing.org) for any questions that may remain.
|
||||
</Tip>
|
||||
|
||||
## Adding a new language
|
||||
|
||||
We would love to make FreeSewing available in more languages. If you are
|
||||
interested in starting a new translation effort, that is great.
|
||||
|
||||
We ask that you familiarize yourself with this translation guide to understand
|
||||
what it takes to add a new language. Then if you can submit your request to setup
|
||||
a new language with the link below.
|
||||
|
||||
<Link compact>
|
||||
|
||||
###### [Suggest a new FreeSewing language](https://freesewing.org/translation/suggest-language)
|
||||
</Link>
|
||||
|
||||
<Tip>
|
||||
|
||||
##### Get the band together
|
||||
|
||||
We recommend finding some like-minded people who can help translating.
|
||||
|
||||
While the core materials of FreeSewing can realistically be handled by one
|
||||
person, translating all of FreeSewing's documentation and content realistically
|
||||
is a job you should not undertake on your own.
|
||||
|
||||
</Tip>
|
||||
|
||||
<Comment by="joost" >
|
||||
|
||||
##### Do or do not. There is no try.
|
||||
|
||||
There is a certain cost to adding a new language. It's not a cost in money,
|
||||
but rather in increased bandwidth, storage requirements, build times,
|
||||
repository size, test times, and so on.
|
||||
|
||||
It's a cost we are __more than happy__ to pay for the benefit gaining another
|
||||
langauge. But it is also a cost that needs to be paid up front, at the start
|
||||
of the effort.
|
||||
|
||||
So, without wanting to discourage anyone, I would really like to avoid a
|
||||
scenario where people enthusiastically start working on a new languages, only
|
||||
to lose interest days or weeks later and see the effort falter.
|
||||
|
||||
With that out of the way, I hope to see many more languages being added in the
|
||||
future.
|
||||
|
||||
</Comment>
|
||||
|
||||
## Translation status
|
||||
|
||||
The status of the ongoing translation work is available at
|
||||
[FreeSewing.org/translation](https://freesewing.org/translation).
|
||||
|
||||
It's a good place to check what languages need extra help, and which are
|
||||
leading the scoreboard.
|
||||
|
||||
## Translation priorities
|
||||
|
||||
To fully translate FreeSewing, the following types of content needs to be
|
||||
translated:
|
||||
|
||||
### Top priority: UX Translations
|
||||
These are translations the directly impact
|
||||
the user experience (_UX_). They include the content used in design, the names
|
||||
of options, translations of menus, emails, and so on.
|
||||
|
||||
This is a relatively small amount of text, and makes up less than 10% of the
|
||||
top & high priority content. It's an effort that a motivated translator can
|
||||
complete over the course of a weekend.
|
||||
|
||||
<Tip>
|
||||
The top-priority translations in Crowdin are everything under the `packages`
|
||||
and `sites` folder. Do this first.
|
||||
</Tip>
|
||||
|
||||
### High priority: Translation of Documentation
|
||||
This includes all the documentation on FreeSewing.org.
|
||||
|
||||
This is a significant amount of text that makes up more than 90% of the top &
|
||||
high priority content. It's an effort you should probably not take on by
|
||||
yourself, but rather tackle with a team of translators.
|
||||
|
||||
<Tip>
|
||||
The high-priory translations in Crowdin is everything under the
|
||||
`markdown/org/docs` folder.
|
||||
</Tip>
|
||||
|
||||
### Low Priority: Content of blog and showcase posts, and newsletters
|
||||
This is _nice to have_ as people can use and navigate FreeSewing even when this
|
||||
content remains untranslated.
|
||||
|
||||
<Tip>
|
||||
The low-priory translations in Crowdin is everything under the
|
||||
`markdown/org/blog`, `markdown/org/showcase`, and `markdown/org/newsletter` folders.
|
||||
</Tip>
|
||||
|
||||
## Translation through Crowdin
|
||||
|
||||
All of our translation work is handled through [Crowdin](https://crowdin.com/),
|
||||
an online platform to facilitate translation.
|
||||
|
||||
<Tip compact>
|
||||
|
||||
You can reach the FreeSewing project on Crowdin directly via
|
||||
[translate.freesewing.org](https://translate.freesewing.org).
|
||||
</Tip>
|
||||
|
||||
Crowdin is configured to automatically detect all of the various translation
|
||||
files in our repository, upload them to the platform, and break them apart into
|
||||
bite-sized portions that you can translate in a collaborative way.
|
||||
Rather than work on one large block of text, various people can jump in and
|
||||
translate smaller snippets,
|
||||
|
||||
Once translated, there is a proofreading step that will be handled by one of
|
||||
our proofreaders. This is often a formality, but it's an extra step to allow
|
||||
quality assurance and avoid any mistakes from slipping in. Much like the code
|
||||
review process when you submit a pull request on GitHub.
|
||||
|
||||
Once your translation is approved, Crowdin will automatically submit a pull
|
||||
request on GitHub to update the translation files in our repository. And the
|
||||
next time our website or software packages get built, they will include the new
|
||||
translations.
|
||||
|
||||
## Machine translation
|
||||
|
||||
While everybody knows that translation is best when it's done by a human being,
|
||||
we also have to be realistic that the growing body of documentation and other
|
||||
FreeSewing content can be a daunting task to take on for translators, especially
|
||||
when you want to start a new language.
|
||||
|
||||
Fortunately, machine translation has gotten rather good so we can get some help.
|
||||
Our Crowdin project is integrated with a [DeepL](https://www.deepl.com)
|
||||
subscription, and this can be a great help to translators.
|
||||
|
||||
You can use the DeepL suggestions when translating, or there is also the possibility
|
||||
to machine-translate entire files or folders. For example, you may start a new
|
||||
language by machine-translating everything, and then focus on proofreading the
|
||||
top-priority content, and then move on to the high-priority content.
|
||||
|
||||
## Syntax
|
||||
|
||||
Most strings are just text, but sometimes you'll find a little markup sprinkled in.
|
||||
|
||||
### HTML formatting
|
||||
|
||||
When you encounter HTML tags, simply translate around them. For example:
|
||||
|
||||
```yaml
|
||||
<b>No</b>, never.
|
||||
```
|
||||
|
||||
looks like this in Spanish:
|
||||
|
||||
```yaml
|
||||
<b>No</b>, nunca.
|
||||
```
|
||||
|
||||
### Placeholders
|
||||
|
||||
When you encounter a `{key}` between curly braces, leave it as-is.
|
||||
These will be filled in later with the correct value. For example:
|
||||
|
||||
```yaml
|
||||
{field} saved
|
||||
```
|
||||
|
||||
looks like this in Spanish
|
||||
|
||||
```yaml
|
||||
{field} guardado
|
||||
```
|
||||
|
||||
## Questions, Suggestions, Discussion
|
||||
|
||||
If you have questions, suggestions, or would like to discuss
|
||||
translation-related matters, please join
|
||||
[discord.freesewing.org](https://discord.freesewing.org/) and head to the
|
||||
__Translation__ channel.
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
title: Body ambassador
|
||||
---
|
||||
|
||||
Maybe you’re unusually short or tall.
|
||||
Maybe you have a bit of a pot belly or very large breasts.
|
||||
Maybe you have a disability that requires fit adjustments.
|
||||
|
||||
Whatever it is, if you represent a minority fitting issue you could
|
||||
represent this minority to make sure their needs are heard and understood.
|
||||
|
||||
<Tip>
|
||||
|
||||
Join the `#pattern-design` channel on the Discord server and help us understand how we can design patterns that fit people with your body type.
|
||||
|
||||
</Tip>
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Community building
|
||||
---
|
||||
|
||||
The FreeSewing community resides [on Discord](https://discord.freesewing.org/).
|
||||
Just being there to answer questions and chat with other people is a valuable part of community building.
|
||||
|
||||
We also can be found in plenty of other places where we'd love to have you join us:
|
||||
|
||||
* [Instagram](https://instagram.com/freesewing_org)
|
||||
* [freesewing.social](https://freesewing.social/@freesewing) (our Mastodon instance)
|
||||
* [Facebook](https://www.facebook.com/groups/627769821272714/)
|
||||
* [Reddit](https://www.reddit.com/r/freesewing)
|
||||
|
||||
Apart from being present in chat rooms and social media, you could also take on some responsibility on one or more platforms.
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
title: Design sewing patterns
|
||||
---
|
||||
|
||||
Everybody wants us to add more patterns. But somebody has to design them.
|
||||
|
||||
That somebody could be you.
|
||||
We can help you with the development side of things.
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
title: Develop sewing patterns
|
||||
---
|
||||
|
||||
You could program new designs for FreeSewing.
|
||||
If you're not afraid of JavaScript and are happy to team up with a designer,
|
||||
you could work on a new pattern together.
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
title: Devops
|
||||
---
|
||||
|
||||
We have use a lot of automation from GitHub actions to automated deployment on Vercel.
|
||||
We also have some Ansible playbooks to run maintenance tasks.
|
||||
|
||||
There's also other technical tasks like database or server administration, certificate renewal, and so on.
|
||||
|
||||
If that's your kind of thing, we could use your help.
|
|
@ -1,51 +0,0 @@
|
|||
---
|
||||
title: Ways to contribute
|
||||
---
|
||||
|
||||
Thank you for being part of our community, and for wanting to contribute! ❤️
|
||||
FreeSewing is an open source project ran by volunteers from different corners of the world.
|
||||
We would love to have you on board, and this page lists everything you need to know to get started.
|
||||
|
||||
## Requirements
|
||||
|
||||
The only requirement we ask from our contributors is that they are the kind of people who
|
||||
value a safe and welcoming environment for all members of the FreeSewing community.
|
||||
|
||||
To that extend, we impose the following requirements to ensure everyone feels safe and welcome:
|
||||
|
||||
- Any member of our community must respect [our community standards](https://freesewing.org/docs/about/community-standards/)
|
||||
- As a contributor, you must uphold [our Code of Conduct](/guides/code-of-conduct/)
|
||||
|
||||
Go ahead and read those, we'll wait.
|
||||
|
||||
## Good to know
|
||||
|
||||
With that out of the way, here's a few more things that are _good to know_:
|
||||
|
||||
- Nobody gets paid to work on/for FreeSewing. We are a 100% volunteer organisation.
|
||||
- We have patrons who support us financially, but all the money that comes in goes to charity —
|
||||
See our [revenue pledge](https://freesewing.org/docs/about/pledge/) for details
|
||||
- FreeSewing follows the [all-contributors](https://allcontributors.org/) specification.
|
||||
Contributions of any kind are welcome.
|
||||
|
||||
## Where to begin
|
||||
|
||||
Below is a list of ideas or roles you could take up.
|
||||
If you're not sure what to do, or if you have questions, [please reach out to
|
||||
us](https://discord.freesewing.org/).
|
||||
|
||||
<ReadMore />
|
||||
|
||||
<Comment by="joost">
|
||||
|
||||
##### Who wants a job in the tech sector?
|
||||
|
||||
For many in our community, contributing to FreeSewing marked their
|
||||
first steps into the world of open source software development.
|
||||
|
||||
I (joost) am happy to provide guidance or mentorship to anyone who
|
||||
wants to learn, especially when doing so enables upwards social mobility.
|
||||
|
||||
[Reach out](https://discord.freesewing.org/) and we let's do this.
|
||||
|
||||
</Comment>
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
title: Make illustrations
|
||||
---
|
||||
|
||||
Our documentation can always use some more/better illustrations to help people figure out how
|
||||
to make our patterns into garments.
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
title: Language ambassador
|
||||
---
|
||||
|
||||
You could represent FreeSewing in a non-English community.
|
||||
There, you can help answer questions or triage problem reports.
|
||||
Or you can point out where translations are missing.
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
title: Pattern ambassador
|
||||
---
|
||||
|
||||
You could take charge of a specific FreeSewing design/pattern.
|
||||
|
||||
You’ll be the person to ask questions about how to make that pattern.
|
||||
You’ll make sure the documentation is not forgotten.
|
||||
And you can help with questions or triage problem reports to developers or designers.
|
|
@ -1,11 +0,0 @@
|
|||
---
|
||||
title: Pattern testing
|
||||
---
|
||||
|
||||
You could make (a muslin for) our patterns prior to release to make sure everything is ok.
|
||||
|
||||
<Tip>
|
||||
|
||||
Join the `#pattern-design` channel on the Discord server and let us know you would like to help. Here you will find people designing new patterns and reviewing existing patterns. Feedback is very welcome!
|
||||
|
||||
</Tip>
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
title: Project management
|
||||
---
|
||||
|
||||
There's a lot going on within the FreeSewing project and it's easy to forget about something.
|
||||
|
||||
A project manager would be helpful to prioritize tasks, makes sure all tasks have an issue,
|
||||
organize milestones, and so on.
|
||||
|
||||
This is helpful in more than one way:
|
||||
|
||||
- It reduces the cognitive load of the people implementing changes because they don't have to worry about forgetting things
|
||||
- It increases transparency by making it clear what sort of things are being worked on
|
||||
- It gives us that good feeling of closing the issue when the task is done
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
title: Proofreading
|
||||
---
|
||||
|
||||
You could check the original English text or translations for typos and/or grammar mistakes.
|
||||
You could propose improvements and watch over a consistent style and tone across FreeSewing’s documentation and written text.
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
title: Report bugs
|
||||
---
|
||||
|
||||
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/).
|
||||
Create an issue [in our monorepo](https://github.com/freesewing/freesewing/issues/new?assignees=\&labels=%F0%9F%90%9B+bug\&template=bug-report.md\&title=Bug+report) if you've found one.
|
||||
|
||||
Explain the problem and include additional details to help maintainers reproduce the problem:
|
||||
|
||||
- **Use a clear and descriptive title** for the issue to identify the problem.
|
||||
- **Describe the exact steps which reproduce the problem** in as many details as possible.
|
||||
- **Include relevant information** such as your username on the site, or the person you drafted a pattern for.
|
||||
|
||||
Provide more context by answering these questions:
|
||||
|
||||
- **Did the problem start happening recently** (e.g. it worked fine before but since the latest update it doesn't)
|
||||
- **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
|
|
@ -1,82 +0,0 @@
|
|||
---
|
||||
title: Showcase our patterns
|
||||
---
|
||||
|
||||
Anytime somebody has made one of our patterns, we like to Showcase it on [freesewing.org](https://freesewing.org/showcase/).
|
||||
|
||||
## How to get your pictures to us
|
||||
|
||||
If you've got pictures, there's a few ways you can get them on the site:
|
||||
|
||||
- [FreeSewing](#freesewing)
|
||||
- [Instagram](#instagram)
|
||||
- [Mastodon](#mastodon)
|
||||
- [Facebook](#facebook)
|
||||
- [Discord](#discord)
|
||||
- [Reddit](#reddit)
|
||||
- [GitHub](#github)
|
||||
- [Email](#email)
|
||||
|
||||
### FreeSewing
|
||||
|
||||
You can share something you (or someone else, with permission) made based on our designs at [FreeSewing.org/new/showcase](https://freesewing.org/new/showcase).
|
||||
|
||||
### Instagram
|
||||
|
||||
Post your pictures on Instagram, and tag or mention [@freesewing\_org](https://instagram.com/freesewing_org).
|
||||
|
||||
### Mastodon
|
||||
|
||||
Post your pictures — or a link to them — on freesewing.social (our Mastodon instance), and tag or mention [@freesewing](https://freesewing.social/@freesewing).
|
||||
|
||||
### Facebook
|
||||
|
||||
Post your pictures — or a link to them — on Facebook, and tag or mention the [@FreeSewing](https://www.facebook.com/groups/627769821272714/) group.
|
||||
|
||||
### Discord
|
||||
|
||||
Post your pictures — or a link to them — in the `#pattern-showcase` channel [on our Discord](https://discord.freesewing.org).
|
||||
|
||||
### Reddit
|
||||
|
||||
Post your pictures — or a link to them — in [r/freesewing](https://www.reddit.com/r/freesewing).
|
||||
|
||||
### GitHub
|
||||
|
||||
Create an issue [on GitHub](https://github.com/freesewing/freesewing/issues/new?assignees=&labels=:%2B1:+good+first+issue%2C+:camera_flash:+showcase%2C+:hugs:+community&template=04_showcase-template.yaml&title=%5Bshowcase%5D%3A+Found+a+great+project+to+showcase) and attach your pictures to it, or include a link to the pictures.
|
||||
|
||||
### Email
|
||||
|
||||
Email your pictures — or a link to them — to showcase@freesewing.org.
|
||||
|
||||
## Tips for great pictures
|
||||
|
||||
Below are just a few easy tips and tricks for your Showcase post.
|
||||
Of course, any Showcase is infinitely better than nothing, so go ahead and send us those low-light mirror selfies - we love them.
|
||||
|
||||
But if you want to take things to the next level, a few things to consider:
|
||||
|
||||
### Show it all
|
||||
|
||||
Show the whole garment. From multiple angles, if possible.
|
||||
It's awesome to see garments from the front, but back and side views can be really helpful, too.
|
||||
Bonus points for adding in a seated picture, which are especially great for sewists who use a wheelchair.
|
||||
|
||||
### Embrace the light
|
||||
|
||||
Take pictures in the best light you can — that might be next to a bright window,
|
||||
in a room where you've turned on all the extra lamps you could find,
|
||||
or that elusive "golden hour" outdoors.
|
||||
Bonus points if you can make it bright enough to not need a flash.
|
||||
|
||||
### Background
|
||||
|
||||
A neutral background can be helpful for seeing details.
|
||||
Try to avoid black on black or another setting that makes it hard to see what is what.
|
||||
|
||||
And remember that the outdoors is often the best background.
|
||||
|
||||
### Close-ups
|
||||
|
||||
If you nailed that welt pocket or hand-stitched all your buttonholes, go ahead and show them off.
|
||||
Close-up pictures make the showcase so much more relevant for people looking to make the same thing.
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
title: Writing for freesewing.dev
|
||||
---
|
||||
|
||||
You could write documentation for freesewing.dev, our developers website.
|
||||
|
||||
You would need good writing skills and a familiarity with code (JavaScript).
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Technical writing
|
||||
---
|
||||
|
||||
<ReadMore />
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
title: Writing for freesewing.org
|
||||
---
|
||||
|
||||
You could write documentation for freesewing.org, our makers website.
|
||||
|
||||
You would need good writing skills and a familiarity with sewing.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
title: Translation
|
||||
---
|
||||
|
||||
You could translate FreeSewing into one of its additional languages
|
||||
(French, German, Dutch, Spanish, Ukrainian). Or if you’re ambitious, add a new one.
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
title: Triage issues
|
||||
---
|
||||
|
||||
Triaging issues is a great way to get involved in FreeSewing. You can do tasks such as:
|
||||
|
||||
- Making sure issues are properly labeled
|
||||
- Ensuring they have a good title that explains the issue in brief
|
||||
- Assigning issues to people to make sure they are tended to
|
||||
- Keeping an eye on stale issues, and either updating or closing them
|
||||
- Assigning issues to milestones so we can plan our releases
|
||||
|
||||
All FreeSewing contributors have triage permissions that allows them to do this.
|
||||
If you don't have the rights, or bump into any issues, [reach out to us on Discord](https://discord.freesewing.org).
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: UI / UX Webdesign
|
||||
---
|
||||
|
||||
You could help us make our website and tools pretty and improve the user experience.
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
title: Translate
|
||||
---
|
||||
|
||||
FreeSewing is proudly multilingual. For that, we rely on the
|
||||
support of our translators.
|
||||
|
||||
FreeSewing currently is available in the following languages:
|
||||
|
||||
- English
|
||||
- Dutch
|
||||
- French
|
||||
- Spanish
|
||||
- German
|
||||
- Ukrainian
|
||||
|
||||
## Translation guide
|
||||
|
||||
This guide for translators covers everything you need to know about (helping out with) the translation of FreeSewing.
|
||||
|
||||
- <DocsLink slug="guides/translation" />
|
||||
|
35
markdown/dev/reference/api/point/dist/en.md
vendored
35
markdown/dev/reference/api/point/dist/en.md
vendored
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
title: Point.dist()
|
||||
---
|
||||
|
||||
The `Point.dist()` method returns the distance (in mm) between this point and
|
||||
the point you pass it.
|
||||
|
||||
## Signature
|
||||
|
||||
```js
|
||||
float point.dist(Point point)
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
<Example caption="An example of the Point.dist() method">
|
||||
```js
|
||||
({ Point, points, Path, paths, units, part }) => {
|
||||
|
||||
points.from = new Point(10, 10)
|
||||
points.to = new Point(80, 70)
|
||||
|
||||
points.text = points.from
|
||||
.shiftFractionTowards(points.to, 0.6)
|
||||
.setText(units(points.from.dist(points.to)), 'text-sm fill-note center')
|
||||
|
||||
paths.line = new Path()
|
||||
.move(points.from)
|
||||
.line(points.to)
|
||||
.setClass('dashed')
|
||||
|
||||
return part
|
||||
}
|
||||
```
|
||||
</Example>
|
|
@ -1,113 +0,0 @@
|
|||
---
|
||||
title: Confirm an account
|
||||
---
|
||||
|
||||
Confirms a newly created User account.
|
||||
If confirmation is successful this will also result in a (passwordless) sign-in.
|
||||
|
||||
## Endpoints
|
||||
|
||||
Confirming a new User account is possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/confirm/signup/:id` | None |
|
||||
|
||||
<Note compact>This endpoint requires no authentication</Note>
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the confirmation ID that was E-mailed to the E-mail
|
||||
address used for the signup. It replaces the `:id` placeholder in the
|
||||
[endpoint listed above](#endpoints).
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `consent` | Number | An integer representing the consent given by the user to process their data |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="404"/> | the confirmation was not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `token` | String | A JSON web token (JWT) token to authenticate with |
|
||||
| `account.id` | Number | The ID of the User |
|
||||
| `account.bio` | String | The bio of the User |
|
||||
| `account.consent` | Number | The consent given by the User |
|
||||
| `account.control` | Number | The control desired by the User |
|
||||
| `account.createdAt` | String | Date string indicating the moment the User was created |
|
||||
| `account.email` | String | The E-mail address currently tied to the User |
|
||||
| `account.github` | String | The GitHub username of the User |
|
||||
| `account.img` | String | The URL to the image stored with this User |
|
||||
| `account.imperial` | Boolean| Whether or not the User prefers imperial units |
|
||||
| `account.initial` | String | The E-mail address that the User was created with |
|
||||
| `account.language` | String | The language preferred by the user |
|
||||
| `account.lastSignIn`| String | Date string indicating them moment the User last signed in |
|
||||
| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled |
|
||||
| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter |
|
||||
| `account.patron` | Number | The level of patronage the user provides to FreeSewing |
|
||||
| `account.role` | String | The role of the User |
|
||||
| `account.status` | Number | The status of the user |
|
||||
| `account.updatedAt` | String | Date string indicating the last time the User was updated |
|
||||
| `account.username` | String | The username of the User |
|
||||
| `account.lusername` | String | A lowercased version of the username of the User |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const confirm = await axios.post(
|
||||
'https://backend.freesewing.org/confirm/signup/3985f312-e407-458a-a78c-4596c361d284',
|
||||
{ consent: 2 },
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5c...truncated",
|
||||
"account": {
|
||||
"id": 14,
|
||||
"bio": "",
|
||||
"consent": 1,
|
||||
"control": 1,
|
||||
"createdAt": "2022-11-19T18:15:22.642Z",
|
||||
"email": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"github": "",
|
||||
"img": "https://freesewing.org/avatar.svg",
|
||||
"imperial": false,
|
||||
"initial": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"language": "en",
|
||||
"lastSignIn": "2022-11-19T18:15:22.668Z",
|
||||
"mfaEnabled": false,
|
||||
"newsletter": false,
|
||||
"patron": 0,
|
||||
"role": "user",
|
||||
"status": 1,
|
||||
"updatedAt": "2022-11-19T18:15:22.668Z",
|
||||
"username": "user-14",
|
||||
"lusername": "user-14"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,66 +0,0 @@
|
|||
---
|
||||
title: Create an account
|
||||
---
|
||||
|
||||
Creates a new User account. The User account will remain inactive
|
||||
until [it is confirmed](/reference/backend/account/confirm).
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new User account is possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/signup` | None |
|
||||
|
||||
<Note compact>This endpoint requires no authentication</Note>
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `email` | `string` | The E-mail address of the User |
|
||||
| `language` | `boolean`| The language code for the User |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `email` | String | The E-mail address where the confirmation email was sent to |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const signup = await axios.post(
|
||||
'https://backend.freesewing.org/signup',
|
||||
{
|
||||
email: "joost@joost.at",
|
||||
language: "en"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"email": "joost@joost.at"
|
||||
}
|
||||
```
|
|
@ -1,94 +0,0 @@
|
|||
---
|
||||
title: Account
|
||||
---
|
||||
|
||||
From an end-user's point of view, their account holds all of their data. From
|
||||
an API point of view, these endpoints deal with data in the User table.
|
||||
|
||||
As the endpoints typically use `/account` we tend to use _account_ more often
|
||||
than _user_.
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
### The `consent` field is about data protection
|
||||
|
||||
The `consent` field holds a number indicating to which level the user has
|
||||
agreed to the processing of their data:
|
||||
|
||||
- `0` : No consent given (yet)
|
||||
- `1` : Consent given for processing profile data
|
||||
- `2` : Consent given for processing profile & people data
|
||||
- `3` : Consent given for processing profile & people data, and for publishing
|
||||
anonymized measurements as open data
|
||||
|
||||
Providing a consent value (that is higher than `0`) is a requirement for
|
||||
confirming a User account. In other words, without sufficient consent, you
|
||||
can't sign up.
|
||||
|
||||
### The `control` field is about keeping it simple
|
||||
|
||||
The `control` field holds a number indicating to which level the user wants to
|
||||
be in control of the FreeSewing platform. It was added as a way to allow for
|
||||
progressive disclosure of (more) advanced features and settings on the
|
||||
FreeSewing website.
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `1` : Hide all but the most crucial features. Make it as simple as possible.
|
||||
- `2` : Hide the majority of features. Make it simple, but not too much.
|
||||
- `3` : Reveal the majority of features, but not all. Balance simplicity with
|
||||
power.
|
||||
- `4` : Reveal everything, but keep handrails and safety checks. Only intervene
|
||||
when I'm about to do something dangerous.
|
||||
- `5` : Reveal everything, remove the handrails and safety checks. Get out of
|
||||
my way, I know what I'm doing.
|
||||
|
||||
### The `ihash` and `ehash` fields are for search
|
||||
|
||||
Because we encrypt a lot of data at rest, it can be difficult for support or
|
||||
administrators to find users when they don't know or remember their username
|
||||
because we cannot search on their E-mail address since that data is encrypted.
|
||||
|
||||
That is why we store a hash of the (lowercased) email address. This way, we can
|
||||
hash the email provided to us, and search the hash instead.
|
||||
|
||||
The `ehash` and `ihash` fields hold the hash for the `email` and `initial`
|
||||
fields.
|
||||
|
||||
### The `imperial` property is a Boolean
|
||||
|
||||
If the `imperial` property is `false`, the user wants metric units.
|
||||
|
||||
If the `imperial` property is `true`, the user wants imperial units.
|
||||
|
||||
### The `initial` field guards against account takeover
|
||||
|
||||
The `initial` field will be set to the E-mail address the account was
|
||||
registered with. It can never be changed.
|
||||
|
||||
This ensures that when there's an account takeover dispute, we can always know
|
||||
what E-mail address was used to create the account, even if the E-mail address
|
||||
associated with the account was changed.
|
||||
|
||||
### The `lusername` field should be unique
|
||||
|
||||
For the backend users `Joost` and `joost` are -- strictly speaking -- two
|
||||
different users. This tends to lead to confusion and possible impersonation.
|
||||
So we enforce uniqueness on the `lusername` field which holds a lowercased
|
||||
version of the `username` field..
|
||||
|
||||
In other words, lowercased username must be unique.
|
||||
|
||||
### The `status` field holds the account status
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `0` : The account is not active (yet)
|
||||
- `1` : The account is active
|
||||
- `-1` : The account was disabled by the user
|
||||
- `-2` : The account was administratively disabled
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
---
|
||||
title: MFA
|
||||
---
|
||||
|
||||
Enable of disable Multi-Factor Authentication (MFA) on the User account.
|
||||
|
||||
- [Setup MFA](#setup-mfa)
|
||||
- [Confirm MFA](#confirm-mfa)
|
||||
- [Disable MFA](#disable-mfa)
|
||||
|
||||
## Endpoints
|
||||
|
||||
Enabling, confirming, and disabling MFA is all possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/account/mfa/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/account/mfa/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Setup MFA
|
||||
|
||||
### Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `mfa` | `boolean`| Set to `true` to enable MFA |
|
||||
|
||||
### Response status codes
|
||||
|
||||
Possible status codes for this endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | access denied |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
### Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| -------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `mfa.secret` | String | The shared secret for generating one-time password (OTP) tokens |
|
||||
| `mfa.otpauth` | String | The OTP Auth URI that is encoded in the QR code |
|
||||
| `mfa.qrcode` | String | SVG to display a QR code with the otpauth URI encoded |
|
||||
|
||||
<Tip>
|
||||
##### Styling the SVG
|
||||
The SVG returned by the backend uses `currentColor` for the QR code, so you can
|
||||
style it with CSS if you embed it in the page.
|
||||
</Tip>
|
||||
|
||||
### Example request
|
||||
|
||||
```js
|
||||
const mfa = await axios.post(
|
||||
'https://backend.freesewing.org/account/mfa/jwt',
|
||||
{ mfa: true },
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"mfa": {
|
||||
"secret": "KBTSKUKRDJPEGCZK",
|
||||
"otpauth": "otpauth://totp/FreeSewing:user-294?secret=KBTSKUKRDJPEGCZK&period=30&digits=6&algorithm=SHA1&issuer=FreeSewing",
|
||||
"qrcode": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 53 53\" shape-rendering=\"crispEdges\"><path fill=\"none\" d=\"M0 0h53v53H0z\"/><path stroke=\"currentColor\" d=\"M4 4.5h7m1 0h1m3 0h1m1 0h3m2 0h1m1 0h1m1 0h1m1 0h2m1 0h5m3 0h1m1 0h7M4 5.5h1m5 0h1m1 0h4m1 0h2m4 0h1m2 0h3m3 0h1m2 0h2m2 0h1m2 0h1m5 0h1M4 6.5h1m1 0h3m1 0h1m1 0h2m1 0h3m4 0h2m1 0h2m3 0h4m2 0h1m2 0h1m2 0h1m1 0h3m1 0h1M4 7.5h1m1 0h3m1 0h1m7 0h1m6 0h3m3 0h1m1 0h1m5 0h2m1 0h1m1 0h3m1 0h1M4 8.5h1m1 0h3m1 0h1m1 0h1m1 0h3m1 0h3m1 0h8m3 0h1m2 0h1m1 0h3m1 0h1m1 0h3m1 0h1M4 9.5h1m5 0h1m7 0h1m1 0h3m1 0h1m3 0h1m2 0h3m1 0h1m1 0h1m4 0h1m5 0h1M4 10.5h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7M14 11.5h2m3 0h4m1 0h1m3 0h4m2 0h1m1 0h3m1 0h1M4 12.5h1m2 0h6m1 0h2m6 0h1m1 0h5m1 0h1m1 0h2m1 0h1m3 0h1m1 0h1m2 0h1m1 0h3M5 13.5h3m3 0h2m1 0h2m5 0h2m1 0h2m2 0h5m1 0h2m2 0h1m2 0h4m1 0h2M5 14.5h1m1 0h2m1 0h1m5 0h1m2 0h1m2 0h1m1 0h3m10 0h2m2 0h1m3 0h1m1 0h2M5 15.5h2m2 0h1m2 0h4m1 0h1m4 0h3m2 0h1m2 0h3m1 0h1m2 0h4m2 0h6M5 16.5h1m4 0h1m2 0h4m1 0h3m1 0h2m1 0h1m3 0h4m2 0h1m2 0h2m3 0h2M5 17.5h3m1 0h1m1 0h1m3 0h2m2 0h3m5 0h2m2 0h1m2 0h1m2 0h1m1 0h2m1 0h2m2 0h1M4 18.5h2m1 0h2m1 0h2m4 0h5m5 0h1m2 0h5m1 0h1m5 0h3m3 0h2M4 19.5h1m1 0h2m3 0h2m2 0h1m1 0h1m1 0h1m1 0h2m3 0h1m2 0h3m1 0h1m1 0h1m1 0h2m1 0h1m1 0h3m1 0h3M6 20.5h1m1 0h3m1 0h1m2 0h1m1 0h1m1 0h4m1 0h1m3 0h1m1 0h3m2 0h3m1 0h1m1 0h1m1 0h1m2 0h1M4 21.5h1m1 0h2m1 0h1m3 0h5m2 0h1m4 0h2m1 0h1m1 0h2m2 0h1m4 0h2m3 0h2m1 0h2M4 22.5h5m1 0h2m3 0h1m1 0h1m3 0h2m9 0h3m1 0h1m2 0h1m3 0h1m2 0h2M4 23.5h1m1 0h1m1 0h1m3 0h1m2 0h1m2 0h1m1 0h2m1 0h2m2 0h4m1 0h3m8 0h2M4 24.5h1m1 0h9m2 0h1m1 0h2m1 0h7m2 0h1m3 0h3m1 0h7M6 25.5h1m1 0h1m3 0h1m1 0h4m1 0h3m2 0h1m3 0h1m1 0h2m3 0h1m3 0h2m3 0h4M4 26.5h1m1 0h1m1 0h1m1 0h1m1 0h2m2 0h1m1 0h1m1 0h1m3 0h1m1 0h1m1 0h3m1 0h2m3 0h4m1 0h1m1 0h3m1 0h1M4 27.5h1m1 0h1m1 0h1m3 0h1m5 0h1m2 0h1m1 0h2m3 0h2m3 0h3m1 0h1m1 0h2m3 0h1m1 0h2M5 28.5h1m2 0h8m2 0h2m4 0h5m1 0h1m1 0h4m4 0h5M8 29.5h1m2 0h2m3 0h1m2 0h1m2 0h1m2 0h2m1 0h1m1 0h2m3 0h1m1 0h1m2 0h2m1 0h1m3 0h1M4 30.5h3m1 0h1m1 0h1m1 0h1m1 0h1m3 0h1m2 0h1m1 0h3m4 0h1m1 0h2m2 0h1m2 0h1m1 0h2m2 0h2M4 31.5h1m1 0h1m2 0h1m2 0h1m1 0h1m2 0h3m1 0h1m5 0h4m1 0h1m1 0h1m1 0h5m2 0h1m2 0h1M6 32.5h1m2 0h3m2 0h1m1 0h2m1 0h1m1 0h2m2 0h1m2 0h1m3 0h1m4 0h1m2 0h3m1 0h1M4 33.5h1m1 0h2m1 0h1m2 0h1m2 0h1m1 0h1m1 0h3m3 0h3m2 0h1m2 0h1m4 0h2m3 0h2m2 0h2M7 34.5h1m2 0h5m1 0h5m1 0h2m1 0h1m2 0h1m4 0h4m2 0h1m2 0h1m1 0h2m1 0h1M4 35.5h2m2 0h1m2 0h1m1 0h1m1 0h1m2 0h8m2 0h2m1 0h4m3 0h2m1 0h1m5 0h2M9 36.5h5m1 0h5m3 0h1m1 0h1m1 0h5m5 0h1m7 0h2M5 37.5h2m2 0h1m2 0h3m6 0h1m1 0h2m3 0h1m1 0h2m1 0h3m2 0h5m4 0h1M8 38.5h1m1 0h1m1 0h3m2 0h1m3 0h2m1 0h1m1 0h1m2 0h1m1 0h1m3 0h1m2 0h2m1 0h5M5 39.5h4m5 0h1m2 0h4m3 0h1m2 0h4m1 0h1m2 0h2m3 0h1m1 0h1m1 0h2M4 40.5h1m2 0h2m1 0h1m1 0h2m4 0h12m3 0h1m1 0h1m2 0h7m3 0h1M12 41.5h1m1 0h3m1 0h3m3 0h1m3 0h1m2 0h1m3 0h1m2 0h1m1 0h1m3 0h1m1 0h2M4 42.5h7m1 0h1m2 0h4m1 0h3m1 0h1m1 0h1m1 0h2m1 0h1m2 0h2m4 0h1m1 0h1m1 0h1m1 0h2M4 43.5h1m5 0h1m1 0h1m1 0h1m1 0h2m1 0h3m2 0h1m3 0h3m2 0h6m1 0h1m3 0h3M4 44.5h1m1 0h3m1 0h1m1 0h1m2 0h2m1 0h2m1 0h1m2 0h6m3 0h1m3 0h1m2 0h6m2 0h1M4 45.5h1m1 0h3m1 0h1m1 0h5m3 0h2m1 0h3m1 0h3m3 0h3m1 0h2m4 0h2m1 0h1m1 0h1M4 46.5h1m1 0h3m1 0h1m3 0h5m3 0h5m1 0h2m1 0h2m2 0h1m1 0h1m1 0h3m1 0h1m1 0h4M4 47.5h1m5 0h1m2 0h1m2 0h1m1 0h1m2 0h1m4 0h2m2 0h1m3 0h2m1 0h3m1 0h3m2 0h3M4 48.5h7m1 0h5m2 0h3m3 0h1m2 0h1m1 0h3m1 0h2m2 0h1m1 0h1m1 0h2m1 0h1\"/></svg>\n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Confirm MFA
|
||||
|
||||
To confirm the MFA, we need to provide an MFA token to ensure the user can
|
||||
generate them.
|
||||
|
||||
### Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `mfa` | `boolean`| Must be set to `true` to confirm MFA |
|
||||
| `secret` | `boolean`| The secret returned when setting up MFA |
|
||||
| `token` | `boolean`| Must be set to `true` to confirm MFA |
|
||||
|
||||
### Response status codes
|
||||
|
||||
Possible status codes for this endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | access denied |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
### Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| -------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
|
||||
### Example request
|
||||
|
||||
```js
|
||||
import { authenticator } from '@otplib/preset-default'
|
||||
|
||||
const confirm = await axios.post(
|
||||
'https://backend.freesewing.org/account/mfa/jwt',
|
||||
{
|
||||
mfa: true,
|
||||
secret: mfa.secret,
|
||||
token: authenticator.generate(mfa.secret)
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Example response
|
||||
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
}
|
||||
```
|
||||
## Disable MFA
|
||||
|
||||
To disable MFA, you need to provide both the account password and a valid token.
|
||||
|
||||
### Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `mfa` | `boolean`| Must be set to `false` to disable MFA |
|
||||
| `password` | `boolean`| The User's password |
|
||||
| `token` | `boolean`| Must be set to `true` to confirm MFA |
|
||||
|
||||
### Response status codes
|
||||
|
||||
Possible status codes for this endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | access denied |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
### Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| -------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
|
||||
### Example request
|
||||
|
||||
```js
|
||||
import { authenticator } from '@otplib/preset-default'
|
||||
|
||||
const confirm = await axios.post(
|
||||
'https://backend.freesewing.org/account/mfa/jwt',
|
||||
{
|
||||
mfa: false,
|
||||
password: "I like big bewbs and I just can't lie",
|
||||
token: authenticator.generate(mfa.secret)
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Example response
|
||||
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
}
|
||||
```
|
|
@ -1,113 +0,0 @@
|
|||
---
|
||||
title: Sign In
|
||||
---
|
||||
|
||||
Sign in as a User with username and password, and optional MFA token.
|
||||
|
||||
## Endpoints
|
||||
|
||||
Password-based sign-in is possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/signin` | None |
|
||||
|
||||
<Note compact>This endpoint requires no authentication</Note>
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `username` | `string` | The E-mail address of the User |
|
||||
| `password` | `boolean`| The language code for the User |
|
||||
| `token` | `boolean`| The MFA token |
|
||||
|
||||
<Note compact>An MFA token is required (only) when the User enabled MFA</Note>
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | MFA token missing |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `token` | String | A JSON web token (JWT) token to authenticate with |
|
||||
| `account.id` | Number | The ID of the User |
|
||||
| `account.bio` | String | The bio of the User |
|
||||
| `account.consent` | Number | The consent given by the User |
|
||||
| `account.control` | Number | The control desired by the User |
|
||||
| `account.createdAt` | String | Date string indicating the moment the User was created |
|
||||
| `account.email` | String | The E-mail address currently tied to the User |
|
||||
| `account.github` | String | The GitHub username of the User |
|
||||
| `account.img` | String | The URL to the image stored with this User |
|
||||
| `account.imperial` | Boolean| Whether or not the User prefers imperial units |
|
||||
| `account.initial` | String | The E-mail address that the User was created with |
|
||||
| `account.language` | String | The language preferred by the user |
|
||||
| `account.lastSignIn`| String | Date string indicating them moment the User last signed in |
|
||||
| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled |
|
||||
| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter |
|
||||
| `account.patron` | Number | The level of patronage the user provides to FreeSewing |
|
||||
| `account.role` | String | The role of the User |
|
||||
| `account.status` | Number | The status of the user |
|
||||
| `account.updatedAt` | String | Date string indicating the last time the User was updated |
|
||||
| `account.username` | String | The username of the User |
|
||||
| `account.lusername` | String | A lowercased version of the username of the User |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const signup = await axios.post(
|
||||
'https://backend.freesewing.org/signup',
|
||||
{
|
||||
username: "jimmy",
|
||||
language: "I like big bewbs and I just can't lie",
|
||||
token: 231586
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5c...truncated",
|
||||
"account": {
|
||||
"id": 14,
|
||||
"bio": "",
|
||||
"consent": 1,
|
||||
"control": 1,
|
||||
"createdAt": "2022-11-19T18:15:22.642Z",
|
||||
"email": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"github": "",
|
||||
"img": "https://freesewing.org/avatar.svg",
|
||||
"imperial": false,
|
||||
"initial": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"language": "en",
|
||||
"lastSignIn": "2022-11-19T18:15:22.668Z",
|
||||
"mfaEnabled": false,
|
||||
"newsletter": false,
|
||||
"patron": 0,
|
||||
"role": "user",
|
||||
"status": 1,
|
||||
"updatedAt": "2022-11-19T18:15:22.668Z",
|
||||
"username": "jimmy",
|
||||
"lusername": "jimmy"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,126 +0,0 @@
|
|||
---
|
||||
title: Update account
|
||||
---
|
||||
|
||||
Updates an existing User account.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to update your own User account
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** account
|
||||
|
||||
## Endpoints
|
||||
|
||||
Updating an existing User account is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method put /> | `/account/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method put /> | `/account/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `bio` | `string` | The User's bio |
|
||||
| `consent` | `string` | A number that indicates [the consent given by the user](/reference/backend/account#the-consent-field-is-about-data-protection) |
|
||||
| `control` | `string` | A number that indicates [the level of control the user prefers](/reference/backend/account#the-control-field-is-about-keeping-it-simple) |
|
||||
| `github` | `string` | The User's username on GitHub |
|
||||
| `imperial` | `boolean`| Whether or not the User prefers imperial units |
|
||||
| `newsletter`| `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) |
|
||||
| `img` | `string` | An image [data-uri][duri] to store with this Person |
|
||||
| `password` | `string` | The (new) password for the User |
|
||||
| `username` | `string` | The (new) username for the User |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `account.id` | Number | The ID of the User |
|
||||
| `account.bio` | String | The bio of the User |
|
||||
| `account.consent` | Number | The consent given by the User |
|
||||
| `account.control` | Number | The control desired by the User |
|
||||
| `account.createdAt` | String | Date string indicating the moment the User was created |
|
||||
| `account.email` | String | The E-mail address currently tied to the User |
|
||||
| `account.github` | String | The GitHub username of the User |
|
||||
| `account.img` | String | The URL to the image stored with this User |
|
||||
| `account.imperial` | Boolean| Whether or not the User prefers imperial units |
|
||||
| `account.initial` | String | The E-mail address that the User was created with |
|
||||
| `account.language` | String | The language preferred by the user |
|
||||
| `account.lastSignIn`| String | Date string indicating them moment the User last signed in |
|
||||
| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled |
|
||||
| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter |
|
||||
| `account.patron` | Number | The level of patronage the user provides to FreeSewing |
|
||||
| `account.role` | String | The role of the User |
|
||||
| `account.status` | Number | The status of the user |
|
||||
| `account.updatedAt` | String | Date string indicating the last time the User was updated |
|
||||
| `account.username` | String | The username of the User |
|
||||
| `account.lusername` | String | A lowercased version of the username of the User |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const udpate = await axios.put(
|
||||
'https://backend.freesewing.org/account/jwt',
|
||||
{
|
||||
bio: "I like imperial now",
|
||||
imperial: true,
|
||||
username: "ImperialLover"
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"account": {
|
||||
"id": 14,
|
||||
"bio": "I like imperial now",
|
||||
"consent": 1,
|
||||
"control": 1,
|
||||
"createdAt": "2022-11-19T18:15:22.642Z",
|
||||
"email": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"github": "",
|
||||
"img": "https://freesewing.org/avatar.svg",
|
||||
"imperial": true,
|
||||
"initial": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"language": "en",
|
||||
"lastSignIn": "2022-11-19T18:15:22.668Z",
|
||||
"mfaEnabled": false,
|
||||
"newsletter": false,
|
||||
"patron": 0,
|
||||
"role": "user",
|
||||
"status": 1,
|
||||
"updatedAt": "2022-11-19T18:15:22.668Z",
|
||||
"username": "ImperialLover",
|
||||
"lusername": "imperiallover"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,97 +0,0 @@
|
|||
---
|
||||
title: Create an API key
|
||||
---
|
||||
|
||||
Creates a new API key. An API key can be used to authenticate against the
|
||||
backend API.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to create an API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new API key is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/apikeys/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/apikeys/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `name` | `string` | A name for the API key |
|
||||
| `level` | `number` | A privilege level from 0 to 8. |
|
||||
| `expiresIn` | `number` | The number of seconds until the API key expires |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
<Warning>
|
||||
##### Make sure to save the secret
|
||||
The response body is the only time the API key's secret will be revealed.
|
||||
</Warning>
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | Either `success` or `error` |
|
||||
| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.secret` | `string` | The API secret |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const apiKey = axios.post(
|
||||
'https://backend.freesewing.org/apikeys/jwt',
|
||||
{
|
||||
name: 'My first API key',
|
||||
level: 2, // Read only
|
||||
expiresIn: 3600, // One hour
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"apikey": {
|
||||
"key": "7ea12968-7758-40b6-8c73-75cc99be762b",
|
||||
"secret": "503d7adbdb3ec18ab27adfcd895d8b47a8d6bc8307d548500fbf9c05a5a8820e",
|
||||
"level": 3,
|
||||
"expiresAt": "2022-11-06T15:57:30.190Z",
|
||||
"name": "My first API key",
|
||||
"userId": 61
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: Delete an API key
|
||||
---
|
||||
|
||||
Deletes an existing API key.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to delete an API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
Deleting an API key is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method delete /> | `/apikeys/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method delete /> | `/apikeys/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the API key you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="204"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
await axios.delete(
|
||||
'https://backend.freesewing.org/apikeys/7ea12968-7758-40b6-8c73-75cc99be762b/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
|
||||
```204.json
|
||||
```
|
||||
<Note>
|
||||
These endpoints return status code <StatusCode status="204"/> (no content) on
|
||||
success, with no response body.
|
||||
</Note>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
title: API Keys
|
||||
---
|
||||
|
||||
API keys are a way to authenticate to the API with basic authentication.
|
||||
They are intended to be used when interacting with the API in an automated
|
||||
way such as from a script or a CI/CD pipeline.
|
||||
|
||||
They are an alternative to JSON Web Tokens (JWT) which is typically used
|
||||
to authenticate users in a browser session.
|
||||
|
||||
The FreeSewing backend REST API supports authentication both with JSON Web
|
||||
Tokens (JWT) as with API keys (KEY). This describes the endpoints that deal
|
||||
with creating, reading, and removing API keys. For authentication details,
|
||||
refer to [the section on
|
||||
authenticating](/reference/backend/authentication).
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
The following is good to keep in mind when working with API keys:
|
||||
|
||||
### API keys are immutable
|
||||
|
||||
Once created, API keys cannot be updated.
|
||||
You should remove them and re-create a new one if you want to make a change.
|
||||
|
||||
### API keys have an expiry
|
||||
|
||||
API keys have an expiry date. The maximum validity for an API key is 1 year.
|
||||
|
||||
### API keys have a permission level
|
||||
|
||||
API keys have a permission level. You can never create an API key with a higher
|
||||
permission level than your own permission level.
|
||||
|
||||
### Circumstances that will trigger your API keys to be revoked
|
||||
|
||||
As a precaution, all your API keys will be revoked when:
|
||||
|
||||
- Your role is downgraded to a role with fewer privileges
|
||||
- Your account is (b)locked
|
||||
- You revoke your consent for FreeSewing to process your data
|
||||
|
||||
<Note>
|
||||
This is not an exhaustive list. For example, if we find your use of our API to
|
||||
be excessive, we might also revoke your API keys to shield us from the
|
||||
financial impact of your use of our API.
|
||||
</Note>
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
---
|
||||
title: Read an API key
|
||||
---
|
||||
|
||||
Reads an existing API key. Note that the API secret can only be retrieved at
|
||||
the moment the API key is created.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to read an API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
Reading an API key is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/apikeys/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method get /> | `/apikeys/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the API key you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="404"/> | API key not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const keyInfo = await axios.get(
|
||||
'https://backend.freesewing.org/apikeys/7ea12968-7758-40b6-8c73-75cc99be762b/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"apikey": {
|
||||
"key": "7ea12968-7758-40b6-8c73-75cc99be762b",
|
||||
"level": 3,
|
||||
"expiresAt": "2022-11-06T15:57:30.190Z",
|
||||
"name": "My first API key",
|
||||
"userId": 61
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: Read the current API key
|
||||
---
|
||||
|
||||
Reads the current API key used to authenticate the request.
|
||||
For obvious reasons, this endpoint is only available with API key authentication.
|
||||
However, there's an equivalent endpoint for JWT authentication.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `0` or higher is required to read the current API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/whoami/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const keyInfo = await axios.get(
|
||||
'https://backend.freesewing.org/whoami/key',
|
||||
{
|
||||
auth: {
|
||||
username: apikey.key,
|
||||
password: apikey.secret,
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"apikey": {
|
||||
"key": "7ea12968-7758-40b6-8c73-75cc99be762b",
|
||||
"level": 3,
|
||||
"expiresAt": "2022-11-06T15:57:30.190Z",
|
||||
"name": "My first API key",
|
||||
"userId": 61
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
---
|
||||
title: Authentication
|
||||
---
|
||||
|
||||
The FreeSewing backend API requires authentication for all but a handful of
|
||||
endpoints.
|
||||
|
||||
The API supports two different types of authentication:
|
||||
|
||||
| Type | Name | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| [JSON Web Tokens](#jwt-authentication) | `jwt` | This is typically used to authenticate humans in a browser session. |
|
||||
| [API Keys](#key-authentication) | `key` | This is typically used to interact with the API in an automated way. Like in a script, a CI/CD context, a serverless runner, and so on. |
|
||||
|
||||
While the API supports both, they are not supported on the same endpoint.
|
||||
Instead, add the authentication type you want to use as the final part of
|
||||
endpoint:
|
||||
|
||||
- `/some/endpoint/jwt` : Authenticate with a JSON Web Token
|
||||
- `/some/endpoint/key` : Authenticate with an API key and secret
|
||||
|
||||
## `jwt` authentication
|
||||
|
||||
The use of JSON Web Tokens ([jwt](https://jwt.io)) is typically used in a
|
||||
browser context where we want to establish a *session*.
|
||||
|
||||
To get a token, you must first authenticate at the [`/signin`](/reference/backend/account/signin) endpoint.
|
||||
You will receive a JSON Web Token (jwt) as part of the response.
|
||||
|
||||
In subsequent API calls, you must then include this token in the
|
||||
`Authorization` header prefixed by `Bearer `. Like his:
|
||||
|
||||
```js
|
||||
const account = await axios.get(
|
||||
`https://backend.freesewing.org/account/jwt`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## `key` authentication
|
||||
|
||||
The combination of API key & secret serves as a username & password for [HTTP
|
||||
basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
|
||||
|
||||
<Note>
|
||||
In basic authentication, the password is sent
|
||||
unencrypted. To guard against this, this API should only be served over a
|
||||
connection that is encrypted with TLS. (a URL starting with `https://`).
|
||||
</Note>
|
||||
|
||||
Sending a username and password with a request like this is supported
|
||||
pretty much everywhere. In addition, there is no need to establish a session
|
||||
first, so this make the entire transaction stateless.
|
||||
|
||||
Below is an example using curl:
|
||||
|
||||
```sh
|
||||
curl -u api-key-here:api-secret-here \
|
||||
https://backend.freesewing.org/account/key
|
||||
```
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
title: Clone a Pattern
|
||||
---
|
||||
|
||||
Create a new Pattern by cloning an existing one.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to clone a
|
||||
Pattern depends on:
|
||||
|
||||
- Whether the Pattern is `public`
|
||||
- Who created the Pattern
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public Patterns | Non-Public Patterns |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `3` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/patterns/:id/clone/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/patterns/:id/clone/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const clone = axios.post(
|
||||
'https://backend.freesewing.org/patterns/10/clone/jwt',
|
||||
null,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 19,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": true,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:29:33.346Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,121 +0,0 @@
|
|||
---
|
||||
title: Create a Pattern
|
||||
---
|
||||
|
||||
Creates a new Pattern. This is typically used when users choose to save a pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to create a Pattern
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/patterns/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/patterns/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
The request body is a JSON object with the following properties:
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `data` | `object` | Any additional data to store with the pattern |
|
||||
| `design` | `string` | The name of the design this Pattern is an instance of |
|
||||
| `img` | `object` | An image [data-uri][duri] to store with this Pattern |
|
||||
| `name` | `string` | A name for the Pattern |
|
||||
| `notes` | `string` | User notes for the pattern |
|
||||
| `person` | `object` | The ID of the person to associate with this pattern |
|
||||
| `settings` | `object` | The settings object to (re-)create the Pattern |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const pattern = await axios.post(
|
||||
'https://backend.freesewing.org/patterns/jwt',
|
||||
{
|
||||
data: {
|
||||
some: 'value',
|
||||
}
|
||||
design: "aaron",
|
||||
img: "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...truncated",
|
||||
name: "Just a test",
|
||||
notes: "These are my notes",
|
||||
person: 17,
|
||||
public: true,
|
||||
settings: {
|
||||
sa: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 10,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": true,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:29:35.023Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: Delete a Pattern
|
||||
---
|
||||
|
||||
Deletes an existing Pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to delete a Pattern
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to delete **another user's** Pattern
|
||||
|
||||
## Endpoints
|
||||
|
||||
Deleting a Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method delete /> | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method delete /> | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="204"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
await axios.delete(
|
||||
'https://backend.freesewing.org/patterns/10/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
|
||||
```204.json
|
||||
```
|
||||
<Note>
|
||||
These endpoints return status code <StatusCode status="204"/> (no content) on
|
||||
success, with no response body.
|
||||
</Note>
|
|
@ -1,33 +0,0 @@
|
|||
---
|
||||
title: Patterns
|
||||
---
|
||||
|
||||
Patterns hold information on and settings for a user's patterns.
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
### The `design` property should hold the design
|
||||
|
||||
The `design` property should hold the name of the FreeSewing design.
|
||||
For example, `aaron`.
|
||||
|
||||
### The `notes` vs `data` properties
|
||||
|
||||
Both the `data` and `notes` properties can hold additional information about
|
||||
the pattern.
|
||||
|
||||
Keep in mind that:
|
||||
- The `notes` property is intended to be used by the user to add notes about
|
||||
their pattern. It will only accept data of type `string`.
|
||||
- The `data` property is intended to allow frontend developers to store
|
||||
additional data about the pattern. It will only accept data of type `object`.
|
||||
|
||||
### The `settings` property should hold the pattern settings
|
||||
|
||||
The `settings` property should hold [a settings object](/reference/settings)
|
||||
that can be passed to [the Pattern
|
||||
constructor](/reference/api/pattern#creating-a-pattern).
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
title: Read a Pattern
|
||||
---
|
||||
|
||||
Reads an existing Pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to read a
|
||||
Pattern depends on:
|
||||
|
||||
- Whether the Pattern is `public`
|
||||
- Who created the Pattern
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public Patterns | Non-Public Patterns |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `1` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Reading a Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method get /> | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to read.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="404"/> | API key not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const pattern = await axios.get(
|
||||
'https://backend.freesewing.org/patterns/10/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 10,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": true,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:29:35.023Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,118 +0,0 @@
|
|||
---
|
||||
title: Update a Pattern
|
||||
---
|
||||
|
||||
Updates an existing Pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to update a Pattern
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** Pattern
|
||||
|
||||
## Endpoints
|
||||
|
||||
Updating an existing Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method put /> | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method put /> | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `data` | `object` | Any additional data to store with the pattern |
|
||||
| `design` | `string` | The name of the design this Pattern is an instance of |
|
||||
| `img` | `object` | An image [data-uri][duri] to store with this Pattern |
|
||||
| `name` | `string` | A name for the Pattern |
|
||||
| `notes` | `string` | User notes for the pattern |
|
||||
| `person` | `object` | The ID of the person to associate with this pattern |
|
||||
| `settings` | `object` | The settings object to (re-)create the Pattern |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const udpate = await axios.put(
|
||||
'https://backend.freesewing.org/patterns/10/jwt',
|
||||
{
|
||||
data: {
|
||||
some: 'new value',
|
||||
}
|
||||
public: false,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 10,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "new value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": false,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:43:39.223Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
title: Clone a Person
|
||||
---
|
||||
|
||||
Create a new Person by cloning an existing one.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to clone a
|
||||
Person depends on:
|
||||
|
||||
- Whether the Person is `public`
|
||||
- Who created the Pattern
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public Patterns | Non-Public Patterns |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `3` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/people/:id/clone/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/people/:id/clone/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Person you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const clone = axios.post(
|
||||
'https://backend.freesewing.org/people/27/clone/jwt',
|
||||
null,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 32,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": false,
|
||||
"name": "Someone",
|
||||
"notes": "These are some notes",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,110 +0,0 @@
|
|||
---
|
||||
title: Create a Person
|
||||
---
|
||||
|
||||
Creates a new Person.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to create a Person
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/people/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/people/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `img` | `string` | An image [data-uri][duri] to store with this Person |
|
||||
| `imperial` | `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) |
|
||||
| `name` | `string` | A name for the Person |
|
||||
| `notes` | `string` | User notes for the person |
|
||||
| `measies` | `object` | The measurements for this person |
|
||||
| `public` | `string` | The name of the design this Pattern is an instance of |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const person = await axios.post(
|
||||
'https://backend.freesewing.org/people/jwt',
|
||||
{
|
||||
name: "Someone",
|
||||
notes: "These are some notes",
|
||||
measies: {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
public: true,
|
||||
imperial: false,
|
||||
img: "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...truncated"
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 27,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": false,
|
||||
"name": "Someone",
|
||||
"notes": "These are some notes",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: Delete a Person
|
||||
---
|
||||
|
||||
Deletes an existing Person.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to delete a Person
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to delete **another user's** Person
|
||||
|
||||
## Endpoints
|
||||
|
||||
Deleting a Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method delete /> | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method delete /> | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Person you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="204"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
await axios.delete(
|
||||
'https://backend.freesewing.org/people/27/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
|
||||
```204.json
|
||||
```
|
||||
<Note>
|
||||
These endpoints return status code <StatusCode status="204"/> (no content) on
|
||||
success, with no response body.
|
||||
</Note>
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
title: People
|
||||
---
|
||||
|
||||
A Person hold information and measurements on the people we generate patterns
|
||||
for.
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
### The `imperial` property is a Boolean
|
||||
|
||||
- If the `imperial` property is `false`, the person wants metric units.
|
||||
- If the `imperial` property is `true`, the person wants imperial units.
|
||||
|
||||
### The `measies` property holds measurements
|
||||
|
||||
These measurements should be structured as an object that can be used for the
|
||||
`measurements` key in the [pattern settings
|
||||
object](/reference/settings/measurements).
|
||||
|
||||
The backend will only accept known measurements listed in the configuration file.
|
||||
|
||||
<Comment by="joost">
|
||||
##### Why we use measies instead of measurements
|
||||
First of all, _measies_ is a cute and adorable alternative for _measurements_
|
||||
coined by Karen. She deserves all the credit.
|
||||
|
||||
But also, I am slightly dyslexic and for some reason, I often drop the middle
|
||||
_e_ when typing measurements' (sic).
|
||||
|
||||
Those typos lead to bugs and I find it much easier to write _measies_.
|
||||
So because fewer bugs, plus did I mention it's cute?
|
||||
|
||||
</Comment>
|
||||
|
||||
### The `settings` property should hold the pattern settings
|
||||
|
||||
The `settings` property should hold [a settings object](/reference/settings)
|
||||
that can be passed to [the Pattern
|
||||
constructor](/reference/api/pattern#creating-a-pattern).
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
title: Read a Person
|
||||
---
|
||||
|
||||
Reads an existing Person.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to read a
|
||||
Person depends on:
|
||||
|
||||
- Whether the Person is `public`
|
||||
- Who created the Person
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public People | Non-Public People |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `4` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Reading a Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method get /> | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request url
|
||||
|
||||
The url should contain the ID of the Person you wish to read.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="404"/> | API key not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const person = await axios.get(
|
||||
'https://backend.freesewing.org/people/27/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 27,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": false,
|
||||
"name": "Someone",
|
||||
"notes": "These are some notes",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
title: Update a Person
|
||||
---
|
||||
|
||||
Updates an existing Person.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to update a Person
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** Person
|
||||
|
||||
## Endpoints
|
||||
|
||||
Updating an existing Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method put /> | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method put /> | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Person you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `img` | `string` | An image [data-uri][duri] to store with this Person |
|
||||
| `imperial` | `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) |
|
||||
| `name` | `string` | A name for the Person |
|
||||
| `notes` | `string` | User notes for the person |
|
||||
| `measies` | `object` | The measurements for this person |
|
||||
| `public` | `string` | The name of the design this Pattern is an instance of |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const udpate = await axios.put(
|
||||
'https://backend.freesewing.org/people/27/jwt',
|
||||
{
|
||||
notes: "Turns out some people like imperial",
|
||||
imperial: true,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 27,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": true,
|
||||
"name": "Someone",
|
||||
"notes": "Turns out some people like imperial",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue