Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add @guardian/libs code #63

Merged
merged 4 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The following packages live in `libs/@guardian/*` and are published to NPM:
- [@guardian/browserslist-config](libs/@guardian/browserslist-config)
- [@guardian/eslint-config](libs/@guardian/eslint-config)
- [@guardian/eslint-config-typescript](libs/@guardian/eslint-config-typescript)
- [@guardian/libs](libs/@guardian/libs)
- [@guardian/prettier](libs/@guardian/prettier)
- [@guardian/tsconfig](libs/@guardian/tsconfig)

Expand Down
2 changes: 1 addition & 1 deletion libs/@guardian/libs/.lintstagedrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const config = require('../../../.lintstagedrc.js');

module.exports = {
'src/logger/**/*':
'src/logger/**/*|scripts/generateSvg.logger.teams.*':
'node -r @swc-node/register scripts/generateSvg.logger.teams.ts',
'*': 'node -r @swc-node/register scripts/update-readme.ts',
...config,
Expand Down
21 changes: 0 additions & 21 deletions libs/@guardian/libs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,3 @@ If you are using this library with TypeScript, make sure you are using at least
This package uses `ES2020`.

If your target environment does not support that, make sure you transpile this package when bundling your application.

## Development
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these sections now covered by a more general monorepo readme? maybe we could link to where that is, if it exists?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, this readme is the info gets displayed on npm for example, so it's still needed here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry — I was referring to the ones you removed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no that's something we need to address, but probably beyond the scope of this PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, is it recorded somewhere that we need to address this? (on trello or similar)


### Requirements

1. [Node LTS (latest)](https://nodejs.org/en/download/) ([nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm) recommended)
2. [Yarn](https://classic.yarnpkg.com/en/docs/install/)

### Releasing

Changes are automatically released to NPM.

The `main` branch on GitHub is analysed by [semantic-release](https://semantic-release.gitbook.io/) after every push.

If a commit message follows the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0), semantic-release can determine what Types of changes are included in that commit.

If necessary, it will then automatically release a new, [semver](https://semver.org/)-compliant version of the package to NPM.

#### Pull requests

Try to write PR titles in the conventional commit format, and [squash and merge](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges#squash-and-merge-your-pull-request-commits) when merging. That way your PR will trigger a release when you merge it (if necessary).
27 changes: 0 additions & 27 deletions libs/@guardian/libs/import

This file was deleted.

7 changes: 2 additions & 5 deletions libs/@guardian/libs/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
{
"name": "@guardian/libs",
"version": "8.0.1",
"private": true,
"version": "8.0.0",
"private": false,
"description": "A collection of JavaScript libraries and TypeScript types for Guardian projects",
"sideEffects": false,
"dependencies": {
"original-libs": "npm:@guardian/[email protected]"
},
"devDependencies": {
"@types/wcag-contrast": "3.0.0",
"jest-fetch-mock": "3.0.3",
Expand Down
86 changes: 86 additions & 0 deletions libs/@guardian/libs/scripts/generateSvg.logger.teams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import fs from 'node:fs';
import { commonStyle, teamStyles } from '../src/logger/teamStyles';

function generateSvg(): string {
const teams = Object.entries(teamStyles);

const padding = 10;
const lineHeight = 24;
const width = 600;
const height = teams.length * lineHeight + padding * 2 + 60;

const lines = teams.map((team, index) => {
const [name, colours] = team;
return `<div class="line">
<span class="label common">@guardian</span>
<span class="label ${name}" style="background-color: ${colours.background}; color: ${colours.font}">${name}</span>
<span class="label">message no.${index}</span>
<span class="gap"></span>
<span class="label log">console.log</span>
</div>`;
});
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
<style>
.wrapper {
font-family: monospace;
padding: ${padding}px;
width: 100%;
height: 100%;
}

* {
box-sizing: border-box;
}

#console {
width: 100%;
height: 100%;
border: 2px solid #999;
border-radius: 5px
}
.line {
display: flex;
height: ${lineHeight}px;
border-bottom: 1px solid #ccc;
padding: 2px 10px;
}
.line.top {
font-family: sans-serif;
border-color: #999;
border-width: 2px;
}
.label {
display: inline-block;
height: min-content;
padding: 2px 3px;
border-radius:3px
}
.label:nth-of-type(n+2) {
margin-left: 3px;
}
.gap {
flex-grow: 1;
}
.log {
opacity: 0.7;
text-decoration: underline;
}

.common {
background-color: ${commonStyle.common.background};
color: ${commonStyle.common.font};
}
</style>
<foreignObject x="0" y="0" width="${width}" height="${height}">
<div class="wrapper" xmlns="http://www.w3.org/1999/xhtml">
<div id="console">
<div class="line top">Console</div>
${lines.join('')}
</div>
</div>
</foreignObject>
</svg>`;
return svg;
}

fs.writeFileSync(__dirname + '/../static/logger.svg', generateSvg());
20 changes: 20 additions & 0 deletions libs/@guardian/libs/src/@types/window.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { TeamSubscription } from '../logger/@types/logger';
import type { Switches } from '../switches/@types/Switches';

declare global {
interface Window {
guardian?: {
logger?: {
subscribeTo: TeamSubscription;
unsubscribeFrom: TeamSubscription;
teams: () => string[];
};
config?: {
page?: {
isPreview: boolean;
};
switches?: Switches;
};
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ArticleElementRole } from './ArticleElementRole';

it('ArticleElementRole enum contains Standard', () => {
expect(ArticleElementRole.Standard).toBeDefined();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// ----- Types ----- //

enum ArticleElementRole {
Standard,
Immersive,
Supporting,
Showcase,
Inline,
Thumbnail,
HalfWidth,
}

// ----- Exports ----- //

export { ArticleElementRole };
11 changes: 11 additions & 0 deletions libs/@guardian/libs/src/ArticleElementRole/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# `ArticleElementRole`

ArticleElementRole is a semantic/layout-oriented property that's applied to elements in an article. It describes the "role" of that element in the piece and how it should be laid out within the page. Consider the example of an image: is the image filling a "supporting" role? is it just a thumbnail? is it "showcasing" something?

Whilst most commonly used for images, it can also apply to atoms and embeds.

## Usage

```js
import { ArticleElementRole } from '@guardian/libs';
```
1 change: 1 addition & 0 deletions libs/@guardian/libs/src/cookies/ERR_INVALID_COOKIE.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ERR_INVALID_COOKIE = `Cookie must not contain invalid characters (space, tab and the following characters: '()<>@,;"/[]?={}')`;
132 changes: 132 additions & 0 deletions libs/@guardian/libs/src/cookies/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Cookies

Robust API over `document.cookie`.

### Usage

```js
import {
getCookie,
removeCookie,
setCookie,
setSessionCookie
} from '@guardian/libs';
```

## Methods

- [`setCookie({name, value, daysToLive?, isCrossSubdomain?})`](#setCookie)
- [`setSessionCookie({name, value})`](#setSessionCookie)
- [`getCookie({name, shouldMemoize?})`](#getCookie)
- [`removeCookie(name)`](#removeCookie)

## `setCookie({name, value, daysToLive?, isCrossSubdomain?})`

Returns: `void`

Sets a cookie taking a config object with name and value, optional daysToLive and optional isCrossSubdomain flag.

#### `name`

Type: `string`

Name of the cookie.

#### `value`

Type: `string`<br>

Value of the cookie.

#### `daysToLive?`

Type: `number`

Days you would like this cookie to live for.

#### `isCrossSubdomain?`

Type: `boolean`<br>

Set this true if the cookie is cross subdomain.

### Example

```js
setCookie({name:'GU_country_code', value:'GB'})
setCookie({name:'GU_country_code', value:'GB', daysToLive: 7})
setCookie({name:'GU_country_code', value:'GB', daysToLive: 7, isCrossSubdomain: true})
```

## `setSessionCookie({name, value})`

Returns: `void`

Sets a session cookie (no expiry date) taking a config object with name and value.

#### `name`

Type: `string`

Name of the cookie.

#### `value`

Type: `string`<br>

Value of the cookie.

### Example

```js
setSessionCookie({name:'GU_country_code', value: 'GB'})
```

## `getCookie({name, shouldMemoize?})`

Returns: `cookie` value if it exists or `null`. Takes a config object with name and shouldMemoize params

#### `name`

Type: `string`

Name of the cookie to retrieve.


#### `shouldMemoize?`

Type: `boolean`<br>

When this is set to true it will keep the cookie in memory to avoid fetching more than once.


### Example

```js
getCookie({name:'GU_geo_country'}); //GB
getCookie({name:'GU_geo_country', shouldMemoize: true}); //GB
```

## `removeCookie({name, currentDomainOnly?})`

Returns: `void`

Removes a cookie.

#### `names`

Type: `string`

Name of the stored cookie to remove.

#### `currentDomainOnly`

Type: `boolean`

Set to true if it's a cookie for current domain only, defaults to false
### Example

```js
removeCookie({name:'GU_geo_country'});
removeCookie({name:'GU_geo_country', currentDomainOnly: true});
```
Loading