Skip to content

Commit

Permalink
Merge pull request #721 from contember/docs/replace-schema-def-imports
Browse files Browse the repository at this point in the history
docs: replace schema-definition imports to `c`
  • Loading branch information
matej21 authored Jun 11, 2024
2 parents a97dd62 + 1ffa51a commit 790bc91
Show file tree
Hide file tree
Showing 26 changed files with 242 additions and 246 deletions.
9 changes: 9 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,12 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# yarn
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
Binary file added docs/.yarn/install-state.gz
Binary file not shown.
1 change: 1 addition & 0 deletions docs/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
yarnPath: ../.yarn/releases/yarn-3.5.0.cjs
44 changes: 22 additions & 22 deletions docs/docs/guides/acl-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ export class Category {
}

export class Article {
category = def.manyHasOne(Category)
category = c.manyHasOne(Category)
// ....
}

export class Comment {
article = def.manyHasOne(Article)
content = def.stringColumn()
hiddenAt = def.dateTimeColumn()
article = c.manyHasOne(Article)
content = c.stringColumn()
hiddenAt = c.dateTimeColumn()
}
```

Expand All @@ -30,12 +30,12 @@ export class Comment {

First, we create a public role using [createRole](/reference/engine/schema/acl.md#create-role) function.

There is only single mandatory argument - a role identifier. In second argument, we can define various role options, as described [here](/reference/engine/schema/acl.md#create-role).
There is only single mandatory argument - a role identifier. In second argument, we can define various role options, as described [here](/reference/engine/schema/acl.md#create-role).

```typescript
import { AclDefinition as acl } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

