Skip to content

Commit

Permalink
feat: update apis to generic query endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoMunizOdoo committed Oct 3, 2023
1 parent 300bb2b commit 195618c
Show file tree
Hide file tree
Showing 31 changed files with 2,570 additions and 185 deletions.
12 changes: 3 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@
"license": "MIT",
"scripts": {
"build": "lerna run build",
"dev": "concurrently --names \"Frontend,Middleware\" \"npm run dev:app\" \"npm run dev:middleware\"",
"dev": "concurrently --names \"Frontend,Server\" \"npm run dev:app\" \"npm run dev:server\"",
"dev:app": "cd playground/app && npm run dev",
"dev:middleware": "cd playground/middleware && npm run dev",
"publish:sdk": "node ./scripts/publishApi.js",
"publish:sdk-api": "node ./scripts/publishComposable.js",
"test": "lerna run test",
"codegen": "cd packages/sdk-api-client && yarn codegen",
"prepare": "husky install",
"commit": "git-cz",
"lint": "eslint . --ext .ts,.vue"
"dev:server": "cd playground/server && npm run dev",
"test": "lerna run test"
},
"config": {
"commitizen": {
Expand Down
18 changes: 8 additions & 10 deletions packages/sdk-api-client/__mocks__/context.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,34 @@ import customQueryCategoryListWithoutChild from '../__mocks__/customQueries/cust
import customQueryProductVariant from '../__mocks__/customQueries/customQueryProductVariant';
import customQueryCountryListWithoutState from './customQueries/customQueryCountryListWithoutState';



const apolloClient = buildClient({
odooGraphqlUrl: "http://localhost:3000/api/graphql",
odooGraphqlUrl: 'http://localhost:5000/api/graphql',
fetchOptions: {}
})
});

// Add custom queries like a real application will do
const customQueries = {
customQueryFullProductTemplate,
customQueryFullProductTemplateListWithoutPrice,
customQueryCategoryWithoutChild,
customQueryCategoryListWithoutChild,
customQueryProductVariant,
customQueryProductVariant,
customQueryCountryListWithoutState
}
};

export const contextMock = {
config: {} as any,
client: apolloClient,
api: jest.fn() as any,
extendQuery: (customQuery: any, defaults: any) => {
const key = Object.keys(defaults)[0]
const key = Object.keys(defaults)[0];

return {
[key]: {
query: customQuery ? customQueries[customQuery[key]] : defaults[key].query,
variables: defaults[key].variables,
variables: defaults[key].variables
}
}
};
},
customQueries
};
7 changes: 0 additions & 7 deletions packages/sdk-api-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,10 @@
"axios": "^0.21.1",
"consola": "^3.0.0",
"cross-fetch": "^4.0.0",
"graphql": "^16.7.1",
"request-ip": "^3.3.0",
"winston": "^3.9.0"
},
"devDependencies": {
"@graphql-codegen/cli": "^4.0.1",
"@graphql-codegen/client-preset": "^4.0.1",
"@graphql-codegen/typescript": "^4.0.1",
"@graphql-codegen/typescript-generic-sdk": "^3.1.0",
"@graphql-typed-document-node/core": "^3.2.0",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"eslint": "^8.45.0",
"jsdom": "^17.0.0",
"typescript": "^5.1.6"
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk-api-client/src/api/query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DocumentNode, gql } from '@apollo/client';
import { Endpoints, OdooIntegrationContext, QueryMetadataParams } from '../../types';

