Skip to content

Commit

Permalink
Merge pull request #9571 from linode/staging
Browse files Browse the repository at this point in the history
Release v1.100.0 - staging → master
  • Loading branch information
mjac0bs authored Aug 21, 2023
2 parents 593c311 + 41bcc15 commit 49a2df2
Show file tree
Hide file tree
Showing 649 changed files with 8,393 additions and 6,751 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ packages/manager/test-report.xml
**/manager/config/staging.json
**/manager/cypress/videos/
**/manager/cypress/downloads/
**/manager/cypress/results/

# ignore all screenshots except records
# we ignore the png files, not the whole folder recursively
Expand Down
62 changes: 62 additions & 0 deletions docs/development-guide/13-coding-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,68 @@ The styles for Cloud Manager are located in three places:
- The breakpoints can be modified at `/foundations/breakpoints/index.ts`.
- Component-specific styles may be defined either at the end of the component file or in a dedicated file, named `ComponentName.styles.tsx`. Refer to the guidelines outlined in the "Styles" section of [Component Structure](02-component-structure.md#styles).

## Typesript Unions, Const Enums and Objects
In our development process, we often encounter scenarios where we need to handle various messages or descriptions in our application. These messages can range from short, pithy statements to longer, more descriptive texts. To ensure a consistent and maintainable approach, we can use union types for lists of pithy data and const enums or plain old JavaScript objects (POJOs) for longer descriptions.

### Union Types for Pithy Data
When dealing with short and concise messages, like error notifications or status updates, using union types can provide a clean and easily understandable way to define the different message types. Union types allow us to define a value that can be one of several types. In this case, we can define a union type for pithy messages using string literals:

```
type CreateTypes = 'fromApp' | 'fromStackScript' | 'fromImage'
```

### Const Enums and POJOs for Longer Descriptions
For longer descriptions that require more context and detail, const enums or plain old JavaScript objects (POJOs) are more suitable. Both approaches provide a structured way to define and organize multiple messages while allowing for descriptive properties.

#### Const Enums Approach:
```
const enum NoOptionsMessage {
Error = 'An error occurred while fetching your options',
NoOptions = 'You have no options to choose from',
NoResults = 'No results',
}
```
With const enums, we define a set of related constants with descriptive names and associated values. Const enums offer benefits primarily during compile-time rather than runtime. Unlike regular enums, const enums do not generate any JavaScript code during compilation. Instead, their values are inlined directly into the generated JavaScript code at compile-time.

#### POJOs Approach:
```
const NoOptionsMessage = {
Error: 'An error occurred while fetching your options',
NoOptions: 'You have no options to choose from',
NoResults: 'No results',
} as const;
```
With POJOs, we create a read-only object using the `as const` assertion to ensure that the values cannot be modified after creation.

### Using Generics and typeof to Extract Values from as const Objects
In addition to utilizing const enums and POJOs for longer descriptions, we can further enhance our code's flexibility and type safety by extracting values from objects declared with `as const`. This can be achieved using generics and the `typeof` operator.
```
const CreateTypes = {
App: 'fromApp',
Stackscript: 'fromStackScript',
Image: 'fromImage',
Backup: 'fromBackup',
Linode: 'fromLinode',
} as const;
```
We can define a generic type, `ObjectValues`, that accepts an object type and extracts its values using the `keyof` operator. This provides us with the flexibility to create union types from object values.
```
type ObjectValues<T> = T[keyof T];
// Union type: 'fromApp' | 'fromStackScript' | 'fromImage' | 'fromBackup' | 'fromLinode'
type LinodeCreateFrom = ObjectValues<typeof CreateTypes>;
```
In our specific case, we can use `ObjectValues<typeof CreateTypes>` to extract the values from the `CreateTypes` object.
By utilizing this approach, we ensure that the values passed to `myFunction` are limited to the possible values defined in the `CreateTypes` object. This enhances type safety and prevents accidental usage of incorrect values.
```
function myFunction(type: LinodeCreateFrom) {
// Function implementation
}
myFunction(CreateTypes.Backup); // Works
myFunction('fromBackup'); // Works
```

## Adobe Analytics

### Writing a Custom Event
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@
"version": "0.0.0",
"volta": {
"node": "18.14.1"
}
},
"dependencies": {}
}
8 changes: 8 additions & 0 deletions packages/api-v4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## [2023-08-21] - v0.99.0


### Changed:

- Include `vpc_id` and rename `subnet` to `subnet_id` in Linode config interface return object ([#9485](https://github.com/linode/manager/pull/9485))


## [2023-08-07] - v0.98.0

### Added:
Expand Down
2 changes: 1 addition & 1 deletion packages/api-v4/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@linode/api-v4",
"version": "0.98.0",
"version": "0.99.0",
"homepage": "https://github.com/linode/manager/tree/develop/packages/api-v4",
"bugs": {
"url": "https://github.com/linode/manager/issues"
Expand Down
102 changes: 102 additions & 0 deletions packages/api-v4/src/aglb/certificates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import Request, {
setData,
setMethod,
setParams,
setURL,
setXFilter,
} from '../request';
import { BETA_API_ROOT } from 'src/constants';
import { Filter, Params, ResourcePage } from '../types';
import { Certificate, CreateCertificatePayload } from './types';

/**
* getLoadbalancerCertificates
*
* Returns a paginated list of Akamai Global Load Balancer certificates
*/
export const getLoadbalancerCertificates = (
loadbalancerId: number,
params?: Params,
filter?: Filter
) =>
Request<ResourcePage<Certificate>>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(loadbalancerId)}/certificates`
),
setMethod('GET'),
setParams(params),
setXFilter(filter)
);

/**
* getLoadbalancerCertificate
*
* Returns an Akamai Global Load Balancer certificate
*/
export const getLoadbalancerCertificate = (
loadbalancerId: number,
certificateId: number
) =>
Request<Certificate>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/certificates/${encodeURIComponent(certificateId)}`
),
setMethod('GET')
);

/**
* createLoadbalancerCertificate
*
* Creates an Akamai Global Load Balancer certificate
*/
export const createLoadbalancerCertificate = (
loadbalancerId: number,
data: CreateCertificatePayload
) =>
Request<Certificate>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(loadbalancerId)}/certificates`
),
setMethod('POST'),
setData(data)
);

/**
* updateLoadbalancerCertificate
*
* Creates an Akamai Global Load Balancer certificate
*/
export const updateLoadbalancerCertificate = (
loadbalancerId: number,
certificateId: number,
data: Partial<CreateCertificatePayload>
) =>
Request<Certificate>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/certificates/${encodeURIComponent(certificateId)}`
),
setMethod('PUT'),
setData(data)
);

/**
* deleteLoadbalancerCertificate
*
* Deletes an Akamai Global Load Balancer certificate
*/
export const deleteLoadbalancerCertificate = (
loadbalancerId: number,
certificateId: number
) =>
Request<{}>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/certificates/${encodeURIComponent(certificateId)}`
),
setMethod('DELETE')
);
106 changes: 106 additions & 0 deletions packages/api-v4/src/aglb/configurations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import Request, {
setData,
setMethod,
setParams,
setURL,
setXFilter,
} from '../request';
import { Filter, Params, ResourcePage } from '../types';
import { BETA_API_ROOT } from '../constants';
import type { Configuration, ConfigurationPayload } from './types';

/**
* getLoadbalancerConfigurations
*
* Returns a paginated list of Akamai Global Load Balancer configurations
*/
export const getLoadbalancerConfigurations = (
loadbalancerId: number,
params?: Params,
filter?: Filter
) =>
Request<ResourcePage<Configuration>>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/configurations`
),
setMethod('GET'),
setParams(params),
setXFilter(filter)
);

/**
* getLoadbalancerConfiguration
*
* Returns an Akamai Global Load Balancer configuration
*/
export const getLoadbalancerConfiguration = (
loadbalancerId: number,
configurationId: number
) =>
Request<Configuration>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/configurations/${encodeURIComponent(configurationId)}`
),
setMethod('GET')
);

/**
* createLoadbalancerConfiguration
*
* Creates an Akamai Global Load Balancer configuration
*/
export const createLoadbalancerConfiguration = (
loadbalancerId: number,
data: ConfigurationPayload
) =>
Request<Configuration>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/configurations`
),
setData(data),
setMethod('POST')
);

/**
* updateLoadbalancerConfiguration
*
* Updates an Akamai Global Load Balancer configuration
*/
export const updateLoadbalancerConfiguration = (
loadbalancerId: number,
configurationId: number,
data: Partial<ConfigurationPayload>
) =>
Request<Configuration>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/configurations/${encodeURIComponent(configurationId)}`
),
setData(data),
setMethod('PUT')
);

/**
* deleteLoadbalancerConfiguration
*
* Deletes an Akamai Global Load Balancer configuration
*/
export const deleteLoadbalancerConfiguration = (
loadbalancerId: number,
configurationId: number
) =>
Request<{}>(
setURL(
`${BETA_API_ROOT}/aglb/${encodeURIComponent(
loadbalancerId
)}/configurations/${encodeURIComponent(configurationId)}`
),
setMethod('DELETE')
);
68 changes: 0 additions & 68 deletions packages/api-v4/src/aglb/entrypoints.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/api-v4/src/aglb/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './entrypoints';
export * from './configurations';

export * from './loadbalancers';

Expand Down
Loading

0 comments on commit 49a2df2

Please sign in to comment.