export const publicRole = acl.createRole('public')
export const publicRole = c.createRole('public')
```

Second, we assign an access rule to a `Comment` entity using [allow](/reference/engine/schema/acl.md#allow) function.
Expand All @@ -45,7 +45,7 @@ In `when` we define a predicate. In `read` there is an array of accessible field

```typescript
// highlight-start
@acl.allow(publicRole, {
@c.Allow(publicRole, {
read: ['content'],
when: { hiddenAt: { isNull: true } },
})
Expand All @@ -62,15 +62,15 @@ That's all. Now, if you access the API with `public` role, you can see not hidde
Now, we define a second mentioned role - a `moderator`. Again, we define a role:

```typescript
export const moderatorRole = acl.createRole('moderator')
export const moderatorRole = c.createRole('moderator')
```

Now it gets a bit more tricky, as we want to allow to only moderate comments in given category.

Let's define an [entity variable](#entity-variable), where a category ID (or a list of categories) will be stored for given user.

```typescript
export const categoryIdVariable = acl.createEntityVariable('categoryId', 'Category', moderatorRole)
export const categoryIdVariable = c.createEntityVariable('categoryId', 'Category', moderatorRole)
```

You can manage this variable [on memberships using Tenant API](/reference/engine/tenant/memberships.md) using its name - `categoryId`.
Expand All @@ -79,7 +79,7 @@ Now we attach another ACL definition to our `Comment` entity:

```typescript
// highlight-start
@acl.allow(moderatorRole, {
@c.Allow(moderatorRole, {
update: ['hiddenAt', 'content'],
when: { article: { category: { id: categoryIdVariable } } },
})
Expand All @@ -90,7 +90,7 @@ export class Comment {
}
```

As you can see, you can traverse through relations. Our definition says, that `moderator` can update fields `hiddenAt` and `content` of any `Comment` of an `Article` in a `Category` defined in `categoryId` variable.
As you can see, you can traverse through relations. Our definition says, that `moderator` can update fields `hiddenAt` and `content` of any `Comment` of an `Article` in a `Category` defined in `categoryId` variable.

:::note migrations
Don't forget to [create a migration](/reference/engine/migrations/basics.md) to apply changes:
Expand All @@ -101,34 +101,34 @@ npm run contember migrations:diff my-blog setup-acl

#### Full example:
```typescript
import { SchemaDefinition as def, Acldefinition as acl } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

export const publicRole = acl.createRole('public')
export const publicRole = c.createRole('public')

export const moderatorRole = acl.createRole('moderator')
export const categoryIdVariable = acl.createEntityVariable('categoryId', 'Category', moderatorRole)
export const moderatorRole = c.createRole('moderator')
export const categoryIdVariable = c.createEntityVariable('categoryId', 'Category', moderatorRole)

export class Category {
// ....
}

export class Article {
category = def.manyHasOne(Category)
category = c.manyHasOne(Category)
// ....
}

@acl.allow(moderatorRole, {
@c.Allow(moderatorRole, {
when: { article: { category: { id: categoryIdVariable } } },
update: ['hiddenAt', 'content'],
})
@acl.allow(publicRole, {
@c.Allow(publicRole, {
when: { hiddenAt: { isNull: true } },
read: ['content'],
})
export class Comment {
article = def.manyHasOne(Article)
content = def.stringColumn()
hiddenAt = def.dateTimeColumn()
article = c.manyHasOne(Article)
content = c.stringColumn()
hiddenAt = c.dateTimeColumn()
}

```
44 changes: 16 additions & 28 deletions docs/docs/guides/seo.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ First, we have to define the schema. Here we have chosen four fields we want to
For this, we define an entity in our schema with fields. We are making only the `title` field required (using the `.notNull()` call). We save it in a new file.

```tsx title="api/model/Seo.ts"
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

export class Seo {
title = def.stringColumn().notNull()
description = def.stringColumn()
ogTitle = def.stringColumn()
ogDescription = def.stringColumn()
title = c.stringColumn().notNull()
description = c.stringColumn()
ogTitle = c.stringColumn()
ogDescription = c.stringColumn()
}
```

Expand All @@ -41,15 +41,15 @@ To add SEO fields to all of these pages you can create a single `Seo` entity and
To connect it to the `Article` entity we add the relation to the entity:

```tsx title="api/model/Article.ts"
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'
// highlight-next-line
import { Seo } from './Seo'

export class Article {
// some specific fields…

// highlight-next-line
seo = def.oneHasOne(Seo, 'article').notNull().removeOrphan()
seo = c.oneHasOne(Seo, 'article').notNull().removeOrphan()
}
```

Expand All @@ -60,18 +60,18 @@ Note, that if you have already created some articles you can't mark this field a
To specify the other side of the relation we add a field to the `Seo` entity we created earlier.

```tsx title="api/model/Seo.ts"
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'
// highlight-next-line
import { Article } from './Article'

export class Seo {
title = def.stringColumn().notNull()
description = def.stringColumn()
ogTitle = def.stringColumn()
ogDescription = def.stringColumn()
title = c.stringColumn().notNull()
description = c.stringColumn()
ogTitle = c.stringColumn()
ogDescription = c.stringColumn()

// highlight-next-line
article = def.oneHasOneInverse(Article, 'seo')
article = c.oneHasOneInverse(Article, 'seo')
}
```

Expand All @@ -82,11 +82,7 @@ To create migration for this we run `npm run contember migration:diff . add-seo`
Now, we have these fields in our database and API, but we need to add them to our administration. To easily reuse them in different parts of our administration we can create a component that will encapsulate all the fields. We create a new file for it:

```tsx title="admin/components/Seo.tsx"
import {
Component,
TextAreaField,
TextField,
} from '@contember/admin'
import { Component, TextAreaField, TextField } from '@contember/admin'

export const Seo = Component(
() => (
Expand Down Expand Up @@ -127,11 +123,7 @@ Most of the time your article or page has a title that you use as a title in SEO
First, let's modify our `Seo` component to take the name of the field we should copy the title from.

```tsx title="admin/components/Seo.tsx"
import {
Component,
TextAreaField,
TextField,
} from '@contember/admin'
import { Component, TextAreaField, TextField } from '@contember/admin'

/* highlight-start */
interface SeoProps {
Expand All @@ -156,11 +148,7 @@ export const Seo = Component<SeoProps>(
And then, when the prop is passed, we use the `DerivedFieldLink` component. Thus when the source field (title of the article) is edited, the change is mirrored in the derived fields (`seo.title` and `seo.ogTitle`).

```tsx title="admin/components/Seo.tsx"
import {
Component,
TextAreaField,
TextField,
} from '@contember/admin'
import { Component, TextAreaField, TextField } from '@contember/admin'

interface SeoProps {
titleField?: string
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/intro/actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ While there's an extensive range of potential applications for Actions, we're go
From our [previous steps](/intro/quickstart), we already have the schema. Imagine you want to send a Slack notification every time a new article is created. Here's how you'd modify the schema:

```javascript
import { SchemaDefinition as def, ActionsDefinition as actions } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

@actions.trigger({
@c.Trigger({
name: 'sent_to_slack',
create: true,
selection: `title`,
webhook: 'https://example.com/send_to_slack', // we'll get to this later
})
export class Article {
title = def.stringColumn()
content = def.stringColumn()
title = c.stringColumn()
content = c.stringColumn()
}
```

Expand Down
12 changes: 6 additions & 6 deletions docs/docs/intro/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ Define your project's schema, which is then passed to the Contember Engine. Cont

```typescript
// Post.ts
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

export const publicRole = acl.createRole('public')
export const publicRole = c.createRole('public')

@acl.allow(publicRole, {
@c.Allow(publicRole, {
when: { publishedAt: { gte: 'now' } },
read: ['content'],
})
export class Post {
title = def.stringColumn().notNull()
publishedAt = def.dateTimeColumn()
content = def.stringColumn().notNull()
title = c.stringColumn().notNull()
publishedAt = c.dateTimeColumn()
content = c.stringColumn().notNull()
}
```
### 2. GraphQL API Generation
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/intro/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ your_project_name/
When we installed Contember it already created the structure above. Let's go to `api/model/index.ts` file. It looks like this:

```ts
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

// export your model definition here

Expand All @@ -67,11 +67,11 @@ For instance, if you were building a blog platform, some of the entities could b
In this example, we'll define entity `Article` with two properties: `title` and `content`, which are both of type string. <span class="smallNote">In real life we would obviously want it a bit different, but this is a very basic example designed to quickly show you how to work with Contember.</span>

```ts title="api/model/index.ts"
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

export class Article {
title = def.stringColumn()
content = def.stringColumn()
title = c.stringColumn()
content = c.stringColumn()
}
```

Expand Down
12 changes: 6 additions & 6 deletions docs/docs/intro/studio-quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,22 @@ In `api/model/index.ts` file you can find your application data model that AI bu
Really simple example looks like this but you'll obviously have a more complicated one.

```ts title="api/model/index.ts"
import { SchemaDefinition as def } from '@contember/schema-definition'
import { c } from '@contember/schema-definition'

@acl.allow(publicRole, {
@c.Allow(publicRole, {
read: ['content'],
when: { hiddenAt: { isNull: true } },
})
export class Article {
title = def.stringColumn()
content = def.stringColumn()
hiddenAt = def.dateTimeColumn()
title = c.stringColumn()
content = c.stringColumn()
hiddenAt = c.dateTimeColumn()
}
```

Few notes:

1. Thanks to `import { SchemaDefinition as def }` you get TypeScript autocompletion. Just press ctrl+space in your editor and you'll what you can use for each entity. It will also underline any errors.
1. Thanks to `import { c }` you get TypeScript autocompletion. Just press ctrl+space in your editor and you'll what you can use for each entity. It will also underline any errors.
2. Schema consists of Entities. Each entity has columns with many supported types.
3. Above Entities you can find access control decorators which define what role can access what.

Expand Down
Loading

0 comments on commit 790bc91

Please sign in to comment.