Skip to content

Commit

Permalink
Connect adaptate and @adaptate/core
Browse files Browse the repository at this point in the history
  • Loading branch information
p10ns11y committed Nov 7, 2024
1 parent 25c7d1a commit 5a99af7
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 15 deletions.
17 changes: 11 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,19 @@ jobs:
- name: Build project
run: npx turbo run build

# - name: Publish to GitHub Packages
# working-directory: packages/core
# env:
# NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# run: npm publish --registry=https://npm.pkg.github.com/
- name: Publish adaptate to npm
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --access public

- name: Publish to npm
- name: Publish @adaptate/core to npm
working-directory: packages/core
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --access public

- name: Publish @adaptate/core to GitHub Packages
working-directory: packages/core
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm publish --registry=https://npm.pkg.github.com/
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ Dynamic and Adaptable Model Validator Using Zod, Interoperable with OpenAPI
To install the library, use npm or yarn:

```sh
npm install @adaptate/core
npm install adaptate
# or
yarn add @adaptate/core
yarn add adaptate
```

## Usage
Expand Down Expand Up @@ -89,7 +89,7 @@ You can make a Zod schema required based on a configuration (components need) us

```ts
import { z } from 'zod';
import { makeSchemaRequired } from '@adaptate/core';
import { makeSchemaRequired } from 'adaptate';

const schema = z.object({
name: z.string().optional(),
Expand Down Expand Up @@ -138,7 +138,7 @@ You can apply conditional requirements to a Zod schema using the applyConditiona

```ts
import { z } from 'zod';
import { applyConditionalRequirements } from '@adaptate/core';
import { applyConditionalRequirements } from 'adaptate';

const schema = z.object({
firstName: z.string().optional(),
Expand Down Expand Up @@ -176,7 +176,7 @@ const updatedSchema = applyConditionalRequirements(schema, config, data);
The utility is in the early stage and not one to one. For complete and advanced use cases check [json-schema-to-zod](https://snyk.io/advisor/npm-package/json-schema-to-zod)

```ts
import { openAPISchemaToZod } from '@adaptate/core';
import { openAPISchemaToZod } from 'adaptate';

const openAPISchema = {
type: 'object',
Expand All @@ -199,7 +199,7 @@ The utility is in the early stage and not one to one. For complete and advanced

```ts
import { z } from 'zod';
import { zodToOpenAPISchema } from '@adaptate/core';
import { zodToOpenAPISchema } from 'adaptate';

const zodSchema = z.object({
name: z.string(),
Expand Down Expand Up @@ -376,6 +376,9 @@ I have attempted to recreate what I have done at work with the help of ChatGPT C

### So why?

#### The Background
<details>
<summary>The Background</summary>

At [Oneflow AB](https://oneflow.com), we faced a situation where a component was used on two different pages, each receiving data from different endpoints. This led to discrepancies in the properties of the same model for valid reasons. To avoid breaking the app, I have built a run-time validation library that abstracted business data extensively. Although it wasn't completely dynamic, it supported specifying business entities, types such as `collection` or `entity`, and reusable specifications like `relations`. It also included React-specific hooks that worked seamlessly with error boundaries. This effort aims to create a more generic solution that can be extended to various use cases.

</details>
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"workspaces": [
"packages/*"
],
"version": "0.0.8",
"version": "0.0.9",
"author": {
"name": "Peramanathan Sathyamoorthy",
"url": "https://github.com/p10ns11y/adaptate.git"
Expand All @@ -17,6 +17,15 @@
},
"homepage": "https://github.com/p10ns11y/adaptate#readme",
"license": "MIT",
"type": "module",
"source": "./packages/core/src/index.ts",
"main": "./packages/core/build/index.es.js",
"types": "./packages/core/build/index.d.ts",
"files": [
"./packages/core/build",
"package.json",
"README.md"
],
"scripts": {
"build": "turbo run build"
},
Expand Down
106 changes: 106 additions & 0 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,109 @@ npm install @adaptate/core
# or
yarn add @adaptate/core
```

## Usage

So what this package ~~Sells~~ solves while there are so many packages in the [ecosystem](https://zod.dev/?id=ecosystem) out there.

#### The pitch for a common use case

In real-world web applications (for the sake of brevity assuming component-oriented apps/pages where the view/page is divided into composed components), developers run into an untreated and often unnoticed issue of data (props) flow into components.

Imagine a hypothetical page component

```tsx
{
/* I will check authentication and authorization to access this page
And put necessary session information and render the content if it is successful
*/
}
<Page>
<Sidebar>
<Navigations />
</Sidebar>
{/* I will fetch the business data from an API endpoint, say, `/api/participants` once and
Pass it down or put it in the global store. This data, either as a whole (not likely)
Or partially will be used by 1000s of components on this page
And from the same data model, each component requires different properties
*/}
<Main>
<Content>
<ComponentOne
data={
'I need so and so props from the parent to behave and function as expected'
}
/>
<ComponentTwo
data={
'I need only these props from the parent to behave and function as expected'
}
/>
{/* Oops! I am also used on some other page
Where the same data model has more properties
And the data comes from another endpoint, say, `/api/participants/participantId`.
And I am one of the most used components and many developers individually
Extend the component based on requirements. Yes, communication loop and forgetting
That it is also used in some other place is a problem when working on the component
In isolation
*/}
<ComponentThree
data={
'I need all these props from the parent to behave and function as expected'
}
/>
<ComponentFour
data={
'I need everything from the parent to behave and function as expected'
}
/>
</Content>
</Main>
</Page>;
```

## Make Required Schema Based on Configuration

You can make a Zod schema required based on a configuration (components need) using the makeSchemaRequired function.

```ts
import { z } from 'zod';
import { makeSchemaRequired } from '@adaptate/core';

const schema = z.object({
name: z.string().optional(),
age: z.number().optional(),
address: z
.object({
street: z.string().optional(),
city: z.string().optional(),
})
.optional(),
});

const config = {
name: true,
age: true,
address: {
city: true,
},
};

const updatedSchema = makeSchemaRequired(schema, config);

updatedSchema.parse({
name: 'Davin',
age: 30,
address: {
city: 'Pettit',
},
}); // will pass

updatedSchema.parse({
name: 'Davin',
age: 30,
address: {
street: 'First Avenue',
},
}); // will throw as required city property is missing
```
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adaptate/core",
"version": "0.0.8",
"version": "0.0.9",
"author": {
"name": "Peramanathan Sathyamoorthy",
"url": "https://github.com/p10ns11y/adaptate.git"
Expand Down

0 comments on commit 5a99af7

Please sign in to comment.