export const query: Endpoints['query'] = async <ApiParams, ApiResponseType>(context: OdooIntegrationContext, metadata: QueryMetadataParams, params?: ApiParams) => {
const query = gql(metadata.query) as DocumentNode;
const query = context.config.queries[metadata.queryName];

const response = await context.client.query<ApiResponseType, ApiParams>({
variables: params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const sessionHeaderExtension: ApiClientExtension = {
},
beforeCall: ({ configuration, callName, args }) => args,
afterCall: ({ configuration, callName, response }) => {
if ((response as any).data.cookie) {
res.setHeader('Set-cookie', (response as any).data.cookie);
if ((response as any)?.data?.cookie) {
res.setHeader('Set-cookie', (response as any)?.data?.cookie);
}

return response;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/sdk-api-client/src/types/api/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { Product, Category, QueryProductArgs, QueryCountriesArgs, QueryProductsA
import { CustomQuery } from '@vue-storefront/middleware';

export interface QueryMetadataParams {
query: string;
queryName: string;
cacheKey?: string
}

Expand Down
8 changes: 6 additions & 2 deletions packages/sdk-api-client/src/types/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DocumentNode } from '@apollo/client';

/**
* Settings to be provided in the `middleware.config.js` file.
*/
Expand All @@ -6,5 +8,7 @@ export interface MiddlewareConfig {
fetchOptions?: any;
sessionAuth?: string,
requestHost?: string,
realIp?: string
}
realIp?: string,
queries: Record<string, DocumentNode>

}
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@erpgap/odoo-sdk-api-client": "*",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-replace": "^2.3.3",
"@vue-storefront/sdk": "1.0.5",
"@vue-storefront/sdk": "1.1.2",
"babel-jest": "^29.6.1",
"msw": "^0.47.3",
"nock": "^13.2.9",
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/methods/query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { client } from '../../client';
* @example
*/
export async function query<ApiParams, ApiResponseType>(metadata: QueryMetadataParams, params?: ApiParams): Promise<ApolloQueryResult<ApiResponseType>> {
const { data } = await client.post<ApolloQueryResult<ApiResponseType>>('query', { metadata, params });
const { data } = await client.post<ApolloQueryResult<ApiResponseType>>('query', [metadata, params]);

return data;
}
19 changes: 19 additions & 0 deletions playground/app/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
schema: [
{
'https://vsfdemo15.labs.odoogap.com/graphql/vsf': {
},
},
],
ignoreNoDocuments: true,
generates: {
'./graphql/gql/': {
documents: ['graphql/**/*.tsx'],
preset: 'client'
},
},
}

export default config
66 changes: 66 additions & 0 deletions playground/app/graphql/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
import { FragmentDefinitionNode } from 'graphql';
import { Incremental } from './graphql';


export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<
infer TType,
any
>
? [TType] extends [{ ' $fragmentName'?: infer TKey }]
? TKey extends string
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
: never
: never
: never;

// return non-nullable if `fragmentType` is non-nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
): TType | null | undefined;
// return array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
): ReadonlyArray<TType>;
// return array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
): TType | ReadonlyArray<TType> | null | undefined {
return fragmentType as any;
}


export function makeFragmentData<
F extends DocumentTypeDecoration<any, any>,
FT extends ResultOf<F>
>(data: FT, _fragment: F): FragmentType<F> {
return data as FragmentType<F>;
}
export function isFragmentReady<TQuery, TFrag>(
queryNode: DocumentTypeDecoration<TQuery, any>,
fragmentNode: TypedDocumentNode<TFrag>,
data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined
): data is FragmentType<typeof fragmentNode> {
const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__
?.deferredFields;

if (!deferredFields) return true;

const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined;
const fragName = fragDef?.name?.value;

const fields = (fragName && deferredFields[fragName]) || [];
return fields.length > 0 && fields.every(field => data && field in data);
}
24 changes: 24 additions & 0 deletions playground/app/graphql/gql/gql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable */
import * as types from './graphql';
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';

const documents = [];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*
*
* @example
* ```ts
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
* ```
*
* The query argument is unknown!
* Please regenerate the types.
*/
export function graphql(source: string): unknown;

export function graphql(source: string) {
return (documents as any)[source] ?? {};
}

export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
Loading

0 comments on commit 195618c

Please sign in to comment.