create-auto-app 0.3.0 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -0
- package/package.json +2 -3
- package/templates/shopping-app/.context/schema.json +426 -215
- package/templates/shopping-app/.context/server/.context/auto-ia-scheme.json +79 -0
- package/templates/shopping-app/.context/server/server/package.json +1 -1
- package/templates/shopping-app/.context/server/server/scripts/generate-schema.ts +1 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.specs.ts +1 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.specs.ts +51 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.ts +43 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/register.ts +24 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.specs.ts +1 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.specs.ts +1 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/commands.ts +8 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.specs.ts +101 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.ts +42 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/events.ts +9 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/evolve.ts +28 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/handle.ts +52 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/mutation.resolver.ts +25 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/register.ts +7 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/state.ts +47 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.specs.ts +41 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.ts +9 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/handle.ts +4 -1
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.specs.ts +3 -41
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.ts +2 -15
- package/templates/shopping-app/auto.config.ts +20 -20
- package/templates/shopping-app/client/package.json +4 -4
- package/templates/shopping-app/example-integrations/ai-chat-completion/package.json +5 -6
- package/templates/shopping-app/example-integrations/ai-chat-completion/src/ai-integration.ts +2 -2
- package/templates/shopping-app/example-integrations/cart/package.json +5 -6
- package/templates/shopping-app/example-integrations/cart-api/package.json +3 -3
- package/templates/shopping-app/example-integrations/product-catalogue/package.json +5 -5
- package/templates/shopping-app/example-integrations/product-catalogue/src/product-catalogue-integration.ts +0 -132
- package/templates/shopping-app/example-integrations/product-catalogue-api/package.json +3 -3
- package/templates/shopping-app/flows/shopping-assistant.flow.ts +195 -195
- package/templates/shopping-app/package.json +3 -1
- package/templates/shopping-app/server/package.json +3 -3
- package/templates/shopping-app/server/src/integrations/ai-integration.ts +2 -2
- package/templates/shopping-app/tsconfig.json +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, it, beforeEach, expect } from 'vitest';
|
|
2
2
|
import { InMemoryProjectionSpec } from '@event-driven-io/emmett';
|
|
3
3
|
import { projection } from './projection';
|
|
4
|
-
import type {
|
|
4
|
+
import type {} from '../unknown/events';
|
|
5
5
|
import { SuggestedItems } from './state';
|
|
6
6
|
|
|
7
|
-
type ProjectionEvent =
|
|
7
|
+
type ProjectionEvent = never;
|
|
8
8
|
|
|
9
9
|
describe('SuggestedItemsProjection Projection', () => {
|
|
10
10
|
let given: InMemoryProjectionSpec<ProjectionEvent>;
|
|
@@ -14,45 +14,7 @@ describe('SuggestedItemsProjection Projection', () => {
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
it('creates or updates SuggestedItems document - case 1', () =>
|
|
17
|
-
given([
|
|
18
|
-
{
|
|
19
|
-
type: 'ShoppingItemsSuggested',
|
|
20
|
-
data: {
|
|
21
|
-
sessionId: 'session-abc',
|
|
22
|
-
suggestedItems: [
|
|
23
|
-
{
|
|
24
|
-
productId: 'prod-soccer-ball',
|
|
25
|
-
name: 'Super Soccer Ball',
|
|
26
|
-
quantity: 1,
|
|
27
|
-
reason: 'Perfect for your daughter who loves soccer',
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
productId: 'prod-craft-kit',
|
|
31
|
-
name: 'Deluxe Craft Kit',
|
|
32
|
-
quantity: 1,
|
|
33
|
-
reason: 'Great for creative activities and crafts',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
productId: 'prod-laptop-bag',
|
|
37
|
-
name: 'Tech Laptop Backpack',
|
|
38
|
-
quantity: 1,
|
|
39
|
-
reason: "Essential for your son's school computer needs",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
productId: 'prod-mtg-starter',
|
|
43
|
-
name: 'Magic the Gathering Starter Set',
|
|
44
|
-
quantity: 1,
|
|
45
|
-
reason: 'Ideal starter set for Magic the Gathering enthusiasts',
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
metadata: {
|
|
50
|
-
streamName: 'ignored-stream',
|
|
51
|
-
streamPosition: 1n,
|
|
52
|
-
globalPosition: 1n,
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
])
|
|
17
|
+
given([])
|
|
56
18
|
.when([])
|
|
57
19
|
.then(async (state) => {
|
|
58
20
|
const document = await state.database
|
|
@@ -4,30 +4,17 @@ import {
|
|
|
4
4
|
type InMemoryReadEventMetadata,
|
|
5
5
|
} from '@event-driven-io/emmett';
|
|
6
6
|
import type { SuggestedItems } from './state';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type AllEvents = ShoppingItemsSuggested;
|
|
7
|
+
type AllEvents = never;
|
|
10
8
|
|
|
11
9
|
export const projection = inMemorySingleStreamProjection<SuggestedItems, AllEvents>({
|
|
12
10
|
collectionName: 'SuggestedItemsProjection',
|
|
13
|
-
canHandle: [
|
|
11
|
+
canHandle: [],
|
|
14
12
|
getDocumentId: (event) => event.data.sessionId,
|
|
15
13
|
evolve: (
|
|
16
14
|
document: SuggestedItems | null,
|
|
17
15
|
event: ReadEvent<AllEvents, InMemoryReadEventMetadata>,
|
|
18
16
|
): SuggestedItems | null => {
|
|
19
17
|
switch (event.type) {
|
|
20
|
-
case 'ShoppingItemsSuggested': {
|
|
21
|
-
/**
|
|
22
|
-
* ## IMPLEMENTATION INSTRUCTIONS ##
|
|
23
|
-
* This event adds or updates the document.
|
|
24
|
-
* Implement the correct fields as needed for your read model.
|
|
25
|
-
*/
|
|
26
|
-
return {
|
|
27
|
-
sessionId: /* TODO: map from event.data */ '',
|
|
28
|
-
items: /* TODO: map from event.data */ [],
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
18
|
default:
|
|
32
19
|
return document;
|
|
33
20
|
}
|
|
@@ -114,28 +114,28 @@ on<ServerGeneratedEvent>('ServerGenerated', (event) =>
|
|
|
114
114
|
]),
|
|
115
115
|
);
|
|
116
116
|
|
|
117
|
-
on<ServerImplementedEvent>('ServerImplemented', (event) =>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
);
|
|
117
|
+
// on<ServerImplementedEvent>('ServerImplemented', (event) =>
|
|
118
|
+
// dispatch.parallel<CheckTypesCommand | CheckTestsCommand | CheckLintCommand>([
|
|
119
|
+
// { type: 'CheckTypes', data: { targetDirectory: event.data.serverDirectory, scope: 'project' } },
|
|
120
|
+
// { type: 'CheckTests', data: { targetDirectory: event.data.serverDirectory, scope: 'project' } },
|
|
121
|
+
// { type: 'CheckLint', data: { targetDirectory: event.data.serverDirectory, scope: 'project' } },
|
|
122
|
+
// ]),
|
|
123
|
+
// );
|
|
124
124
|
|
|
125
|
-
on<IAGeneratedEvent>('IAGenerated', (event) =>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
);
|
|
125
|
+
// on<IAGeneratedEvent>('IAGenerated', (event) =>
|
|
126
|
+
// dispatch<ImplementClientCommand>({
|
|
127
|
+
// type: 'ImplementClient',
|
|
128
|
+
// data: {
|
|
129
|
+
// projectDir: event.data.outputDir.replace('/.context', '/client'),
|
|
130
|
+
// iaSchemeDir: event.data.outputDir,
|
|
131
|
+
// designSystemPath: './.context/design-system.md',
|
|
132
|
+
// },
|
|
133
|
+
// }),
|
|
134
|
+
// );
|
|
135
135
|
|
|
136
|
-
on<ClientImplementedEvent>('ClientImplemented', (event) =>
|
|
137
|
-
|
|
138
|
-
);
|
|
136
|
+
// on<ClientImplementedEvent>('ClientImplemented', (event) =>
|
|
137
|
+
// dispatch<CheckClientCommand>({ type: 'CheckClient', data: { clientDirectory: './client', skipBrowserChecks: true } }),
|
|
138
|
+
// );
|
|
139
139
|
|
|
140
140
|
// on<ClientImplementationFailedEvent>('ClientImplementationFailed', (event) =>
|
|
141
141
|
// dispatch<ImplementClientCommand>({
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"lint": "eslint .",
|
|
12
12
|
"preview": "vite preview",
|
|
13
13
|
"codegen": "graphql-codegen --config codegen.ts",
|
|
14
|
-
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../../.prettierignore",
|
|
14
|
+
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../../.prettierignore --log-level warn",
|
|
15
15
|
"type:check": "tsc --noEmit",
|
|
16
16
|
"type-check": "tsc --noEmit",
|
|
17
17
|
"lint:fix": "eslint .",
|
|
18
|
-
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../../.prettierignore",
|
|
18
|
+
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../../.prettierignore --log-level warn",
|
|
19
19
|
"auto-configure": "tsx auto-configure.ts"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@apollo/client": "^3.13.8",
|
|
23
|
-
"@auto-engineer/ai-gateway": "
|
|
24
|
-
"@auto-engineer/frontend-generator-react-graphql": "
|
|
23
|
+
"@auto-engineer/ai-gateway": "workspace:*",
|
|
24
|
+
"@auto-engineer/frontend-generator-react-graphql": "workspace:*",
|
|
25
25
|
"@hookform/resolvers": "^3.10.0",
|
|
26
26
|
"@radix-ui/react-accordion": "^1.2.11",
|
|
27
27
|
"@radix-ui/react-alert-dialog": "^1.1.14",
|
|
@@ -5,18 +5,17 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@auto-engineer/flow": "
|
|
9
|
-
"@auto-engineer/ai-gateway": "
|
|
8
|
+
"@auto-engineer/flow": "workspace:*",
|
|
9
|
+
"@auto-engineer/ai-gateway": "workspace:*"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc",
|
|
13
|
-
"
|
|
14
|
-
"test": "vitest run",
|
|
13
|
+
"test": "vitest run --reporter=dot",
|
|
15
14
|
"lint": "eslint 'src/**/*.ts' --max-warnings 0 --config ./eslint.config.ts",
|
|
16
15
|
"type-check": "tsc --noEmit",
|
|
17
|
-
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore",
|
|
16
|
+
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn",
|
|
18
17
|
"lint:fix": "eslint 'src/**/*.ts' --fix --config ./eslint.config.ts",
|
|
19
|
-
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore"
|
|
18
|
+
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn"
|
|
20
19
|
},
|
|
21
20
|
"publishConfig": {
|
|
22
21
|
"access": "public"
|
package/templates/shopping-app/example-integrations/ai-chat-completion/src/ai-integration.ts
CHANGED
|
@@ -52,7 +52,7 @@ export const AI: Integration<'ai', Record<string, never>, AICommands> = {
|
|
|
52
52
|
const schema = getSchemaByName(schemaName);
|
|
53
53
|
|
|
54
54
|
if (schema) {
|
|
55
|
-
return await generateStructuredDataWithAI(fullPrompt,
|
|
55
|
+
return await generateStructuredDataWithAI(fullPrompt, undefined, {
|
|
56
56
|
schema: schema as z.ZodSchema<T>,
|
|
57
57
|
schemaName,
|
|
58
58
|
schemaDescription: `AI output matching schema '${schemaName}'`,
|
|
@@ -60,7 +60,7 @@ export const AI: Integration<'ai', Record<string, never>, AICommands> = {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
const raw = await generateTextWithAI(fullPrompt,
|
|
63
|
+
const raw = await generateTextWithAI(fullPrompt, undefined, {
|
|
64
64
|
includeTools: true,
|
|
65
65
|
});
|
|
66
66
|
|
|
@@ -5,20 +5,19 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@auto-engineer/flow": "
|
|
9
|
-
"@auto-engineer/ai-gateway": "
|
|
8
|
+
"@auto-engineer/flow": "workspace:*",
|
|
9
|
+
"@auto-engineer/ai-gateway": "workspace:*",
|
|
10
10
|
"axios": "^1.6.0",
|
|
11
11
|
"zod": "^3.22.4"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc",
|
|
15
|
-
"
|
|
16
|
-
"test": "vitest run",
|
|
15
|
+
"test": "vitest run --reporter=dot",
|
|
17
16
|
"lint": "eslint 'src/**/*.ts' --ignore-pattern 'src/generated/**/*' --max-warnings 0 --config ./eslint.config.ts",
|
|
18
17
|
"type-check": "tsc --noEmit",
|
|
19
|
-
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore",
|
|
18
|
+
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn",
|
|
20
19
|
"lint:fix": "eslint 'src/**/*.ts' --ignore-pattern 'src/generated/**/*' --fix --config ./eslint.config.ts",
|
|
21
|
-
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore"
|
|
20
|
+
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn"
|
|
22
21
|
},
|
|
23
22
|
"publishConfig": {
|
|
24
23
|
"access": "public"
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
"clean": "rm -rf dist",
|
|
11
11
|
"dev": "tsx watch src/index.ts",
|
|
12
12
|
"start": "tsx src/index.ts",
|
|
13
|
-
"test": "vitest run",
|
|
13
|
+
"test": "vitest run --reporter=dot",
|
|
14
14
|
"test:watch": "vitest",
|
|
15
15
|
"lint": "eslint 'src/**/*.ts' --max-warnings 0 --config ../../eslint.config.ts",
|
|
16
16
|
"type-check": "tsc --noEmit",
|
|
17
|
-
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore",
|
|
17
|
+
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn",
|
|
18
18
|
"lint:fix": "eslint 'src/**/*.ts' --fix --config ../../eslint.config.ts",
|
|
19
|
-
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore"
|
|
19
|
+
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"cors": "^2.8.5",
|
|
@@ -5,20 +5,20 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@auto-engineer/flow": "
|
|
9
|
-
"@auto-engineer/ai-gateway": "
|
|
8
|
+
"@auto-engineer/flow": "workspace:*",
|
|
9
|
+
"@auto-engineer/ai-gateway": "workspace:*",
|
|
10
10
|
"axios": "^1.6.0",
|
|
11
11
|
"zod": "^3.22.4"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc",
|
|
15
15
|
"dev": "tsc --watch",
|
|
16
|
-
"test": "vitest run",
|
|
16
|
+
"test": "vitest run --reporter=dot",
|
|
17
17
|
"lint": "eslint 'src/**/*.ts' --ignore-pattern 'src/generated/**/*' --max-warnings 0 --config ./eslint.config.ts",
|
|
18
18
|
"type-check": "tsc --noEmit",
|
|
19
|
-
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore",
|
|
19
|
+
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn",
|
|
20
20
|
"lint:fix": "eslint 'src/**/*.ts' --ignore-pattern 'src/generated/**/*' --fix --config ./eslint.config.ts",
|
|
21
|
-
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore"
|
|
21
|
+
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { State, Integration } from '@auto-engineer/flow';
|
|
2
|
-
import { registerTool, z } from '@auto-engineer/ai-gateway';
|
|
3
2
|
|
|
4
3
|
import { createClient } from './generated/product-catalog/client';
|
|
5
4
|
import type {
|
|
@@ -11,12 +10,6 @@ import type {
|
|
|
11
10
|
GetApiProductsByIdResponses,
|
|
12
11
|
GetApiProductsByIdErrors,
|
|
13
12
|
} from './generated/product-catalog';
|
|
14
|
-
import {
|
|
15
|
-
zGetApiProductsResponse,
|
|
16
|
-
zGetApiProductsSearchResponse,
|
|
17
|
-
zGetApiProductsCategoryByCategoryResponse,
|
|
18
|
-
zGetApiProductsByIdResponse,
|
|
19
|
-
} from './generated/product-catalog/zod.gen';
|
|
20
13
|
|
|
21
14
|
export type Product = ProductCatalogItem;
|
|
22
15
|
|
|
@@ -105,128 +98,3 @@ const _ProductCatalog: Integration<'product-catalog', ProductCatalogQueries> = {
|
|
|
105
98
|
},
|
|
106
99
|
},
|
|
107
100
|
};
|
|
108
|
-
|
|
109
|
-
// ---------- Lazy MCP tool registration ----------
|
|
110
|
-
let _toolsRegistered = false;
|
|
111
|
-
|
|
112
|
-
function registerProductCatalogToolsOnce(): void {
|
|
113
|
-
if (_toolsRegistered) return;
|
|
114
|
-
_toolsRegistered = true;
|
|
115
|
-
|
|
116
|
-
// All products
|
|
117
|
-
registerTool<Record<string, unknown>>(
|
|
118
|
-
'PRODUCT_CATALOGUE_PRODUCTS',
|
|
119
|
-
{
|
|
120
|
-
title: 'Get All Products',
|
|
121
|
-
description: 'Fetches all products from the product catalog',
|
|
122
|
-
inputSchema: {},
|
|
123
|
-
schema: zGetApiProductsResponse,
|
|
124
|
-
schemaName: 'GetApiProductsResponse',
|
|
125
|
-
schemaDescription: 'Array of ProductCatalogItem',
|
|
126
|
-
},
|
|
127
|
-
async () => {
|
|
128
|
-
const queries = _ProductCatalog.Queries as ProductCatalogQueries;
|
|
129
|
-
if (!queries?.Products) {
|
|
130
|
-
return {
|
|
131
|
-
content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.Products is not available' }],
|
|
132
|
-
isError: true,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
const result = await queries.Products();
|
|
136
|
-
return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.products, null, 2) }] };
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
// By category
|
|
141
|
-
interface ProductsByCategoryParams extends Record<string, unknown> {
|
|
142
|
-
category: string;
|
|
143
|
-
}
|
|
144
|
-
registerTool<ProductsByCategoryParams>(
|
|
145
|
-
'PRODUCT_CATALOGUE_PRODUCTS_BY_CATEGORY',
|
|
146
|
-
{
|
|
147
|
-
title: 'Get Products by Category',
|
|
148
|
-
description: 'Fetches products from a specific category',
|
|
149
|
-
inputSchema: { category: z.string().min(1, 'Category is required') },
|
|
150
|
-
schema: zGetApiProductsCategoryByCategoryResponse,
|
|
151
|
-
schemaName: 'GetApiProductsCategoryByCategoryResponse',
|
|
152
|
-
schemaDescription: 'Array of ProductCatalogItem',
|
|
153
|
-
},
|
|
154
|
-
async ({ category }) => {
|
|
155
|
-
const queries = _ProductCatalog.Queries as ProductCatalogQueries;
|
|
156
|
-
if (!queries?.ProductsByCategory) {
|
|
157
|
-
return {
|
|
158
|
-
content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.ProductsByCategory is not available' }],
|
|
159
|
-
isError: true,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
const result = await queries.ProductsByCategory({ category });
|
|
163
|
-
return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.products, null, 2) }] };
|
|
164
|
-
},
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
// Search
|
|
168
|
-
interface ProductSearchParams extends Record<string, unknown> {
|
|
169
|
-
query: string;
|
|
170
|
-
}
|
|
171
|
-
registerTool<ProductSearchParams>(
|
|
172
|
-
'PRODUCT_CATALOGUE_SEARCH',
|
|
173
|
-
{
|
|
174
|
-
title: 'Search Products',
|
|
175
|
-
description: 'Search for products using a query string',
|
|
176
|
-
inputSchema: { query: z.string().min(1, 'Search query is required') },
|
|
177
|
-
schema: zGetApiProductsSearchResponse,
|
|
178
|
-
schemaName: 'GetApiProductsSearchResponse',
|
|
179
|
-
schemaDescription: 'Array of ProductCatalogItem',
|
|
180
|
-
},
|
|
181
|
-
async ({ query }) => {
|
|
182
|
-
const queries = _ProductCatalog.Queries as ProductCatalogQueries;
|
|
183
|
-
if (!queries?.ProductSearchResults) {
|
|
184
|
-
return {
|
|
185
|
-
content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.ProductSearchResults is not available' }],
|
|
186
|
-
isError: true,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
const result = await queries.ProductSearchResults({ query });
|
|
190
|
-
return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.products, null, 2) }] };
|
|
191
|
-
},
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
// Details
|
|
195
|
-
interface ProductDetailsParams extends Record<string, unknown> {
|
|
196
|
-
id: string;
|
|
197
|
-
}
|
|
198
|
-
registerTool<ProductDetailsParams>(
|
|
199
|
-
'PRODUCT_CATALOGUE_PRODUCT_DETAILS',
|
|
200
|
-
{
|
|
201
|
-
title: 'Get Product Details',
|
|
202
|
-
description: 'Fetches detailed information about a specific product',
|
|
203
|
-
inputSchema: { id: z.string().min(1, 'Product ID is required') },
|
|
204
|
-
schema: zGetApiProductsByIdResponse,
|
|
205
|
-
schemaName: 'GetApiProductsByIdResponse',
|
|
206
|
-
schemaDescription: 'Single ProductCatalogItem',
|
|
207
|
-
},
|
|
208
|
-
async ({ id }) => {
|
|
209
|
-
const queries = _ProductCatalog.Queries as ProductCatalogQueries;
|
|
210
|
-
if (!queries?.ProductDetails) {
|
|
211
|
-
return {
|
|
212
|
-
content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.ProductDetails is not available' }],
|
|
213
|
-
isError: true,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
const result = await queries.ProductDetails({ id });
|
|
217
|
-
if (result.data.product === null) {
|
|
218
|
-
return { content: [{ type: 'text' as const, text: `Product with ID "${id}" not found` }], isError: true };
|
|
219
|
-
}
|
|
220
|
-
return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.product, null, 2) }] };
|
|
221
|
-
},
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// registers tools on *first usage* of the integration
|
|
226
|
-
export const ProductCatalog: Integration<'product-catalog', ProductCatalogQueries> = new Proxy(_ProductCatalog, {
|
|
227
|
-
get(target, prop, receiver) {
|
|
228
|
-
// First touch of ProductCatalog triggers tool registration
|
|
229
|
-
registerProductCatalogToolsOnce();
|
|
230
|
-
return Reflect.get(target, prop, receiver);
|
|
231
|
-
},
|
|
232
|
-
});
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
"clean": "rm -rf dist",
|
|
11
11
|
"dev": "tsx watch src/index.ts",
|
|
12
12
|
"start": "tsx src/index.ts",
|
|
13
|
-
"test": "vitest run",
|
|
13
|
+
"test": "vitest run --reporter=dot",
|
|
14
14
|
"test:watch": "vitest",
|
|
15
15
|
"lint": "eslint 'src/**/*.ts' --max-warnings 0 --config ../../eslint.config.ts",
|
|
16
16
|
"type-check": "tsc --noEmit",
|
|
17
|
-
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore",
|
|
17
|
+
"format": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn",
|
|
18
18
|
"lint:fix": "eslint 'src/**/*.ts' --fix --config ../../eslint.config.ts",
|
|
19
|
-
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore"
|
|
19
|
+
"format:fix": "prettier --write \"**/*.{js,ts,json,md,yml,yaml}\" --ignore-path ../../.prettierignore --log-level warn"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"cors": "^2.8.5",
|