@htlkg/data 0.0.1 → 0.0.3
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 +53 -0
- package/dist/client/index.d.ts +117 -31
- package/dist/client/index.js +74 -22
- package/dist/client/index.js.map +1 -1
- package/dist/content-collections/index.js +20 -24
- package/dist/content-collections/index.js.map +1 -1
- package/dist/hooks/index.d.ts +113 -5
- package/dist/hooks/index.js +165 -182
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.js +305 -182
- package/dist/index.js.map +1 -1
- package/dist/queries/index.d.ts +78 -1
- package/dist/queries/index.js +47 -0
- package/dist/queries/index.js.map +1 -1
- package/dist/stores/index.d.ts +106 -0
- package/dist/stores/index.js +108 -0
- package/dist/stores/index.js.map +1 -0
- package/package.json +60 -37
- package/src/client/__tests__/server.test.ts +100 -0
- package/src/client/client.md +91 -0
- package/src/client/index.test.ts +232 -0
- package/src/client/index.ts +145 -0
- package/src/client/server.ts +118 -0
- package/src/content-collections/content-collections.md +87 -0
- package/src/content-collections/generator.ts +314 -0
- package/src/content-collections/index.ts +32 -0
- package/src/content-collections/schemas.ts +75 -0
- package/src/content-collections/sync.ts +139 -0
- package/src/hooks/README.md +293 -0
- package/src/hooks/createDataHook.ts +208 -0
- package/src/hooks/data-hook-errors.property.test.ts +270 -0
- package/src/hooks/data-hook-filters.property.test.ts +263 -0
- package/src/hooks/data-hooks.property.test.ts +190 -0
- package/src/hooks/hooks.test.ts +76 -0
- package/src/hooks/index.ts +21 -0
- package/src/hooks/useAccounts.ts +66 -0
- package/src/hooks/useBrands.ts +95 -0
- package/src/hooks/useProducts.ts +88 -0
- package/src/hooks/useUsers.ts +89 -0
- package/src/index.ts +32 -0
- package/src/mutations/accounts.ts +127 -0
- package/src/mutations/brands.ts +133 -0
- package/src/mutations/index.ts +32 -0
- package/src/mutations/mutations.md +96 -0
- package/src/mutations/users.ts +136 -0
- package/src/queries/accounts.ts +121 -0
- package/src/queries/brands.ts +176 -0
- package/src/queries/index.ts +45 -0
- package/src/queries/products.ts +282 -0
- package/src/queries/queries.md +88 -0
- package/src/queries/server-helpers.ts +114 -0
- package/src/queries/users.ts +199 -0
- package/src/stores/createStores.ts +148 -0
- package/src/stores/index.ts +15 -0
- package/src/stores/stores.md +104 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @htlkg/data
|
|
2
|
+
|
|
3
|
+
GraphQL client, queries, mutations, hooks, and stores for Hotelinking applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @htlkg/data
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Modules
|
|
12
|
+
|
|
13
|
+
### [Client](src/client/client.md)
|
|
14
|
+
GraphQL client generation for client-side and server-side data fetching with Amplify.
|
|
15
|
+
|
|
16
|
+
### [Hooks](src/hooks/README.md)
|
|
17
|
+
Vue composables for reactive data management: `useBrands`, `useAccounts`, `useUsers`, `useProducts`.
|
|
18
|
+
|
|
19
|
+
### [Queries](src/queries/queries.md)
|
|
20
|
+
GraphQL query functions for accounts, brands, users, and products.
|
|
21
|
+
|
|
22
|
+
### [Mutations](src/mutations/mutations.md)
|
|
23
|
+
GraphQL mutation functions for creating, updating, and deleting resources.
|
|
24
|
+
|
|
25
|
+
### [Stores](src/stores/stores.md)
|
|
26
|
+
Nanostore factories for request-scoped state management in Astro SSR.
|
|
27
|
+
|
|
28
|
+
### [Content Collections](src/content-collections/content-collections.md)
|
|
29
|
+
Astro content collection generators and schema definitions.
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// Client-side data fetching
|
|
35
|
+
import { getSharedClient } from '@htlkg/data/client';
|
|
36
|
+
import type { Schema } from '@backend/data/resource';
|
|
37
|
+
|
|
38
|
+
const client = getSharedClient<Schema>();
|
|
39
|
+
const { data } = await client.models.Brand.list();
|
|
40
|
+
|
|
41
|
+
// Vue composables
|
|
42
|
+
import { useBrands, useAccounts } from '@htlkg/data/hooks';
|
|
43
|
+
|
|
44
|
+
const { brands, loading, error, refetch } = useBrands({
|
|
45
|
+
accountId: 'account-123',
|
|
46
|
+
activeOnly: true,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Server-side queries
|
|
50
|
+
import { fetchBrands, fetchAccounts } from '@htlkg/data/queries';
|
|
51
|
+
|
|
52
|
+
const brands = await fetchBrands(client, { accountId });
|
|
53
|
+
```
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
|
-
import { AstroCookies } from 'astro';
|
|
2
1
|
import { generateClient as generateClient$1 } from 'aws-amplify/data';
|
|
2
|
+
import { ResourcesConfig } from 'aws-amplify';
|
|
3
|
+
import { AstroGlobal } from 'astro';
|
|
4
|
+
import { CommonPublicClientOptions, DefaultCommonClientOptions, V6ClientSSRCookies } from 'aws-amplify/api/internals';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Server-side data client for Astro
|
|
8
|
+
*
|
|
9
|
+
* Provides a client generator similar to Next.js's generateServerClientUsingCookies
|
|
10
|
+
* using generateClientWithAmplifyInstance for proper server context integration.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
interface AstroCookiesClientParams {
|
|
14
|
+
cookies: AstroGlobal["cookies"];
|
|
15
|
+
request: AstroGlobal["request"];
|
|
16
|
+
config: ResourcesConfig;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Generates a server-side data client for Astro (matches Next.js implementation)
|
|
20
|
+
*
|
|
21
|
+
* This function creates a client that automatically wraps all operations in the Amplify server context,
|
|
22
|
+
* ensuring that authentication tokens from cookies are properly used.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import type { Schema } from '../amplify/data/resource';
|
|
27
|
+
* import { generateServerClientUsingCookies } from '@htlkg/data/client';
|
|
28
|
+
* import { parseAmplifyConfig } from 'aws-amplify/utils';
|
|
29
|
+
* import outputs from '../amplify_outputs.json';
|
|
30
|
+
*
|
|
31
|
+
* const amplifyConfig = parseAmplifyConfig(outputs);
|
|
32
|
+
*
|
|
33
|
+
* const client = generateServerClientUsingCookies<Schema>({
|
|
34
|
+
* config: amplifyConfig,
|
|
35
|
+
* cookies: Astro.cookies,
|
|
36
|
+
* request: Astro.request,
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* // Use the client directly - operations are automatically wrapped
|
|
40
|
+
* const result = await client.models.User.list({
|
|
41
|
+
* selectionSet: ['id', 'email'],
|
|
42
|
+
* limit: 100,
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
declare function generateServerClientUsingCookies<T extends Record<any, any> = never, Options extends CommonPublicClientOptions & AstroCookiesClientParams = DefaultCommonClientOptions & AstroCookiesClientParams>(options: Options): V6ClientSSRCookies<T, Options>;
|
|
3
47
|
|
|
4
48
|
/**
|
|
5
49
|
* GraphQL Client for @htlkg/data
|
|
@@ -8,6 +52,21 @@ import { generateClient as generateClient$1 } from 'aws-amplify/data';
|
|
|
8
52
|
* The server-side functions use the Amplify Astro adapter for proper SSR support.
|
|
9
53
|
*/
|
|
10
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Get or create the shared GraphQL client instance (singleton pattern)
|
|
57
|
+
* Use this for client-side fetching to avoid creating multiple client instances.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const client = getSharedClient<Schema>();
|
|
62
|
+
* const { data } = await client.models.Account.list();
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare function getSharedClient<TSchema extends Record<string, unknown> = Record<string, unknown>>(): ReturnType<typeof generateClient$1<TSchema>>;
|
|
66
|
+
/**
|
|
67
|
+
* Reset the shared client instance (useful for testing or auth state changes)
|
|
68
|
+
*/
|
|
69
|
+
declare function resetSharedClient(): void;
|
|
11
70
|
/**
|
|
12
71
|
* Generate a client-side GraphQL client for use in Vue components and browser contexts
|
|
13
72
|
* This is SSR-safe and should be called within a component's setup function or after hydration
|
|
@@ -23,48 +82,75 @@ import { generateClient as generateClient$1 } from 'aws-amplify/data';
|
|
|
23
82
|
*/
|
|
24
83
|
declare function generateClient<TSchema extends Record<string, unknown> = Record<string, unknown>>(): ReturnType<typeof generateClient$1<TSchema>>;
|
|
25
84
|
/**
|
|
26
|
-
* Configuration for Amplify
|
|
85
|
+
* Configuration for Amplify (matches amplify_outputs.json format)
|
|
86
|
+
*/
|
|
87
|
+
type AstroAmplifyConfig = ResourcesConfig;
|
|
88
|
+
/**
|
|
89
|
+
* Authentication mode for server-side GraphQL client
|
|
90
|
+
*/
|
|
91
|
+
type ServerAuthMode = 'userPool' | 'apiKey';
|
|
92
|
+
/**
|
|
93
|
+
* Options for generating a server-side GraphQL client
|
|
27
94
|
*/
|
|
28
|
-
interface
|
|
29
|
-
API
|
|
30
|
-
|
|
31
|
-
endpoint: string;
|
|
32
|
-
region: string;
|
|
33
|
-
defaultAuthMode: string;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
Auth?: {
|
|
37
|
-
Cognito?: {
|
|
38
|
-
userPoolId: string;
|
|
39
|
-
userPoolClientId: string;
|
|
40
|
-
identityPoolId?: string;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
95
|
+
interface GenerateServerClientOptions {
|
|
96
|
+
/** Authentication mode - 'userPool' (default) uses JWT from cookies, 'apiKey' uses API key */
|
|
97
|
+
authMode?: ServerAuthMode;
|
|
43
98
|
}
|
|
44
99
|
/**
|
|
45
|
-
* Generate a server-side GraphQL client
|
|
46
|
-
* Use this in Astro pages and API routes for server-side GraphQL operations
|
|
100
|
+
* Generate a server-side GraphQL client for use within runWithAmplifyServerContext
|
|
47
101
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
102
|
+
* This function creates a GraphQL client that can be used for server-side data fetching in Astro.
|
|
103
|
+
* It MUST be called within runWithAmplifyServerContext to access JWT tokens from cookies.
|
|
104
|
+
*
|
|
105
|
+
* The client supports two authentication modes:
|
|
106
|
+
* - 'userPool' (default): Uses JWT tokens from cookies (requires runWithAmplifyServerContext)
|
|
107
|
+
* - 'apiKey': Uses API key for public/unauthenticated requests
|
|
108
|
+
*
|
|
109
|
+
* **Important**:
|
|
110
|
+
* - Amplify.configure() must be called once at app startup (e.g., in amplify-server.ts)
|
|
111
|
+
* - This function must be called INSIDE the operation function of runWithAmplifyServerContext
|
|
112
|
+
* - The context automatically provides the token provider that reads JWT tokens from cookies
|
|
51
113
|
*
|
|
52
114
|
* @example
|
|
53
115
|
* ```typescript
|
|
116
|
+
* // In your Astro page
|
|
54
117
|
* import type { Schema } from '../amplify/data/resource';
|
|
55
118
|
* import { generateServerClient } from '@htlkg/data/client';
|
|
119
|
+
* import { createRunWithAmplifyServerContext } from '@htlkg/core/amplify-astro-adapter';
|
|
56
120
|
* import outputs from '../amplify_outputs.json';
|
|
57
121
|
*
|
|
58
|
-
* const
|
|
59
|
-
*
|
|
60
|
-
*
|
|
122
|
+
* const runWithAmplifyServerContext = createRunWithAmplifyServerContext({ config: outputs });
|
|
123
|
+
*
|
|
124
|
+
* // Fetch data with authentication
|
|
125
|
+
* const result = await runWithAmplifyServerContext({
|
|
126
|
+
* astroServerContext: {
|
|
127
|
+
* cookies: Astro.cookies,
|
|
128
|
+
* request: Astro.request
|
|
129
|
+
* },
|
|
130
|
+
* operation: async (contextSpec) => {
|
|
131
|
+
* // Generate client INSIDE the operation
|
|
132
|
+
* const client = generateServerClient<Schema>({ authMode: 'userPool' });
|
|
133
|
+
* return await client.models.User.list();
|
|
134
|
+
* }
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* const users = result.data || [];
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* @example Using API key for public data
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const result = await runWithAmplifyServerContext({
|
|
143
|
+
* astroServerContext: {
|
|
144
|
+
* cookies: Astro.cookies,
|
|
145
|
+
* request: Astro.request
|
|
146
|
+
* },
|
|
147
|
+
* operation: async (contextSpec) => {
|
|
148
|
+
* const client = generateServerClient<Schema>({ authMode: 'apiKey' });
|
|
149
|
+
* return await client.models.Brand.list();
|
|
150
|
+
* }
|
|
61
151
|
* });
|
|
62
|
-
* const { data: brands } = await client.models.Brand.list();
|
|
63
152
|
* ```
|
|
64
153
|
*/
|
|
65
|
-
declare function generateServerClient<TSchema extends Record<string, unknown> = Record<string, unknown>>(options:
|
|
66
|
-
cookies: AstroCookies;
|
|
67
|
-
config: AstroAmplifyConfig;
|
|
68
|
-
}): any;
|
|
154
|
+
declare function generateServerClient<TSchema extends Record<string, unknown> = Record<string, unknown>>(options?: GenerateServerClientOptions): ReturnType<typeof generateClient$1<TSchema>>;
|
|
69
155
|
|
|
70
|
-
export { type AstroAmplifyConfig, generateClient, generateServerClient };
|
|
156
|
+
export { type AstroAmplifyConfig, type GenerateServerClientOptions, type ServerAuthMode, generateClient, generateServerClient, generateServerClientUsingCookies, getSharedClient, resetSharedClient };
|
package/dist/client/index.js
CHANGED
|
@@ -1,33 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __copyProps = (to, from, except, desc) => {
|
|
6
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
-
for (let key of __getOwnPropNames(from))
|
|
8
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
-
}
|
|
11
|
-
return to;
|
|
12
|
-
};
|
|
13
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
1
|
+
// src/client/index.ts
|
|
2
|
+
import { generateClient as generateDataClient } from "aws-amplify/data";
|
|
14
3
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
// src/client/server.ts
|
|
5
|
+
import {
|
|
6
|
+
generateClientWithAmplifyInstance
|
|
7
|
+
} from "aws-amplify/api/internals";
|
|
8
|
+
import { getAmplifyServerContext } from "aws-amplify/adapter-core/internals";
|
|
9
|
+
import { createRunWithAmplifyServerContext, createLogger } from "@htlkg/core/amplify-astro-adapter";
|
|
10
|
+
var log = createLogger("server-client");
|
|
11
|
+
function generateServerClientUsingCookies(options) {
|
|
12
|
+
const runWithAmplifyServerContext = createRunWithAmplifyServerContext({
|
|
13
|
+
config: options.config
|
|
14
|
+
});
|
|
15
|
+
const resourcesConfig = options.config;
|
|
16
|
+
const getAmplify = (fn) => {
|
|
17
|
+
return runWithAmplifyServerContext({
|
|
18
|
+
astroServerContext: {
|
|
19
|
+
cookies: options.cookies,
|
|
20
|
+
request: options.request
|
|
21
|
+
},
|
|
22
|
+
operation: async (contextSpec) => {
|
|
23
|
+
const amplifyInstance = getAmplifyServerContext(contextSpec).amplify;
|
|
24
|
+
try {
|
|
25
|
+
const config = amplifyInstance.getConfig();
|
|
26
|
+
log.debug("Amplify config from instance:", {
|
|
27
|
+
hasAPI: !!config.API,
|
|
28
|
+
hasGraphQL: !!config.API?.GraphQL,
|
|
29
|
+
endpoint: config.API?.GraphQL?.endpoint,
|
|
30
|
+
defaultAuthMode: config.API?.GraphQL?.defaultAuthMode,
|
|
31
|
+
region: config.API?.GraphQL?.region
|
|
32
|
+
});
|
|
33
|
+
const session = await amplifyInstance.Auth.fetchAuthSession();
|
|
34
|
+
log.debug("Auth session:", {
|
|
35
|
+
hasTokens: !!session.tokens,
|
|
36
|
+
hasAccessToken: !!session.tokens?.accessToken,
|
|
37
|
+
hasIdToken: !!session.tokens?.idToken,
|
|
38
|
+
hasCredentials: !!session.credentials
|
|
39
|
+
});
|
|
40
|
+
} catch (e) {
|
|
41
|
+
log.debug("Error fetching session:", e.message);
|
|
42
|
+
}
|
|
43
|
+
return fn(amplifyInstance);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
const {
|
|
48
|
+
cookies: _cookies,
|
|
49
|
+
request: _request,
|
|
50
|
+
config: _config,
|
|
51
|
+
...params
|
|
52
|
+
} = options;
|
|
53
|
+
return generateClientWithAmplifyInstance({
|
|
54
|
+
amplify: getAmplify,
|
|
55
|
+
config: resourcesConfig,
|
|
56
|
+
...params
|
|
57
|
+
});
|
|
58
|
+
}
|
|
19
59
|
|
|
20
60
|
// src/client/index.ts
|
|
61
|
+
var sharedClientInstance = null;
|
|
62
|
+
function getSharedClient() {
|
|
63
|
+
if (!sharedClientInstance) {
|
|
64
|
+
sharedClientInstance = generateDataClient();
|
|
65
|
+
}
|
|
66
|
+
return sharedClientInstance;
|
|
67
|
+
}
|
|
68
|
+
function resetSharedClient() {
|
|
69
|
+
sharedClientInstance = null;
|
|
70
|
+
}
|
|
21
71
|
function generateClient() {
|
|
22
|
-
return (
|
|
72
|
+
return generateDataClient();
|
|
23
73
|
}
|
|
24
74
|
function generateServerClient(options) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
);
|
|
75
|
+
const client = generateDataClient();
|
|
76
|
+
return client;
|
|
28
77
|
}
|
|
29
78
|
export {
|
|
30
79
|
generateClient,
|
|
31
|
-
generateServerClient
|
|
80
|
+
generateServerClient,
|
|
81
|
+
generateServerClientUsingCookies,
|
|
82
|
+
getSharedClient,
|
|
83
|
+
resetSharedClient
|
|
32
84
|
};
|
|
33
85
|
//# sourceMappingURL=index.js.map
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../node_modules/.pnpm/aws-amplify@6.15.8/node_modules/aws-amplify/dist/esm/api/index.mjs","../../src/client/index.ts"],"sourcesContent":["export * from '@aws-amplify/api';\n//# sourceMappingURL=index.mjs.map\n","/**\n * GraphQL Client for @htlkg/data\n *\n * Provides both client-side and server-side GraphQL capabilities using AWS Amplify Data.\n * The server-side functions use the Amplify Astro adapter for proper SSR support.\n */\n\nimport type { AstroCookies } from \"astro\";\nimport { generateClient as generateDataClient } from \"aws-amplify/data\";\n\n/**\n * Generate a client-side GraphQL client for use in Vue components and browser contexts\n * This is SSR-safe and should be called within a component's setup function or after hydration\n *\n * @example\n * ```typescript\n * import type { Schema } from '@backend/data/resource';\n * import { generateClient } from '@htlkg/data/client';\n *\n * const client = generateClient<Schema>();\n * const { data: brands } = await client.models.Brand.list();\n * ```\n */\nexport function generateClient<\n\tTSchema extends Record<string, unknown> = Record<string, unknown>,\n>(): ReturnType<typeof generateDataClient<TSchema>> {\n\treturn generateDataClient<TSchema>();\n}\n\n/**\n * Configuration for Amplify Astro adapter\n */\nexport interface AstroAmplifyConfig {\n\tAPI?: {\n\t\tGraphQL?: {\n\t\t\tendpoint: string;\n\t\t\tregion: string;\n\t\t\tdefaultAuthMode: string;\n\t\t};\n\t};\n\tAuth?: {\n\t\tCognito?: {\n\t\t\tuserPoolId: string;\n\t\t\tuserPoolClientId: string;\n\t\t\tidentityPoolId?: string;\n\t\t};\n\t};\n}\n\n/**\n * Generate a server-side GraphQL client with cookie-based authentication\n * Use this in Astro pages and API routes for server-side GraphQL operations\n *\n * Note: This is a placeholder that will be properly implemented once the\n * Amplify Astro adapter is migrated to the modular architecture.\n * For now, import generateServerClient from @htlkg/shared/lib/graphql directly.\n *\n * @example\n * ```typescript\n * import type { Schema } from '../amplify/data/resource';\n * import { generateServerClient } from '@htlkg/data/client';\n * import outputs from '../amplify_outputs.json';\n *\n * const client = generateServerClient<Schema>({\n * cookies: Astro.cookies,\n * config: outputs\n * });\n * const { data: brands } = await client.models.Brand.list();\n * ```\n */\nexport function generateServerClient<\n\tTSchema extends Record<string, unknown> = Record<string, unknown>,\n>(options: { cookies: AstroCookies; config: AstroAmplifyConfig }): any {\n\tthrow new Error(\n\t\t\"[generateServerClient] Not yet implemented in modular architecture. \" +\n\t\t\"Please use generateServerClient from @htlkg/shared/lib/graphql for now. \" +\n\t\t\"This will be properly implemented when the Amplify Astro adapter is migrated.\",\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc;;;ACuBP,SAAS,iBAEoC;AACnD,aAAO,YAAAA,gBAA4B;AACpC;AA2CO,SAAS,qBAEd,SAAqE;AACtE,QAAM,IAAI;AAAA,IACT;AAAA,EAGD;AACD;","names":["generateDataClient"]}
|
|
1
|
+
{"version":3,"sources":["../../src/client/index.ts","../../src/client/server.ts"],"sourcesContent":["/**\n * GraphQL Client for @htlkg/data\n *\n * Provides both client-side and server-side GraphQL capabilities using AWS Amplify Data.\n * The server-side functions use the Amplify Astro adapter for proper SSR support.\n */\n\nimport { generateClient as generateDataClient } from \"aws-amplify/data\";\nimport type { ResourcesConfig } from \"aws-amplify\";\n\n// Re-export server-side client generation\nexport { generateServerClientUsingCookies } from \"./server\";\n\n// Singleton client instance for client-side fetching\nlet sharedClientInstance: any = null;\n\n/**\n * Get or create the shared GraphQL client instance (singleton pattern)\n * Use this for client-side fetching to avoid creating multiple client instances.\n *\n * @example\n * ```typescript\n * const client = getSharedClient<Schema>();\n * const { data } = await client.models.Account.list();\n * ```\n */\nexport function getSharedClient<\n\tTSchema extends Record<string, unknown> = Record<string, unknown>,\n>(): ReturnType<typeof generateDataClient<TSchema>> {\n\tif (!sharedClientInstance) {\n\t\tsharedClientInstance = generateDataClient<TSchema>();\n\t}\n\treturn sharedClientInstance;\n}\n\n/**\n * Reset the shared client instance (useful for testing or auth state changes)\n */\nexport function resetSharedClient(): void {\n\tsharedClientInstance = null;\n}\n\n/**\n * Generate a client-side GraphQL client for use in Vue components and browser contexts\n * This is SSR-safe and should be called within a component's setup function or after hydration\n *\n * @example\n * ```typescript\n * import type { Schema } from '@backend/data/resource';\n * import { generateClient } from '@htlkg/data/client';\n *\n * const client = generateClient<Schema>();\n * const { data: brands } = await client.models.Brand.list();\n * ```\n */\nexport function generateClient<\n\tTSchema extends Record<string, unknown> = Record<string, unknown>,\n>(): ReturnType<typeof generateDataClient<TSchema>> {\n\treturn generateDataClient<TSchema>();\n}\n\n/**\n * Configuration for Amplify (matches amplify_outputs.json format)\n */\nexport type AstroAmplifyConfig = ResourcesConfig;\n\n/**\n * Authentication mode for server-side GraphQL client\n */\nexport type ServerAuthMode = 'userPool' | 'apiKey';\n\n/**\n * Options for generating a server-side GraphQL client\n */\nexport interface GenerateServerClientOptions {\n\t/** Authentication mode - 'userPool' (default) uses JWT from cookies, 'apiKey' uses API key */\n\tauthMode?: ServerAuthMode;\n}\n\n/**\n * Generate a server-side GraphQL client for use within runWithAmplifyServerContext\n * \n * This function creates a GraphQL client that can be used for server-side data fetching in Astro.\n * It MUST be called within runWithAmplifyServerContext to access JWT tokens from cookies.\n * \n * The client supports two authentication modes:\n * - 'userPool' (default): Uses JWT tokens from cookies (requires runWithAmplifyServerContext)\n * - 'apiKey': Uses API key for public/unauthenticated requests\n *\n * **Important**: \n * - Amplify.configure() must be called once at app startup (e.g., in amplify-server.ts)\n * - This function must be called INSIDE the operation function of runWithAmplifyServerContext\n * - The context automatically provides the token provider that reads JWT tokens from cookies\n *\n * @example\n * ```typescript\n * // In your Astro page\n * import type { Schema } from '../amplify/data/resource';\n * import { generateServerClient } from '@htlkg/data/client';\n * import { createRunWithAmplifyServerContext } from '@htlkg/core/amplify-astro-adapter';\n * import outputs from '../amplify_outputs.json';\n *\n * const runWithAmplifyServerContext = createRunWithAmplifyServerContext({ config: outputs });\n *\n * // Fetch data with authentication\n * const result = await runWithAmplifyServerContext({\n * astroServerContext: {\n * cookies: Astro.cookies,\n * request: Astro.request\n * },\n * operation: async (contextSpec) => {\n * // Generate client INSIDE the operation\n * const client = generateServerClient<Schema>({ authMode: 'userPool' });\n * return await client.models.User.list();\n * }\n * });\n * \n * const users = result.data || [];\n * ```\n * \n * @example Using API key for public data\n * ```typescript\n * const result = await runWithAmplifyServerContext({\n * astroServerContext: {\n * cookies: Astro.cookies,\n * request: Astro.request\n * },\n * operation: async (contextSpec) => {\n * const client = generateServerClient<Schema>({ authMode: 'apiKey' });\n * return await client.models.Brand.list();\n * }\n * });\n * ```\n */\nexport function generateServerClient<\n\tTSchema extends Record<string, unknown> = Record<string, unknown>,\n>(options?: GenerateServerClientOptions): ReturnType<typeof generateDataClient<TSchema>> {\n\t// Generate the client without authMode parameter\n\t// When called within runWithAmplifyServerContext, it will automatically use the token provider\n\t// from the context (which reads JWT tokens from cookies)\n\t// The authMode should be specified per-operation, not at client creation\n\tconst client = generateDataClient<TSchema>();\n\t\n\treturn client;\n}\n","/**\n * Server-side data client for Astro\n *\n * Provides a client generator similar to Next.js's generateServerClientUsingCookies\n * using generateClientWithAmplifyInstance for proper server context integration.\n */\n\nimport type { AstroGlobal } from \"astro\";\nimport type { ResourcesConfig } from \"aws-amplify\";\nimport {\n\tCommonPublicClientOptions,\n\tDefaultCommonClientOptions,\n\tV6ClientSSRCookies,\n\tgenerateClientWithAmplifyInstance,\n} from \"aws-amplify/api/internals\";\nimport { getAmplifyServerContext } from \"aws-amplify/adapter-core/internals\";\nimport { createRunWithAmplifyServerContext, createLogger } from \"@htlkg/core/amplify-astro-adapter\";\n\nconst log = createLogger('server-client');\n\ninterface AstroCookiesClientParams {\n\tcookies: AstroGlobal[\"cookies\"];\n\trequest: AstroGlobal[\"request\"];\n\tconfig: ResourcesConfig;\n}\n\n/**\n * Generates a server-side data client for Astro (matches Next.js implementation)\n *\n * This function creates a client that automatically wraps all operations in the Amplify server context,\n * ensuring that authentication tokens from cookies are properly used.\n *\n * @example\n * ```typescript\n * import type { Schema } from '../amplify/data/resource';\n * import { generateServerClientUsingCookies } from '@htlkg/data/client';\n * import { parseAmplifyConfig } from 'aws-amplify/utils';\n * import outputs from '../amplify_outputs.json';\n *\n * const amplifyConfig = parseAmplifyConfig(outputs);\n *\n * const client = generateServerClientUsingCookies<Schema>({\n * config: amplifyConfig,\n * cookies: Astro.cookies,\n * request: Astro.request,\n * });\n *\n * // Use the client directly - operations are automatically wrapped\n * const result = await client.models.User.list({\n * selectionSet: ['id', 'email'],\n * limit: 100,\n * });\n * ```\n */\nexport function generateServerClientUsingCookies<\n\tT extends Record<any, any> = never,\n\tOptions extends CommonPublicClientOptions &\n\t\tAstroCookiesClientParams = DefaultCommonClientOptions &\n\t\tAstroCookiesClientParams,\n>(options: Options): V6ClientSSRCookies<T, Options> {\n\tconst runWithAmplifyServerContext = createRunWithAmplifyServerContext({\n\t\tconfig: options.config,\n\t});\n\n\tconst resourcesConfig = options.config;\n\n\t// This function reference gets passed down to InternalGraphQLAPI.ts.graphql\n\t// where this._graphql is passed in as the `fn` argument\n\t// causing it to always get invoked inside `runWithAmplifyServerContext`\n\tconst getAmplify = (fn: (amplify: any) => Promise<any>) => {\n\t\treturn runWithAmplifyServerContext({\n\t\t\tastroServerContext: {\n\t\t\t\tcookies: options.cookies,\n\t\t\t\trequest: options.request,\n\t\t\t},\n\t\t\toperation: async (contextSpec: any) => {\n\t\t\t\tconst amplifyInstance = getAmplifyServerContext(contextSpec).amplify;\n\t\t\t\t\n\t\t\t\t// Debug logging (only when DEBUG=true)\n\t\t\t\ttry {\n\t\t\t\t\tconst config = amplifyInstance.getConfig();\n\t\t\t\t\tlog.debug('Amplify config from instance:', {\n\t\t\t\t\t\thasAPI: !!config.API,\n\t\t\t\t\t\thasGraphQL: !!config.API?.GraphQL,\n\t\t\t\t\t\tendpoint: config.API?.GraphQL?.endpoint,\n\t\t\t\t\t\tdefaultAuthMode: config.API?.GraphQL?.defaultAuthMode,\n\t\t\t\t\t\tregion: config.API?.GraphQL?.region,\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tconst session = await amplifyInstance.Auth.fetchAuthSession();\n\t\t\t\t\tlog.debug('Auth session:', {\n\t\t\t\t\t\thasTokens: !!session.tokens,\n\t\t\t\t\t\thasAccessToken: !!session.tokens?.accessToken,\n\t\t\t\t\t\thasIdToken: !!session.tokens?.idToken,\n\t\t\t\t\t\thasCredentials: !!session.credentials,\n\t\t\t\t\t});\n\t\t\t\t} catch (e: any) {\n\t\t\t\t\tlog.debug('Error fetching session:', e.message);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn fn(amplifyInstance);\n\t\t\t},\n\t\t});\n\t};\n\n\tconst {\n\t\tcookies: _cookies,\n\t\trequest: _request,\n\t\tconfig: _config,\n\t\t...params\n\t} = options;\n\n\treturn generateClientWithAmplifyInstance<T, V6ClientSSRCookies<T, Options>>({\n\t\tamplify: getAmplify,\n\t\tconfig: resourcesConfig,\n\t\t...params,\n\t} as any);\n}\n"],"mappings":";AAOA,SAAS,kBAAkB,0BAA0B;;;ACErD;AAAA,EAIC;AAAA,OACM;AACP,SAAS,+BAA+B;AACxC,SAAS,mCAAmC,oBAAoB;AAEhE,IAAM,MAAM,aAAa,eAAe;AAoCjC,SAAS,iCAKd,SAAkD;AACnD,QAAM,8BAA8B,kCAAkC;AAAA,IACrE,QAAQ,QAAQ;AAAA,EACjB,CAAC;AAED,QAAM,kBAAkB,QAAQ;AAKhC,QAAM,aAAa,CAAC,OAAuC;AAC1D,WAAO,4BAA4B;AAAA,MAClC,oBAAoB;AAAA,QACnB,SAAS,QAAQ;AAAA,QACjB,SAAS,QAAQ;AAAA,MAClB;AAAA,MACA,WAAW,OAAO,gBAAqB;AACtC,cAAM,kBAAkB,wBAAwB,WAAW,EAAE;AAG7D,YAAI;AACH,gBAAM,SAAS,gBAAgB,UAAU;AACzC,cAAI,MAAM,iCAAiC;AAAA,YAC1C,QAAQ,CAAC,CAAC,OAAO;AAAA,YACjB,YAAY,CAAC,CAAC,OAAO,KAAK;AAAA,YAC1B,UAAU,OAAO,KAAK,SAAS;AAAA,YAC/B,iBAAiB,OAAO,KAAK,SAAS;AAAA,YACtC,QAAQ,OAAO,KAAK,SAAS;AAAA,UAC9B,CAAC;AAED,gBAAM,UAAU,MAAM,gBAAgB,KAAK,iBAAiB;AAC5D,cAAI,MAAM,iBAAiB;AAAA,YAC1B,WAAW,CAAC,CAAC,QAAQ;AAAA,YACrB,gBAAgB,CAAC,CAAC,QAAQ,QAAQ;AAAA,YAClC,YAAY,CAAC,CAAC,QAAQ,QAAQ;AAAA,YAC9B,gBAAgB,CAAC,CAAC,QAAQ;AAAA,UAC3B,CAAC;AAAA,QACF,SAAS,GAAQ;AAChB,cAAI,MAAM,2BAA2B,EAAE,OAAO;AAAA,QAC/C;AAEA,eAAO,GAAG,eAAe;AAAA,MAC1B;AAAA,IACD,CAAC;AAAA,EACF;AAEA,QAAM;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,GAAG;AAAA,EACJ,IAAI;AAEJ,SAAO,kCAAqE;AAAA,IAC3E,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,GAAG;AAAA,EACJ,CAAQ;AACT;;;ADvGA,IAAI,uBAA4B;AAYzB,SAAS,kBAEoC;AACnD,MAAI,CAAC,sBAAsB;AAC1B,2BAAuB,mBAA4B;AAAA,EACpD;AACA,SAAO;AACR;AAKO,SAAS,oBAA0B;AACzC,yBAAuB;AACxB;AAeO,SAAS,iBAEoC;AACnD,SAAO,mBAA4B;AACpC;AA2EO,SAAS,qBAEd,SAAuF;AAKxF,QAAM,SAAS,mBAA4B;AAE3C,SAAO;AACR;","names":[]}
|
|
@@ -134,6 +134,10 @@ var productSchema = z.object({
|
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
// src/content-collections/generator.ts
|
|
137
|
+
var log = {
|
|
138
|
+
info: (msg) => console.info(`[content-collections] ${msg}`),
|
|
139
|
+
error: (msg) => console.error(`[content-collections] ${msg}`)
|
|
140
|
+
};
|
|
137
141
|
async function generateContentCollections(options) {
|
|
138
142
|
const {
|
|
139
143
|
outputDir = "src/content",
|
|
@@ -156,7 +160,7 @@ async function generateContentCollections(options) {
|
|
|
156
160
|
}
|
|
157
161
|
}
|
|
158
162
|
try {
|
|
159
|
-
|
|
163
|
+
log.info("Fetching brands...");
|
|
160
164
|
const brandsResult = await fetchBrands(options);
|
|
161
165
|
if (brandsResult.errors && !continueOnError) {
|
|
162
166
|
throw new Error(
|
|
@@ -178,26 +182,24 @@ async function generateContentCollections(options) {
|
|
|
178
182
|
result.brands.count++;
|
|
179
183
|
} catch (error) {
|
|
180
184
|
const errorMsg = `Failed to process brand ${brand.id}: ${error.message}`;
|
|
181
|
-
|
|
185
|
+
log.error(errorMsg);
|
|
182
186
|
result.brands.errors.push(errorMsg);
|
|
183
187
|
if (!continueOnError) {
|
|
184
188
|
throw error;
|
|
185
189
|
}
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
|
-
|
|
189
|
-
`[generateContentCollections] Generated ${result.brands.count} brands`
|
|
190
|
-
);
|
|
192
|
+
log.info(`Generated ${result.brands.count} brands`);
|
|
191
193
|
} catch (error) {
|
|
192
194
|
const errorMsg = `Failed to generate brands: ${error.message}`;
|
|
193
|
-
|
|
195
|
+
log.error(errorMsg);
|
|
194
196
|
result.brands.errors.push(errorMsg);
|
|
195
197
|
if (!continueOnError) {
|
|
196
198
|
throw error;
|
|
197
199
|
}
|
|
198
200
|
}
|
|
199
201
|
try {
|
|
200
|
-
|
|
202
|
+
log.info("Fetching accounts...");
|
|
201
203
|
const accountsResult = await fetchAccounts(options);
|
|
202
204
|
if (accountsResult.errors && !continueOnError) {
|
|
203
205
|
throw new Error(
|
|
@@ -219,26 +221,24 @@ async function generateContentCollections(options) {
|
|
|
219
221
|
result.accounts.count++;
|
|
220
222
|
} catch (error) {
|
|
221
223
|
const errorMsg = `Failed to process account ${account.id}: ${error.message}`;
|
|
222
|
-
|
|
224
|
+
log.error(errorMsg);
|
|
223
225
|
result.accounts.errors.push(errorMsg);
|
|
224
226
|
if (!continueOnError) {
|
|
225
227
|
throw error;
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
|
-
|
|
230
|
-
`[generateContentCollections] Generated ${result.accounts.count} accounts`
|
|
231
|
-
);
|
|
231
|
+
log.info(`Generated ${result.accounts.count} accounts`);
|
|
232
232
|
} catch (error) {
|
|
233
233
|
const errorMsg = `Failed to generate accounts: ${error.message}`;
|
|
234
|
-
|
|
234
|
+
log.error(errorMsg);
|
|
235
235
|
result.accounts.errors.push(errorMsg);
|
|
236
236
|
if (!continueOnError) {
|
|
237
237
|
throw error;
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
try {
|
|
241
|
-
|
|
241
|
+
log.info("Fetching product instances...");
|
|
242
242
|
const productInstancesResult = await fetchProductInstances(options);
|
|
243
243
|
if (productInstancesResult.errors && !continueOnError) {
|
|
244
244
|
throw new Error(
|
|
@@ -260,26 +260,24 @@ async function generateContentCollections(options) {
|
|
|
260
260
|
result.productInstances.count++;
|
|
261
261
|
} catch (error) {
|
|
262
262
|
const errorMsg = `Failed to process product instance ${instance.id}: ${error.message}`;
|
|
263
|
-
|
|
263
|
+
log.error(errorMsg);
|
|
264
264
|
result.productInstances.errors.push(errorMsg);
|
|
265
265
|
if (!continueOnError) {
|
|
266
266
|
throw error;
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
-
|
|
271
|
-
`[generateContentCollections] Generated ${result.productInstances.count} product instances`
|
|
272
|
-
);
|
|
270
|
+
log.info(`Generated ${result.productInstances.count} product instances`);
|
|
273
271
|
} catch (error) {
|
|
274
272
|
const errorMsg = `Failed to generate product instances: ${error.message}`;
|
|
275
|
-
|
|
273
|
+
log.error(errorMsg);
|
|
276
274
|
result.productInstances.errors.push(errorMsg);
|
|
277
275
|
if (!continueOnError) {
|
|
278
276
|
throw error;
|
|
279
277
|
}
|
|
280
278
|
}
|
|
281
279
|
try {
|
|
282
|
-
|
|
280
|
+
log.info("Fetching products...");
|
|
283
281
|
const productsResult = await fetchProducts(options);
|
|
284
282
|
if (productsResult.errors && !continueOnError) {
|
|
285
283
|
throw new Error(
|
|
@@ -301,19 +299,17 @@ async function generateContentCollections(options) {
|
|
|
301
299
|
result.products.count++;
|
|
302
300
|
} catch (error) {
|
|
303
301
|
const errorMsg = `Failed to process product ${product.id}: ${error.message}`;
|
|
304
|
-
|
|
302
|
+
log.error(errorMsg);
|
|
305
303
|
result.products.errors.push(errorMsg);
|
|
306
304
|
if (!continueOnError) {
|
|
307
305
|
throw error;
|
|
308
306
|
}
|
|
309
307
|
}
|
|
310
308
|
}
|
|
311
|
-
|
|
312
|
-
`[generateContentCollections] Generated ${result.products.count} products`
|
|
313
|
-
);
|
|
309
|
+
log.info(`Generated ${result.products.count} products`);
|
|
314
310
|
} catch (error) {
|
|
315
311
|
const errorMsg = `Failed to generate products: ${error.message}`;
|
|
316
|
-
|
|
312
|
+
log.error(errorMsg);
|
|
317
313
|
result.products.errors.push(errorMsg);
|
|
318
314
|
if (!continueOnError) {
|
|
319
315
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/content-collections/generator.ts","../../src/content-collections/sync.ts","../../src/content-collections/schemas.ts"],"sourcesContent":["/**\n * Content Collections Generator\n *\n * Generates Astro Content Collections from AppSync data.\n * Fetches brands, accounts, and product instances and writes them as JSON files.\n */\n\nimport { writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n\tfetchBrands,\n\tfetchAccounts,\n\tfetchProductInstances,\n\tfetchProducts,\n\ttype SyncOptions,\n} from \"./sync\";\nimport {\n\tbrandSchema,\n\taccountSchema,\n\tproductInstanceSchema,\n\tproductSchema,\n\ttype BrandData,\n\ttype AccountData,\n\ttype ProductInstanceData,\n\ttype ProductData,\n} from \"./schemas\";\n\nexport interface GeneratorOptions extends SyncOptions {\n\t/** Output directory for content collections (default: 'src/content') */\n\toutputDir?: string;\n\t/** Whether to validate data against schemas (default: true) */\n\tvalidate?: boolean;\n\t/** Whether to continue on errors (default: true) */\n\tcontinueOnError?: boolean;\n}\n\nexport interface GeneratorResult {\n\tbrands: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n\taccounts: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n\tproductInstances: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n\tproducts: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n}\n\n/**\n * Generate Content Collections from AppSync\n *\n * @example\n * ```typescript\n * import { generateContentCollections } from '@htlkg/data/content-collections';\n *\n * const result = await generateContentCollections({\n * apiConfig: {\n * endpoint: process.env.APPSYNC_ENDPOINT,\n * region: 'us-east-1',\n * apiKey: process.env.APPSYNC_API_KEY\n * },\n * outputDir: 'src/content'\n * });\n *\n * console.log(`Generated ${result.brands.count} brands`);\n * ```\n */\nexport async function generateContentCollections(\n\toptions: GeneratorOptions,\n): Promise<GeneratorResult> {\n\tconst {\n\t\toutputDir = \"src/content\",\n\t\tvalidate = true,\n\t\tcontinueOnError = true,\n\t} = options;\n\n\tconst result: GeneratorResult = {\n\t\tbrands: { count: 0, errors: [] },\n\t\taccounts: { count: 0, errors: [] },\n\t\tproductInstances: { count: 0, errors: [] },\n\t\tproducts: { count: 0, errors: [] },\n\t};\n\n\t// Ensure output directories exist\n\tconst brandsDir = join(outputDir, \"brands\");\n\tconst accountsDir = join(outputDir, \"accounts\");\n\tconst productInstancesDir = join(outputDir, \"product-instances\");\n\tconst productsDir = join(outputDir, \"products\");\n\n\tfor (const dir of [brandsDir, accountsDir, productInstancesDir, productsDir]) {\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t}\n\t}\n\n\t// Fetch and generate brands\n\ttry {\n\t\tconsole.log(\"[generateContentCollections] Fetching brands...\");\n\t\tconst brandsResult = await fetchBrands(options);\n\n\t\tif (brandsResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch brands: ${brandsResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (brandsResult.errors) {\n\t\t\tresult.brands.errors.push(\n\t\t\t\t...brandsResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const brand of brandsResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\tbrandSchema.parse(brand);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(brandsDir, `${brand.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(brand, null, 2));\n\t\t\t\tresult.brands.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process brand ${brand.id}: ${(error as Error).message}`;\n\t\t\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\t\t\tresult.brands.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`[generateContentCollections] Generated ${result.brands.count} brands`,\n\t\t);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate brands: ${(error as Error).message}`;\n\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\tresult.brands.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Fetch and generate accounts\n\ttry {\n\t\tconsole.log(\"[generateContentCollections] Fetching accounts...\");\n\t\tconst accountsResult = await fetchAccounts(options);\n\n\t\tif (accountsResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch accounts: ${accountsResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (accountsResult.errors) {\n\t\t\tresult.accounts.errors.push(\n\t\t\t\t...accountsResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const account of accountsResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\taccountSchema.parse(account);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(accountsDir, `${account.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(account, null, 2));\n\t\t\t\tresult.accounts.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process account ${account.id}: ${(error as Error).message}`;\n\t\t\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\t\t\tresult.accounts.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`[generateContentCollections] Generated ${result.accounts.count} accounts`,\n\t\t);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate accounts: ${(error as Error).message}`;\n\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\tresult.accounts.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Fetch and generate product instances\n\ttry {\n\t\tconsole.log(\"[generateContentCollections] Fetching product instances...\");\n\t\tconst productInstancesResult = await fetchProductInstances(options);\n\n\t\tif (productInstancesResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch product instances: ${productInstancesResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (productInstancesResult.errors) {\n\t\t\tresult.productInstances.errors.push(\n\t\t\t\t...productInstancesResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const instance of productInstancesResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\tproductInstanceSchema.parse(instance);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(productInstancesDir, `${instance.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(instance, null, 2));\n\t\t\t\tresult.productInstances.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process product instance ${instance.id}: ${(error as Error).message}`;\n\t\t\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\t\t\tresult.productInstances.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`[generateContentCollections] Generated ${result.productInstances.count} product instances`,\n\t\t);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate product instances: ${(error as Error).message}`;\n\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\tresult.productInstances.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Fetch and generate products\n\ttry {\n\t\tconsole.log(\"[generateContentCollections] Fetching products...\");\n\t\tconst productsResult = await fetchProducts(options);\n\n\t\tif (productsResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch products: ${productsResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (productsResult.errors) {\n\t\t\tresult.products.errors.push(\n\t\t\t\t...productsResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const product of productsResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\tproductSchema.parse(product);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(productsDir, `${product.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(product, null, 2));\n\t\t\t\tresult.products.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process product ${product.id}: ${(error as Error).message}`;\n\t\t\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\t\t\tresult.products.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`[generateContentCollections] Generated ${result.products.count} products`,\n\t\t);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate products: ${(error as Error).message}`;\n\t\tconsole.error(`[generateContentCollections] ${errorMsg}`);\n\t\tresult.products.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Sync data from AppSync (alias for generateContentCollections)\n */\nexport const syncFromAppSync = generateContentCollections;\n","/**\n * AppSync Sync for Content Collections\n *\n * Fetches data from Admin's AppSync API for use in Content Collections.\n */\n\nimport { generateClient } from \"@aws-amplify/api\";\n\nexport interface SyncOptions {\n\t/** AppSync API configuration */\n\tapiConfig: {\n\t\tendpoint: string;\n\t\tregion: string;\n\t\tapiKey?: string;\n\t};\n\t/** Authorization mode (default: 'apiKey') */\n\tauthMode?: \"apiKey\" | \"userPool\" | \"iam\";\n\t/** Limit for list queries */\n\tlimit?: number;\n}\n\nexport interface SyncResult<T> {\n\tdata: T[];\n\terrors: Array<{ message: string }> | null;\n}\n\n/**\n * Fetch brands from AppSync\n */\nexport async function fetchBrands(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.Brand.list({\n\t\t\tlimit: options.limit || 1000,\n\t\t});\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchBrands] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n\n/**\n * Fetch accounts from AppSync\n */\nexport async function fetchAccounts(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.Account.list({\n\t\t\tlimit: options.limit || 1000,\n\t\t});\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchAccounts] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n\n/**\n * Fetch product instances from AppSync\n */\nexport async function fetchProductInstances(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.ProductInstance.list(\n\t\t\t{\n\t\t\t\tlimit: options.limit || 1000,\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchProductInstances] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n\n/**\n * Fetch products from AppSync\n */\nexport async function fetchProducts(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.Product.list({\n\t\t\tlimit: options.limit || 1000,\n\t\t});\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchProducts] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n","/**\n * Zod Schemas for Content Collections\n *\n * Defines validation schemas for brands, accounts, and product instances\n * that will be synced from AppSync to Astro Content Collections.\n */\n\nimport { z } from \"zod\";\n\n/**\n * Brand schema for content collections\n */\nexport const brandSchema = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\taccountId: z.string(),\n\tlogo: z.string().optional(),\n\ttimezone: z.string(),\n\tstatus: z.enum([\"active\", \"inactive\", \"maintenance\", \"suspended\"]),\n\tsettings: z.record(z.any()).optional().default({}),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type BrandData = z.infer<typeof brandSchema>;\n\n/**\n * Account schema for content collections\n */\nexport const accountSchema = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\tlogo: z.string().optional(),\n\tsubscription: z.record(z.any()).optional().default({}),\n\tsettings: z.record(z.any()).optional().default({}),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type AccountData = z.infer<typeof accountSchema>;\n\n/**\n * Product Instance schema for content collections\n */\nexport const productInstanceSchema = z.object({\n\tid: z.string(),\n\tproductId: z.string(),\n\tproductName: z.string(),\n\tbrandId: z.string(),\n\taccountId: z.string(),\n\tenabled: z.boolean(),\n\tconfig: z.record(z.any()).optional().default({}),\n\tversion: z.string(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type ProductInstanceData = z.infer<typeof productInstanceSchema>;\n\n/**\n * Product schema for content collections\n */\nexport const productSchema = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\tversion: z.string(),\n\tschema: z.record(z.any()).optional().default({}),\n\tuiSchema: z.record(z.any()).optional().default({}),\n\tdefaultConfig: z.record(z.any()).optional().default({}),\n\tisActive: z.boolean(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type ProductData = z.infer<typeof productSchema>;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/content-collections/generator.ts","../../src/content-collections/sync.ts","../../src/content-collections/schemas.ts"],"sourcesContent":["/**\n * Content Collections Generator\n *\n * Generates Astro Content Collections from AppSync data.\n * Fetches brands, accounts, and product instances and writes them as JSON files.\n */\n\nimport { writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n\tfetchBrands,\n\tfetchAccounts,\n\tfetchProductInstances,\n\tfetchProducts,\n\ttype SyncOptions,\n} from \"./sync\";\nimport {\n\tbrandSchema,\n\taccountSchema,\n\tproductInstanceSchema,\n\tproductSchema,\n\ttype BrandData,\n\ttype AccountData,\n\ttype ProductInstanceData,\n\ttype ProductData,\n} from \"./schemas\";\n\nconst log = {\n\tinfo: (msg: string) => console.info(`[content-collections] ${msg}`),\n\terror: (msg: string) => console.error(`[content-collections] ${msg}`),\n};\n\nexport interface GeneratorOptions extends SyncOptions {\n\t/** Output directory for content collections (default: 'src/content') */\n\toutputDir?: string;\n\t/** Whether to validate data against schemas (default: true) */\n\tvalidate?: boolean;\n\t/** Whether to continue on errors (default: true) */\n\tcontinueOnError?: boolean;\n}\n\nexport interface GeneratorResult {\n\tbrands: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n\taccounts: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n\tproductInstances: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n\tproducts: {\n\t\tcount: number;\n\t\terrors: string[];\n\t};\n}\n\n/**\n * Generate Content Collections from AppSync\n *\n * @example\n * ```typescript\n * import { generateContentCollections } from '@htlkg/data/content-collections';\n *\n * const result = await generateContentCollections({\n * apiConfig: {\n * endpoint: process.env.APPSYNC_ENDPOINT,\n * region: 'us-east-1',\n * apiKey: process.env.APPSYNC_API_KEY\n * },\n * outputDir: 'src/content'\n * });\n *\n * console.log(`Generated ${result.brands.count} brands`);\n * ```\n */\nexport async function generateContentCollections(\n\toptions: GeneratorOptions,\n): Promise<GeneratorResult> {\n\tconst {\n\t\toutputDir = \"src/content\",\n\t\tvalidate = true,\n\t\tcontinueOnError = true,\n\t} = options;\n\n\tconst result: GeneratorResult = {\n\t\tbrands: { count: 0, errors: [] },\n\t\taccounts: { count: 0, errors: [] },\n\t\tproductInstances: { count: 0, errors: [] },\n\t\tproducts: { count: 0, errors: [] },\n\t};\n\n\t// Ensure output directories exist\n\tconst brandsDir = join(outputDir, \"brands\");\n\tconst accountsDir = join(outputDir, \"accounts\");\n\tconst productInstancesDir = join(outputDir, \"product-instances\");\n\tconst productsDir = join(outputDir, \"products\");\n\n\tfor (const dir of [brandsDir, accountsDir, productInstancesDir, productsDir]) {\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t}\n\t}\n\n\t// Fetch and generate brands\n\ttry {\n\t\tlog.info(\"Fetching brands...\");\n\t\tconst brandsResult = await fetchBrands(options);\n\n\t\tif (brandsResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch brands: ${brandsResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (brandsResult.errors) {\n\t\t\tresult.brands.errors.push(\n\t\t\t\t...brandsResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const brand of brandsResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\tbrandSchema.parse(brand);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(brandsDir, `${brand.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(brand, null, 2));\n\t\t\t\tresult.brands.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process brand ${brand.id}: ${(error as Error).message}`;\n\t\t\t\tlog.error(errorMsg);\n\t\t\t\tresult.brands.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlog.info(`Generated ${result.brands.count} brands`);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate brands: ${(error as Error).message}`;\n\t\tlog.error(errorMsg);\n\t\tresult.brands.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Fetch and generate accounts\n\ttry {\n\t\tlog.info(\"Fetching accounts...\");\n\t\tconst accountsResult = await fetchAccounts(options);\n\n\t\tif (accountsResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch accounts: ${accountsResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (accountsResult.errors) {\n\t\t\tresult.accounts.errors.push(\n\t\t\t\t...accountsResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const account of accountsResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\taccountSchema.parse(account);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(accountsDir, `${account.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(account, null, 2));\n\t\t\t\tresult.accounts.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process account ${account.id}: ${(error as Error).message}`;\n\t\t\t\tlog.error(errorMsg);\n\t\t\t\tresult.accounts.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlog.info(`Generated ${result.accounts.count} accounts`);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate accounts: ${(error as Error).message}`;\n\t\tlog.error(errorMsg);\n\t\tresult.accounts.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Fetch and generate product instances\n\ttry {\n\t\tlog.info(\"Fetching product instances...\");\n\t\tconst productInstancesResult = await fetchProductInstances(options);\n\n\t\tif (productInstancesResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch product instances: ${productInstancesResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (productInstancesResult.errors) {\n\t\t\tresult.productInstances.errors.push(\n\t\t\t\t...productInstancesResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const instance of productInstancesResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\tproductInstanceSchema.parse(instance);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(productInstancesDir, `${instance.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(instance, null, 2));\n\t\t\t\tresult.productInstances.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process product instance ${instance.id}: ${(error as Error).message}`;\n\t\t\t\tlog.error(errorMsg);\n\t\t\t\tresult.productInstances.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlog.info(`Generated ${result.productInstances.count} product instances`);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate product instances: ${(error as Error).message}`;\n\t\tlog.error(errorMsg);\n\t\tresult.productInstances.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Fetch and generate products\n\ttry {\n\t\tlog.info(\"Fetching products...\");\n\t\tconst productsResult = await fetchProducts(options);\n\n\t\tif (productsResult.errors && !continueOnError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to fetch products: ${productsResult.errors[0]?.message}`,\n\t\t\t);\n\t\t}\n\n\t\tif (productsResult.errors) {\n\t\t\tresult.products.errors.push(\n\t\t\t\t...productsResult.errors.map((e) => e.message),\n\t\t\t);\n\t\t}\n\n\t\tfor (const product of productsResult.data) {\n\t\t\ttry {\n\t\t\t\t// Validate if enabled\n\t\t\t\tif (validate) {\n\t\t\t\t\tproductSchema.parse(product);\n\t\t\t\t}\n\n\t\t\t\t// Write JSON file\n\t\t\t\tconst filename = join(productsDir, `${product.id}.json`);\n\t\t\t\twriteFileSync(filename, JSON.stringify(product, null, 2));\n\t\t\t\tresult.products.count++;\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMsg = `Failed to process product ${product.id}: ${(error as Error).message}`;\n\t\t\t\tlog.error(errorMsg);\n\t\t\t\tresult.products.errors.push(errorMsg);\n\n\t\t\t\tif (!continueOnError) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlog.info(`Generated ${result.products.count} products`);\n\t} catch (error) {\n\t\tconst errorMsg = `Failed to generate products: ${(error as Error).message}`;\n\t\tlog.error(errorMsg);\n\t\tresult.products.errors.push(errorMsg);\n\n\t\tif (!continueOnError) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Sync data from AppSync (alias for generateContentCollections)\n */\nexport const syncFromAppSync = generateContentCollections;\n","/**\n * AppSync Sync for Content Collections\n *\n * Fetches data from Admin's AppSync API for use in Content Collections.\n */\n\nimport { generateClient } from \"@aws-amplify/api\";\n\nexport interface SyncOptions {\n\t/** AppSync API configuration */\n\tapiConfig: {\n\t\tendpoint: string;\n\t\tregion: string;\n\t\tapiKey?: string;\n\t};\n\t/** Authorization mode (default: 'apiKey') */\n\tauthMode?: \"apiKey\" | \"userPool\" | \"iam\";\n\t/** Limit for list queries */\n\tlimit?: number;\n}\n\nexport interface SyncResult<T> {\n\tdata: T[];\n\terrors: Array<{ message: string }> | null;\n}\n\n/**\n * Fetch brands from AppSync\n */\nexport async function fetchBrands(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.Brand.list({\n\t\t\tlimit: options.limit || 1000,\n\t\t});\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchBrands] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n\n/**\n * Fetch accounts from AppSync\n */\nexport async function fetchAccounts(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.Account.list({\n\t\t\tlimit: options.limit || 1000,\n\t\t});\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchAccounts] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n\n/**\n * Fetch product instances from AppSync\n */\nexport async function fetchProductInstances(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.ProductInstance.list(\n\t\t\t{\n\t\t\t\tlimit: options.limit || 1000,\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchProductInstances] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n\n/**\n * Fetch products from AppSync\n */\nexport async function fetchProducts(\n\toptions: SyncOptions,\n): Promise<SyncResult<any>> {\n\ttry {\n\t\tconst client = generateClient({\n\t\t\tauthMode: options.authMode || \"apiKey\",\n\t\t});\n\n\t\tconst { data, errors } = await (client as any).models.Product.list({\n\t\t\tlimit: options.limit || 1000,\n\t\t});\n\n\t\treturn {\n\t\t\tdata: data || [],\n\t\t\terrors: errors || null,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[fetchProducts] Error:\", error);\n\t\treturn {\n\t\t\tdata: [],\n\t\t\terrors: [{ message: (error as Error).message }],\n\t\t};\n\t}\n}\n","/**\n * Zod Schemas for Content Collections\n *\n * Defines validation schemas for brands, accounts, and product instances\n * that will be synced from AppSync to Astro Content Collections.\n */\n\nimport { z } from \"zod\";\n\n/**\n * Brand schema for content collections\n */\nexport const brandSchema = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\taccountId: z.string(),\n\tlogo: z.string().optional(),\n\ttimezone: z.string(),\n\tstatus: z.enum([\"active\", \"inactive\", \"maintenance\", \"suspended\"]),\n\tsettings: z.record(z.any()).optional().default({}),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type BrandData = z.infer<typeof brandSchema>;\n\n/**\n * Account schema for content collections\n */\nexport const accountSchema = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\tlogo: z.string().optional(),\n\tsubscription: z.record(z.any()).optional().default({}),\n\tsettings: z.record(z.any()).optional().default({}),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type AccountData = z.infer<typeof accountSchema>;\n\n/**\n * Product Instance schema for content collections\n */\nexport const productInstanceSchema = z.object({\n\tid: z.string(),\n\tproductId: z.string(),\n\tproductName: z.string(),\n\tbrandId: z.string(),\n\taccountId: z.string(),\n\tenabled: z.boolean(),\n\tconfig: z.record(z.any()).optional().default({}),\n\tversion: z.string(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type ProductInstanceData = z.infer<typeof productInstanceSchema>;\n\n/**\n * Product schema for content collections\n */\nexport const productSchema = z.object({\n\tid: z.string(),\n\tname: z.string(),\n\tversion: z.string(),\n\tschema: z.record(z.any()).optional().default({}),\n\tuiSchema: z.record(z.any()).optional().default({}),\n\tdefaultConfig: z.record(z.any()).optional().default({}),\n\tisActive: z.boolean(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport type ProductData = z.infer<typeof productSchema>;\n"],"mappings":";AAOA,SAAS,eAAe,WAAW,kBAAkB;AACrD,SAAS,YAAY;;;ACFrB,SAAS,sBAAsB;AAuB/B,eAAsB,YACrB,SAC2B;AAC3B,MAAI;AACH,UAAM,SAAS,eAAe;AAAA,MAC7B,UAAU,QAAQ,YAAY;AAAA,IAC/B,CAAC;AAED,UAAM,EAAE,MAAM,OAAO,IAAI,MAAO,OAAe,OAAO,MAAM,KAAK;AAAA,MAChE,OAAO,QAAQ,SAAS;AAAA,IACzB,CAAC;AAED,WAAO;AAAA,MACN,MAAM,QAAQ,CAAC;AAAA,MACf,QAAQ,UAAU;AAAA,IACnB;AAAA,EACD,SAAS,OAAO;AACf,YAAQ,MAAM,wBAAwB,KAAK;AAC3C,WAAO;AAAA,MACN,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,EAAE,SAAU,MAAgB,QAAQ,CAAC;AAAA,IAC/C;AAAA,EACD;AACD;AAKA,eAAsB,cACrB,SAC2B;AAC3B,MAAI;AACH,UAAM,SAAS,eAAe;AAAA,MAC7B,UAAU,QAAQ,YAAY;AAAA,IAC/B,CAAC;AAED,UAAM,EAAE,MAAM,OAAO,IAAI,MAAO,OAAe,OAAO,QAAQ,KAAK;AAAA,MAClE,OAAO,QAAQ,SAAS;AAAA,IACzB,CAAC;AAED,WAAO;AAAA,MACN,MAAM,QAAQ,CAAC;AAAA,MACf,QAAQ,UAAU;AAAA,IACnB;AAAA,EACD,SAAS,OAAO;AACf,YAAQ,MAAM,0BAA0B,KAAK;AAC7C,WAAO;AAAA,MACN,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,EAAE,SAAU,MAAgB,QAAQ,CAAC;AAAA,IAC/C;AAAA,EACD;AACD;AAKA,eAAsB,sBACrB,SAC2B;AAC3B,MAAI;AACH,UAAM,SAAS,eAAe;AAAA,MAC7B,UAAU,QAAQ,YAAY;AAAA,IAC/B,CAAC;AAED,UAAM,EAAE,MAAM,OAAO,IAAI,MAAO,OAAe,OAAO,gBAAgB;AAAA,MACrE;AAAA,QACC,OAAO,QAAQ,SAAS;AAAA,MACzB;AAAA,IACD;AAEA,WAAO;AAAA,MACN,MAAM,QAAQ,CAAC;AAAA,MACf,QAAQ,UAAU;AAAA,IACnB;AAAA,EACD,SAAS,OAAO;AACf,YAAQ,MAAM,kCAAkC,KAAK;AACrD,WAAO;AAAA,MACN,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,EAAE,SAAU,MAAgB,QAAQ,CAAC;AAAA,IAC/C;AAAA,EACD;AACD;AAKA,eAAsB,cACrB,SAC2B;AAC3B,MAAI;AACH,UAAM,SAAS,eAAe;AAAA,MAC7B,UAAU,QAAQ,YAAY;AAAA,IAC/B,CAAC;AAED,UAAM,EAAE,MAAM,OAAO,IAAI,MAAO,OAAe,OAAO,QAAQ,KAAK;AAAA,MAClE,OAAO,QAAQ,SAAS;AAAA,IACzB,CAAC;AAED,WAAO;AAAA,MACN,MAAM,QAAQ,CAAC;AAAA,MACf,QAAQ,UAAU;AAAA,IACnB;AAAA,EACD,SAAS,OAAO;AACf,YAAQ,MAAM,0BAA0B,KAAK;AAC7C,WAAO;AAAA,MACN,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,EAAE,SAAU,MAAgB,QAAQ,CAAC;AAAA,IAC/C;AAAA,EACD;AACD;;;ACnIA,SAAS,SAAS;AAKX,IAAM,cAAc,EAAE,OAAO;AAAA,EACnC,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO;AAAA,EACf,WAAW,EAAE,OAAO;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,UAAU,EAAE,OAAO;AAAA,EACnB,QAAQ,EAAE,KAAK,CAAC,UAAU,YAAY,eAAe,WAAW,CAAC;AAAA,EACjE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACjD,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AAOM,IAAM,gBAAgB,EAAE,OAAO;AAAA,EACrC,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACrD,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACjD,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AAOM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC7C,IAAI,EAAE,OAAO;AAAA,EACb,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AAAA,EACtB,SAAS,EAAE,OAAO;AAAA,EAClB,WAAW,EAAE,OAAO;AAAA,EACpB,SAAS,EAAE,QAAQ;AAAA,EACnB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC/C,SAAS,EAAE,OAAO;AAAA,EAClB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AAOM,IAAM,gBAAgB,EAAE,OAAO;AAAA,EACrC,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,EAAE,OAAO;AAAA,EAClB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC/C,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACjD,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACtD,UAAU,EAAE,QAAQ;AAAA,EACpB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;;;AF7CD,IAAM,MAAM;AAAA,EACX,MAAM,CAAC,QAAgB,QAAQ,KAAK,yBAAyB,GAAG,EAAE;AAAA,EAClE,OAAO,CAAC,QAAgB,QAAQ,MAAM,yBAAyB,GAAG,EAAE;AACrE;AAiDA,eAAsB,2BACrB,SAC2B;AAC3B,QAAM;AAAA,IACL,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,kBAAkB;AAAA,EACnB,IAAI;AAEJ,QAAM,SAA0B;AAAA,IAC/B,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC,EAAE;AAAA,IAC/B,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAC,EAAE;AAAA,IACjC,kBAAkB,EAAE,OAAO,GAAG,QAAQ,CAAC,EAAE;AAAA,IACzC,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAC,EAAE;AAAA,EAClC;AAGA,QAAM,YAAY,KAAK,WAAW,QAAQ;AAC1C,QAAM,cAAc,KAAK,WAAW,UAAU;AAC9C,QAAM,sBAAsB,KAAK,WAAW,mBAAmB;AAC/D,QAAM,cAAc,KAAK,WAAW,UAAU;AAE9C,aAAW,OAAO,CAAC,WAAW,aAAa,qBAAqB,WAAW,GAAG;AAC7E,QAAI,CAAC,WAAW,GAAG,GAAG;AACrB,gBAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACnC;AAAA,EACD;AAGA,MAAI;AACH,QAAI,KAAK,oBAAoB;AAC7B,UAAM,eAAe,MAAM,YAAY,OAAO;AAE9C,QAAI,aAAa,UAAU,CAAC,iBAAiB;AAC5C,YAAM,IAAI;AAAA,QACT,2BAA2B,aAAa,OAAO,CAAC,GAAG,OAAO;AAAA,MAC3D;AAAA,IACD;AAEA,QAAI,aAAa,QAAQ;AACxB,aAAO,OAAO,OAAO;AAAA,QACpB,GAAG,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,MAC5C;AAAA,IACD;AAEA,eAAW,SAAS,aAAa,MAAM;AACtC,UAAI;AAEH,YAAI,UAAU;AACb,sBAAY,MAAM,KAAK;AAAA,QACxB;AAGA,cAAM,WAAW,KAAK,WAAW,GAAG,MAAM,EAAE,OAAO;AACnD,sBAAc,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AACtD,eAAO,OAAO;AAAA,MACf,SAAS,OAAO;AACf,cAAM,WAAW,2BAA2B,MAAM,EAAE,KAAM,MAAgB,OAAO;AACjF,YAAI,MAAM,QAAQ;AAClB,eAAO,OAAO,OAAO,KAAK,QAAQ;AAElC,YAAI,CAAC,iBAAiB;AACrB,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,aAAa,OAAO,OAAO,KAAK,SAAS;AAAA,EACnD,SAAS,OAAO;AACf,UAAM,WAAW,8BAA+B,MAAgB,OAAO;AACvE,QAAI,MAAM,QAAQ;AAClB,WAAO,OAAO,OAAO,KAAK,QAAQ;AAElC,QAAI,CAAC,iBAAiB;AACrB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACH,QAAI,KAAK,sBAAsB;AAC/B,UAAM,iBAAiB,MAAM,cAAc,OAAO;AAElD,QAAI,eAAe,UAAU,CAAC,iBAAiB;AAC9C,YAAM,IAAI;AAAA,QACT,6BAA6B,eAAe,OAAO,CAAC,GAAG,OAAO;AAAA,MAC/D;AAAA,IACD;AAEA,QAAI,eAAe,QAAQ;AAC1B,aAAO,SAAS,OAAO;AAAA,QACtB,GAAG,eAAe,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,MAC9C;AAAA,IACD;AAEA,eAAW,WAAW,eAAe,MAAM;AAC1C,UAAI;AAEH,YAAI,UAAU;AACb,wBAAc,MAAM,OAAO;AAAA,QAC5B;AAGA,cAAM,WAAW,KAAK,aAAa,GAAG,QAAQ,EAAE,OAAO;AACvD,sBAAc,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AACxD,eAAO,SAAS;AAAA,MACjB,SAAS,OAAO;AACf,cAAM,WAAW,6BAA6B,QAAQ,EAAE,KAAM,MAAgB,OAAO;AACrF,YAAI,MAAM,QAAQ;AAClB,eAAO,SAAS,OAAO,KAAK,QAAQ;AAEpC,YAAI,CAAC,iBAAiB;AACrB,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,aAAa,OAAO,SAAS,KAAK,WAAW;AAAA,EACvD,SAAS,OAAO;AACf,UAAM,WAAW,gCAAiC,MAAgB,OAAO;AACzE,QAAI,MAAM,QAAQ;AAClB,WAAO,SAAS,OAAO,KAAK,QAAQ;AAEpC,QAAI,CAAC,iBAAiB;AACrB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACH,QAAI,KAAK,+BAA+B;AACxC,UAAM,yBAAyB,MAAM,sBAAsB,OAAO;AAElE,QAAI,uBAAuB,UAAU,CAAC,iBAAiB;AACtD,YAAM,IAAI;AAAA,QACT,sCAAsC,uBAAuB,OAAO,CAAC,GAAG,OAAO;AAAA,MAChF;AAAA,IACD;AAEA,QAAI,uBAAuB,QAAQ;AAClC,aAAO,iBAAiB,OAAO;AAAA,QAC9B,GAAG,uBAAuB,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,MACtD;AAAA,IACD;AAEA,eAAW,YAAY,uBAAuB,MAAM;AACnD,UAAI;AAEH,YAAI,UAAU;AACb,gCAAsB,MAAM,QAAQ;AAAA,QACrC;AAGA,cAAM,WAAW,KAAK,qBAAqB,GAAG,SAAS,EAAE,OAAO;AAChE,sBAAc,UAAU,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AACzD,eAAO,iBAAiB;AAAA,MACzB,SAAS,OAAO;AACf,cAAM,WAAW,sCAAsC,SAAS,EAAE,KAAM,MAAgB,OAAO;AAC/F,YAAI,MAAM,QAAQ;AAClB,eAAO,iBAAiB,OAAO,KAAK,QAAQ;AAE5C,YAAI,CAAC,iBAAiB;AACrB,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,aAAa,OAAO,iBAAiB,KAAK,oBAAoB;AAAA,EACxE,SAAS,OAAO;AACf,UAAM,WAAW,yCAA0C,MAAgB,OAAO;AAClF,QAAI,MAAM,QAAQ;AAClB,WAAO,iBAAiB,OAAO,KAAK,QAAQ;AAE5C,QAAI,CAAC,iBAAiB;AACrB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACH,QAAI,KAAK,sBAAsB;AAC/B,UAAM,iBAAiB,MAAM,cAAc,OAAO;AAElD,QAAI,eAAe,UAAU,CAAC,iBAAiB;AAC9C,YAAM,IAAI;AAAA,QACT,6BAA6B,eAAe,OAAO,CAAC,GAAG,OAAO;AAAA,MAC/D;AAAA,IACD;AAEA,QAAI,eAAe,QAAQ;AAC1B,aAAO,SAAS,OAAO;AAAA,QACtB,GAAG,eAAe,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,MAC9C;AAAA,IACD;AAEA,eAAW,WAAW,eAAe,MAAM;AAC1C,UAAI;AAEH,YAAI,UAAU;AACb,wBAAc,MAAM,OAAO;AAAA,QAC5B;AAGA,cAAM,WAAW,KAAK,aAAa,GAAG,QAAQ,EAAE,OAAO;AACvD,sBAAc,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AACxD,eAAO,SAAS;AAAA,MACjB,SAAS,OAAO;AACf,cAAM,WAAW,6BAA6B,QAAQ,EAAE,KAAM,MAAgB,OAAO;AACrF,YAAI,MAAM,QAAQ;AAClB,eAAO,SAAS,OAAO,KAAK,QAAQ;AAEpC,YAAI,CAAC,iBAAiB;AACrB,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,aAAa,OAAO,SAAS,KAAK,WAAW;AAAA,EACvD,SAAS,OAAO;AACf,UAAM,WAAW,gCAAiC,MAAgB,OAAO;AACzE,QAAI,MAAM,QAAQ;AAClB,WAAO,SAAS,OAAO,KAAK,QAAQ;AAEpC,QAAI,CAAC,iBAAiB;AACrB,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO;AACR;AAKO,IAAM,kBAAkB;","names":[]}
|