@intrig/plugin-next 0.0.2-2 → 0.0.2-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.
Files changed (3) hide show
  1. package/dist/index.cjs +287 -37
  2. package/dist/index.js +287 -37
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -8,6 +8,7 @@ var fsx = require('fs-extra');
8
8
  var mimeType = require('mime-types');
9
9
  var _ = require('lodash');
10
10
  var fs = require('fs');
11
+ var chalk = require('chalk');
11
12
 
12
13
  function _interopNamespaceDefault(e) {
13
14
  var n = Object.create(null);
@@ -1650,6 +1651,7 @@ function providerHooksTemplate() {
1650
1651
  useMemo,
1651
1652
  useState,
1652
1653
  useRef,
1654
+ useEffect,
1653
1655
  } from 'react';
1654
1656
  import {
1655
1657
  ErrorState,
@@ -1693,6 +1695,16 @@ export function useNetworkState<T>({
1693
1695
  const context = useContext(Context);
1694
1696
 
1695
1697
  const [abortController, setAbortController] = useState<AbortController>();
1698
+
1699
+ const contextRef = useRef(context);
1700
+ const schemaRef = useRef(schema);
1701
+ const errorSchemaRef = useRef(errorSchema);
1702
+
1703
+ useEffect(() => {
1704
+ contextRef.current = context;
1705
+ schemaRef.current = schema;
1706
+ errorSchemaRef.current = errorSchema;
1707
+ });
1696
1708
 
1697
1709
  const networkState = useMemo(() => {
1698
1710
  logger.info(${"`Updating status ${key} ${operation} ${source}`"});
@@ -1701,7 +1713,7 @@ export function useNetworkState<T>({
1701
1713
  (context.state?.[${"`${source}:${operation}:${key}`"}] as NetworkState<T>) ??
1702
1714
  init()
1703
1715
  );
1704
- }, [JSON.stringify(context.state?.[${"`${source}:${operation}:${key}`"}])]);
1716
+ }, [context.state, key, operation, source]);
1705
1717
 
1706
1718
  const dispatch = useCallback(
1707
1719
  (state: NetworkState<T>) => {
@@ -1749,30 +1761,30 @@ export function useNetworkState<T>({
1749
1761
  signal: abortController.signal,
1750
1762
  };
1751
1763
 
1752
- await context.execute(
1764
+ await contextRef.current.execute(
1753
1765
  requestConfig,
1754
1766
  dispatch,
1755
- schema,
1756
- errorSchema as any,
1767
+ schemaRef.current,
1768
+ errorSchemaRef.current as any,
1757
1769
  );
1758
1770
  },
1759
- [networkState, context.dispatch],
1771
+ [dispatch, key, operation, source],
1760
1772
  );
1761
1773
 
1762
1774
  const deboundedExecute = useMemo(
1763
- () => debounce(execute, debounceDelay ?? 0),
1764
- [execute],
1775
+ () => debounce(execute, debounceDelay),
1776
+ [execute, debounceDelay],
1765
1777
  );
1766
1778
 
1767
1779
  const clear = useCallback(() => {
1768
1780
  logger.info(${"`Clearing request ${key} ${operation} ${source}`"});
1769
1781
  dispatch(init());
1770
- setAbortController((abortController) => {
1782
+ setAbortController((prev) => {
1771
1783
  logger.info(${"`Aborting request ${key} ${operation} ${source}`"});
1772
- abortController?.abort();
1784
+ prev?.abort();
1773
1785
  return undefined;
1774
1786
  });
1775
- }, [dispatch, abortController]);
1787
+ }, [dispatch, key, operation, source]);
1776
1788
 
1777
1789
  return [networkState, deboundedExecute, clear, dispatch];
1778
1790
  }
@@ -1789,6 +1801,14 @@ export function useTransitionCall<T>({
1789
1801
  }): [(request: RequestType) => Promise<T>, () => void] {
1790
1802
  const ctx = useContext(Context);
1791
1803
  const controller = useRef<AbortController | undefined>(undefined);
1804
+
1805
+ const schemaRef = useRef(schema);
1806
+ const errorSchemaRef = useRef(errorSchema);
1807
+
1808
+ useEffect(() => {
1809
+ schemaRef.current = schema;
1810
+ errorSchemaRef.current = errorSchema;
1811
+ });
1792
1812
 
1793
1813
  const call = useCallback(
1794
1814
  async (request: RequestType) => {
@@ -1806,12 +1826,12 @@ export function useTransitionCall<T>({
1806
1826
  reject(state.error);
1807
1827
  }
1808
1828
  },
1809
- schema,
1810
- errorSchema,
1829
+ schemaRef.current,
1830
+ errorSchemaRef.current,
1811
1831
  );
1812
1832
  });
1813
1833
  },
1814
- [ctx, schema, errorSchema],
1834
+ [ctx],
1815
1835
  );
1816
1836
 
1817
1837
  const abort = useCallback(() => {
@@ -2447,7 +2467,7 @@ async function requestHookTemplate({ source, data: { paths, operationId, respons
2447
2467
  const modifiedRequestUrl = `${requestUrl == null ? void 0 : requestUrl.replace(/\{/g, "${")}`;
2448
2468
  const imports = new Set();
2449
2469
  imports.add(`import { z } from 'zod'`);
2450
- imports.add(`import { useCallback, useEffect } from 'react'`);
2470
+ imports.add(`import { useCallback, useEffect, useRef } from 'react'`);
2451
2471
  imports.add(`import {useNetworkState, NetworkState, DispatchState, error, successfulDispatch, validationError, encode, requestValidationError} from "@intrig/react"`);
2452
2472
  const { hookShape, optionsShape } = extractHookShapeAndOptionsShape$1(response, requestBody, imports);
2453
2473
  const { paramExpression, paramType } = extractParamDeconstruction$3(variables != null ? variables : [], requestBody);
@@ -2500,6 +2520,11 @@ async function requestHookTemplate({ source, data: { paths, operationId, respons
2500
2520
  schema,
2501
2521
  errorSchema
2502
2522
  });
2523
+
2524
+ const optionsRef = useRef(options);
2525
+ useEffect(() => {
2526
+ optionsRef.current = options;
2527
+ });
2503
2528
 
2504
2529
  const doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
2505
2530
  const { ${paramExplode}} = p
@@ -2525,22 +2550,22 @@ async function requestHookTemplate({ source, data: { paths, operationId, respons
2525
2550
  ${responseTypePart()}
2526
2551
  })
2527
2552
  return successfulDispatch();
2528
- }, [dispatch])
2553
+ }, [dispatch, dispatchState])
2529
2554
 
2530
2555
  useEffect(() => {
2531
- if (options.fetchOnMount) {
2556
+ if (optionsRef.current.fetchOnMount) {
2532
2557
  doExecute(${[
2533
- requestBody ? `options.body!` : undefined,
2534
- "options.params!"
2558
+ requestBody ? `optionsRef.current.body!` : undefined,
2559
+ "optionsRef.current.params!"
2535
2560
  ].filter((a)=>a).join(",")});
2536
2561
  }
2537
2562
 
2538
2563
  return () => {
2539
- if (options.clearOnUnmount) {
2564
+ if (optionsRef.current.clearOnUnmount) {
2540
2565
  clear();
2541
2566
  }
2542
2567
  }
2543
- }, [])
2568
+ }, [doExecute, clear])
2544
2569
 
2545
2570
  return [
2546
2571
  state,
@@ -2837,7 +2862,7 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2837
2862
  const modifiedRequestUrl = `${requestUrl == null ? void 0 : requestUrl.replace(/\{/g, "${")}`;
2838
2863
  const imports = new Set();
2839
2864
  imports.add(`import { z } from 'zod'`);
2840
- imports.add(`import { useCallback, useEffect } from 'react'`);
2865
+ imports.add(`import { useCallback, useEffect, useRef } from 'react'`);
2841
2866
  imports.add(`import {useNetworkState, NetworkState, DispatchState, pending, success, error, init, successfulDispatch, validationError, encode, isSuccess, requestValidationError} from "@intrig/react"`);
2842
2867
  const { hookShape, optionsShape } = extractHookShapeAndOptionsShape(response, requestBody, imports);
2843
2868
  const { paramExpression, paramType } = extractParamDeconstruction$1(variables, requestBody);
@@ -2883,7 +2908,7 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2883
2908
  const source = "${source}"
2884
2909
 
2885
2910
  function use${pluginSdk.pascalCase(operationId)}Hook(options: ${optionsShape} = {}): [NetworkState<Response>, (${paramType}) => DispatchState<any>, () => void] {
2886
- let [state, dispatch, clear, dispatchState] = useNetworkState<Response>({
2911
+ const [state, dispatch, clear, dispatchState] = useNetworkState<Response>({
2887
2912
  key: options?.key ?? 'default',
2888
2913
  operation,
2889
2914
  source,
@@ -2891,6 +2916,11 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2891
2916
  errorSchema
2892
2917
  });
2893
2918
 
2919
+ const optionsRef = useRef(options);
2920
+ useEffect(() => {
2921
+ optionsRef.current = options;
2922
+ });
2923
+
2894
2924
  useEffect(() => {
2895
2925
  if (isSuccess(state)) {
2896
2926
  let a = document.createElement('a');
@@ -2923,10 +2953,10 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2923
2953
  document.body.removeChild(a);
2924
2954
  dispatchState(init())
2925
2955
  }
2926
- }, [state])
2956
+ }, [state, dispatchState])
2927
2957
 
2928
- let doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
2929
- let { ${paramExplode}} = p
2958
+ const doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
2959
+ const { ${paramExplode}} = p
2930
2960
 
2931
2961
  ${requestBody ? `
2932
2962
  const validationResult = requestBodySchema.safeParse(data);
@@ -2949,22 +2979,22 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2949
2979
  ${responseTypePart()}
2950
2980
  })
2951
2981
  return successfulDispatch();
2952
- }, [dispatch])
2982
+ }, [dispatch, dispatchState])
2953
2983
 
2954
2984
  useEffect(() => {
2955
- if (options.fetchOnMount) {
2985
+ if (optionsRef.current.fetchOnMount) {
2956
2986
  doExecute(${[
2957
- requestBody ? `options.body!` : undefined,
2958
- "options.params!"
2987
+ requestBody ? `optionsRef.current.body!` : undefined,
2988
+ "optionsRef.current.params!"
2959
2989
  ].filter((a)=>a).join(",")});
2960
2990
  }
2961
2991
 
2962
2992
  return () => {
2963
- if (options.clearOnUnmount) {
2993
+ if (optionsRef.current.clearOnUnmount) {
2964
2994
  clear();
2965
2995
  }
2966
2996
  }
2967
- }, [])
2997
+ }, [doExecute, clear]) // Added proper dependencies
2968
2998
 
2969
2999
  return [
2970
3000
  state,
@@ -3581,6 +3611,217 @@ function handleComplexSchema(schema, imports) {
3581
3611
  };
3582
3612
  }
3583
3613
 
3614
+ function serverFunctionDocs(descriptor) {
3615
+ const md = pluginSdk.mdLiteral('server-function.md');
3616
+ var _descriptor_data_variables;
3617
+ // ===== Derived names (preserve these) =====
3618
+ const hasPathParams = ((_descriptor_data_variables = descriptor.data.variables) != null ? _descriptor_data_variables : []).some((v)=>{
3619
+ var _v_in;
3620
+ return ((_v_in = v.in) == null ? void 0 : _v_in.toUpperCase()) === 'PATH';
3621
+ });
3622
+ const actionName = pluginSdk.camelCase(descriptor.name) // e.g. getUser
3623
+ ;
3624
+ const executeActionName = `execute${pluginSdk.pascalCase(descriptor.name)}` // e.g. executeGetUser
3625
+ ;
3626
+ const requestBodyVar = descriptor.data.requestBody ? pluginSdk.camelCase(descriptor.data.requestBody) // e.g. createUser
3627
+ : undefined;
3628
+ const requestBodyType = descriptor.data.requestBody ? pluginSdk.pascalCase(descriptor.data.requestBody) // e.g. CreateUser
3629
+ : undefined;
3630
+ const paramsVar = hasPathParams ? `${actionName}Params` : undefined // e.g. getUserParams
3631
+ ;
3632
+ const paramsType = hasPathParams ? `${pluginSdk.pascalCase(descriptor.name)}Params` : undefined // e.g. GetUserParams
3633
+ ;
3634
+ const responseTypeName = `${pluginSdk.pascalCase(descriptor.name)}Response` // e.g. GetUserResponse
3635
+ ;
3636
+ const callArgs = [
3637
+ requestBodyVar,
3638
+ paramsVar
3639
+ ].filter(Boolean).join(', ');
3640
+ return md`
3641
+ # Server-Side Functions — Quick Guide
3642
+
3643
+ ## Copy-paste starter (fast lane)
3644
+
3645
+ ### 1) Function import (in your Next.js API route or server component)
3646
+ ${"```ts"}
3647
+ import { ${actionName}, ${executeActionName} } from '@intrig/react/${descriptor.path}/server';
3648
+ ${"```"}
3649
+
3650
+ ### 2) Use the async function
3651
+ ${"```ts"}
3652
+ // Simple usage - returns parsed response
3653
+ const result = await ${actionName}(${callArgs});
3654
+
3655
+ // Advanced usage - returns raw data + headers
3656
+ const { data, headers } = await ${executeActionName}(${callArgs});
3657
+ ${"```"}
3658
+
3659
+ Server-side functions are for **Next.js API routes** and **server components**. They return **awaitable promises** that directly call your backend API.
3660
+
3661
+ ---
3662
+
3663
+ ## TL;DR (copy–paste examples)
3664
+
3665
+ ### In API Route (\`pages/api\` or \`app/api\`)
3666
+ ${"```ts"}
3667
+ // pages/api/example.ts or app/api/example/route.ts
3668
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3669
+ import type { NextApiRequest, NextApiResponse } from 'next';
3670
+
3671
+ export default async function handler(req: NextApiRequest, res: NextApiResponse) {
3672
+ try {
3673
+ const result = await ${actionName}(${callArgs});
3674
+ res.status(200).json(result);
3675
+ } catch (error) {
3676
+ console.error('API call failed:', error);
3677
+ res.status(500).json({ error: 'Internal server error' });
3678
+ }
3679
+ }
3680
+ ${"```"}
3681
+
3682
+ ### In Server Component (App Router)
3683
+ ${"```tsx"}
3684
+ // app/example/page.tsx
3685
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3686
+
3687
+ export default async function ExamplePage() {
3688
+ try {
3689
+ const data = await ${actionName}(${callArgs});
3690
+
3691
+ return (
3692
+ <div>
3693
+ <h1>Server Data</h1>
3694
+ <pre>{JSON.stringify(data, null, 2)}</pre>
3695
+ </div>
3696
+ );
3697
+ } catch (error) {
3698
+ return <div>Error loading data: {error.message}</div>;
3699
+ }
3700
+ }
3701
+ ${"```"}
3702
+
3703
+ ### In Server Action (App Router)
3704
+ ${"```ts"}
3705
+ // app/actions.ts
3706
+ 'use server';
3707
+
3708
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3709
+
3710
+ export async function serverAction(formData: FormData) {
3711
+ try {
3712
+ const result = await ${actionName}(${callArgs});
3713
+ // Process result...
3714
+ return { success: true, data: result };
3715
+ } catch (error) {
3716
+ return { success: false, error: error.message };
3717
+ }
3718
+ }
3719
+ ${"```"}
3720
+
3721
+ ${requestBodyType || paramsType ? `### Optional types (if generated by your build)
3722
+ ${"```ts"}
3723
+ ${requestBodyType ? `import type { ${requestBodyType} } from '@intrig/react/${descriptor.source}/components/schemas/${requestBodyType}';
3724
+ ` : ''}${paramsType ? `import type { ${paramsType} } from '@intrig/react/${descriptor.path}/${pluginSdk.pascalCase(descriptor.name)}.params';
3725
+ ` : ''}import type { ${responseTypeName} } from '@intrig/react/${descriptor.path}/${pluginSdk.pascalCase(descriptor.name)}.response';
3726
+ ${"```"}
3727
+ ` : ''}
3728
+
3729
+ ---
3730
+
3731
+ ## Function API
3732
+
3733
+ ${"```ts"}
3734
+ // Prefer concrete types if your build emits them:
3735
+ // import type { ${responseTypeName} } from '@intrig/react/${descriptor.path}/${pluginSdk.pascalCase(descriptor.name)}.response';
3736
+ // ${paramsType ? `import type { ${paramsType} } from '@intrig/react/${descriptor.path}/${pluginSdk.pascalCase(descriptor.name)}.params';` : ''}
3737
+
3738
+ type ${pluginSdk.pascalCase(descriptor.name)}Data = ${'unknown'}; // replace with ${responseTypeName} if generated
3739
+ type ${pluginSdk.pascalCase(descriptor.name)}Request = {
3740
+ body?: ${requestBodyType != null ? requestBodyType : 'unknown'};
3741
+ params?: ${paramsType != null ? paramsType : 'unknown'};
3742
+ };
3743
+
3744
+ // Main function - returns parsed response
3745
+ declare function ${actionName}(
3746
+ ${requestBodyVar ? `body: ${pluginSdk.pascalCase(descriptor.name)}Request['body'], ` : ''}${paramsVar ? `params: ${pluginSdk.pascalCase(descriptor.name)}Request['params'], ` : ''}options?: AsyncRequestOptions
3747
+ ): Promise<${pluginSdk.pascalCase(descriptor.name)}Data>;
3748
+
3749
+ // Advanced function - returns raw data + headers
3750
+ declare function ${executeActionName}(
3751
+ ${requestBodyVar ? `body: ${pluginSdk.pascalCase(descriptor.name)}Request['body'], ` : ''}${paramsVar ? `params: ${pluginSdk.pascalCase(descriptor.name)}Request['params'], ` : ''}options?: AsyncRequestOptions
3752
+ ): Promise<{ data: any, headers: any }>;
3753
+ ${"```"}
3754
+
3755
+ ### Why server-side functions?
3756
+ - **Server-only execution:** Perfect for Next.js API routes and server components.
3757
+ - **Direct API calls:** No client-side state management needed.
3758
+ - **SSR/SSG friendly:** Use in \`getServerSideProps\`, \`getStaticProps\`, or server components.
3759
+ - **Built-in error handling:** Automatic network and validation error handling.
3760
+
3761
+ ### Options
3762
+ Both functions accept an optional \`options\` parameter:
3763
+
3764
+ ${"```ts"}
3765
+ type AsyncRequestOptions = {
3766
+ hydrate?: boolean; // Cache response for client-side hydration
3767
+ key?: string; // Custom cache key (when hydrate is true)
3768
+ };
3769
+ ${"```"}
3770
+
3771
+ ### Error Handling
3772
+ Server-side functions throw errors for:
3773
+ - **Network errors:** Connection issues, HTTP error status codes
3774
+ - **Validation errors:** Response doesn't match expected schema
3775
+ - **Request errors:** Invalid request body or parameters
3776
+
3777
+ Always wrap calls in try-catch blocks for production use.
3778
+
3779
+ ---
3780
+
3781
+ ## Next.js Integration Patterns
3782
+
3783
+ ### 1. API Routes (Pages Router)
3784
+ Use server functions in your API routes to proxy requests or process data server-side.
3785
+
3786
+ ### 2. Server Components (App Router)
3787
+ Directly call server functions in your server components for SSR data fetching.
3788
+
3789
+ ### 3. Server Actions (App Router)
3790
+ Use server functions within server actions for form submissions and mutations.
3791
+
3792
+ ### 4. Middleware
3793
+ Server functions can be used in Next.js middleware for request preprocessing.
3794
+
3795
+ ### 5. getServerSideProps / getStaticProps (Pages Router)
3796
+ Perfect for data fetching in traditional Next.js data fetching methods.
3797
+
3798
+ ---
3799
+
3800
+ ## Best Practices
3801
+
3802
+ 1. **Error boundaries:** Always handle errors appropriately for your use case
3803
+ 2. **Caching:** Use the \`hydrate\` option for data that should be available client-side
3804
+ 3. **Types:** Import and use the generated TypeScript types for better DX
3805
+ 4. **Logging:** Server functions include built-in logging for debugging
3806
+
3807
+ ${"```ts"}
3808
+ // Example with proper error handling and types
3809
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3810
+ ${paramsType ? `import type { ${paramsType} } from '@intrig/react/${descriptor.path}/${pluginSdk.pascalCase(descriptor.name)}.params';` : ''}
3811
+ import type { ${responseTypeName} } from '@intrig/react/${descriptor.path}/${pluginSdk.pascalCase(descriptor.name)}.response';
3812
+
3813
+ export async function fetchData(${paramsVar ? `params: ${paramsType}` : ''}): Promise<${responseTypeName} | null> {
3814
+ try {
3815
+ return await ${actionName}(${callArgs});
3816
+ } catch (error) {
3817
+ console.error('Failed to fetch data:', error);
3818
+ return null;
3819
+ }
3820
+ }
3821
+ ${"```"}
3822
+ `;
3823
+ }
3824
+
3584
3825
  async function generateCode(ctx) {
3585
3826
  // Root/project files
3586
3827
  await ctx.dump(packageJsonTemplate(ctx));
@@ -3614,6 +3855,7 @@ async function generateCode(ctx) {
3614
3855
  await ctx.dump(paramsTemplate(restDescriptor));
3615
3856
  await ctx.dump(asyncFunctionHookTemplate(restDescriptor, internalGeneratorContext));
3616
3857
  await ctx.dump(nextRequestMethodTemplate(restDescriptor, internalGeneratorContext));
3858
+ await ctx.dump(serverFunctionDocs(restDescriptor));
3617
3859
  if (restDescriptor.data.isDownloadable) {
3618
3860
  await ctx.dump(downloadHookTemplate(restDescriptor, internalGeneratorContext));
3619
3861
  }
@@ -3659,12 +3901,12 @@ Use this TypeScript type anywhere you need static typing for this object shape i
3659
3901
 
3660
3902
  ## Import
3661
3903
  ${'```ts'}
3662
- ${importContent}
3904
+ ${importContent.content}
3663
3905
  ${'```'}
3664
3906
 
3665
3907
  ## Definition
3666
3908
  ${'```ts'}
3667
- ${codeContent}
3909
+ ${codeContent.content}
3668
3910
  ${'```'}
3669
3911
  `;
3670
3912
  }
@@ -3686,12 +3928,12 @@ Use this JSON Schema with tools that consume JSON Schema: UI form builders (e.g.
3686
3928
 
3687
3929
  ## Import
3688
3930
  ${'```ts'}
3689
- ${importContent}
3931
+ ${importContent.content}
3690
3932
  ${'```'}
3691
3933
 
3692
3934
  ## Definition
3693
3935
  ${'```ts'}
3694
- ${codeContent}
3936
+ ${codeContent.content}
3695
3937
  ${'```'}
3696
3938
  `;
3697
3939
  }
@@ -3713,12 +3955,12 @@ Use this Zod schema for runtime validation and parsing: form validation, client/
3713
3955
 
3714
3956
  ## Import
3715
3957
  ${'```ts'}
3716
- ${importContent}
3958
+ ${importContent.content}
3717
3959
  ${'```'}
3718
3960
 
3719
3961
  ## Definition
3720
3962
  ${'```ts'}
3721
- ${codeContent}
3963
+ ${codeContent.content}
3722
3964
  ${'```'}
3723
3965
  `;
3724
3966
  }
@@ -4738,6 +4980,14 @@ async function initPlugin(ctx) {
4738
4980
  const apiRoutesDir = (options == null ? void 0 : options.apiRoutesDir) || 'src/app/api';
4739
4981
  // Add the directory with (generated) to gitignore
4740
4982
  updateGitIgnore(rootDir, `${apiRoutesDir}/(generated)`);
4983
+ return {
4984
+ postInit: ()=>{
4985
+ console.log(chalk.blue('\nšŸ“‹ Next Steps:'));
4986
+ console.log(chalk.white('To complete your Next.js setup, please refer to the post-initialization instructions at:'));
4987
+ console.log(chalk.cyan('https://intrig.dev/docs/next/initialization#3-post-initialization-steps'));
4988
+ console.log(chalk.gray('\nThis guide will show you how to add IntrigProvider to your Next.js application.\n'));
4989
+ }
4990
+ };
4741
4991
  }
4742
4992
 
4743
4993
  async function postBuild(ctx) {
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import * as fsx from 'fs-extra';
5
5
  import * as mimeType from 'mime-types';
6
6
  import * as _ from 'lodash';
7
7
  import * as fs from 'fs';
8
+ import chalk from 'chalk';
8
9
 
9
10
  class InternalGeneratorContext {
10
11
  getCounter(sourceId) {
@@ -1624,6 +1625,7 @@ function providerHooksTemplate() {
1624
1625
  useMemo,
1625
1626
  useState,
1626
1627
  useRef,
1628
+ useEffect,
1627
1629
  } from 'react';
1628
1630
  import {
1629
1631
  ErrorState,
@@ -1667,6 +1669,16 @@ export function useNetworkState<T>({
1667
1669
  const context = useContext(Context);
1668
1670
 
1669
1671
  const [abortController, setAbortController] = useState<AbortController>();
1672
+
1673
+ const contextRef = useRef(context);
1674
+ const schemaRef = useRef(schema);
1675
+ const errorSchemaRef = useRef(errorSchema);
1676
+
1677
+ useEffect(() => {
1678
+ contextRef.current = context;
1679
+ schemaRef.current = schema;
1680
+ errorSchemaRef.current = errorSchema;
1681
+ });
1670
1682
 
1671
1683
  const networkState = useMemo(() => {
1672
1684
  logger.info(${"`Updating status ${key} ${operation} ${source}`"});
@@ -1675,7 +1687,7 @@ export function useNetworkState<T>({
1675
1687
  (context.state?.[${"`${source}:${operation}:${key}`"}] as NetworkState<T>) ??
1676
1688
  init()
1677
1689
  );
1678
- }, [JSON.stringify(context.state?.[${"`${source}:${operation}:${key}`"}])]);
1690
+ }, [context.state, key, operation, source]);
1679
1691
 
1680
1692
  const dispatch = useCallback(
1681
1693
  (state: NetworkState<T>) => {
@@ -1723,30 +1735,30 @@ export function useNetworkState<T>({
1723
1735
  signal: abortController.signal,
1724
1736
  };
1725
1737
 
1726
- await context.execute(
1738
+ await contextRef.current.execute(
1727
1739
  requestConfig,
1728
1740
  dispatch,
1729
- schema,
1730
- errorSchema as any,
1741
+ schemaRef.current,
1742
+ errorSchemaRef.current as any,
1731
1743
  );
1732
1744
  },
1733
- [networkState, context.dispatch],
1745
+ [dispatch, key, operation, source],
1734
1746
  );
1735
1747
 
1736
1748
  const deboundedExecute = useMemo(
1737
- () => debounce(execute, debounceDelay ?? 0),
1738
- [execute],
1749
+ () => debounce(execute, debounceDelay),
1750
+ [execute, debounceDelay],
1739
1751
  );
1740
1752
 
1741
1753
  const clear = useCallback(() => {
1742
1754
  logger.info(${"`Clearing request ${key} ${operation} ${source}`"});
1743
1755
  dispatch(init());
1744
- setAbortController((abortController) => {
1756
+ setAbortController((prev) => {
1745
1757
  logger.info(${"`Aborting request ${key} ${operation} ${source}`"});
1746
- abortController?.abort();
1758
+ prev?.abort();
1747
1759
  return undefined;
1748
1760
  });
1749
- }, [dispatch, abortController]);
1761
+ }, [dispatch, key, operation, source]);
1750
1762
 
1751
1763
  return [networkState, deboundedExecute, clear, dispatch];
1752
1764
  }
@@ -1763,6 +1775,14 @@ export function useTransitionCall<T>({
1763
1775
  }): [(request: RequestType) => Promise<T>, () => void] {
1764
1776
  const ctx = useContext(Context);
1765
1777
  const controller = useRef<AbortController | undefined>(undefined);
1778
+
1779
+ const schemaRef = useRef(schema);
1780
+ const errorSchemaRef = useRef(errorSchema);
1781
+
1782
+ useEffect(() => {
1783
+ schemaRef.current = schema;
1784
+ errorSchemaRef.current = errorSchema;
1785
+ });
1766
1786
 
1767
1787
  const call = useCallback(
1768
1788
  async (request: RequestType) => {
@@ -1780,12 +1800,12 @@ export function useTransitionCall<T>({
1780
1800
  reject(state.error);
1781
1801
  }
1782
1802
  },
1783
- schema,
1784
- errorSchema,
1803
+ schemaRef.current,
1804
+ errorSchemaRef.current,
1785
1805
  );
1786
1806
  });
1787
1807
  },
1788
- [ctx, schema, errorSchema],
1808
+ [ctx],
1789
1809
  );
1790
1810
 
1791
1811
  const abort = useCallback(() => {
@@ -2421,7 +2441,7 @@ async function requestHookTemplate({ source, data: { paths, operationId, respons
2421
2441
  const modifiedRequestUrl = `${requestUrl == null ? void 0 : requestUrl.replace(/\{/g, "${")}`;
2422
2442
  const imports = new Set();
2423
2443
  imports.add(`import { z } from 'zod'`);
2424
- imports.add(`import { useCallback, useEffect } from 'react'`);
2444
+ imports.add(`import { useCallback, useEffect, useRef } from 'react'`);
2425
2445
  imports.add(`import {useNetworkState, NetworkState, DispatchState, error, successfulDispatch, validationError, encode, requestValidationError} from "@intrig/react"`);
2426
2446
  const { hookShape, optionsShape } = extractHookShapeAndOptionsShape$1(response, requestBody, imports);
2427
2447
  const { paramExpression, paramType } = extractParamDeconstruction$3(variables != null ? variables : [], requestBody);
@@ -2474,6 +2494,11 @@ async function requestHookTemplate({ source, data: { paths, operationId, respons
2474
2494
  schema,
2475
2495
  errorSchema
2476
2496
  });
2497
+
2498
+ const optionsRef = useRef(options);
2499
+ useEffect(() => {
2500
+ optionsRef.current = options;
2501
+ });
2477
2502
 
2478
2503
  const doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
2479
2504
  const { ${paramExplode}} = p
@@ -2499,22 +2524,22 @@ async function requestHookTemplate({ source, data: { paths, operationId, respons
2499
2524
  ${responseTypePart()}
2500
2525
  })
2501
2526
  return successfulDispatch();
2502
- }, [dispatch])
2527
+ }, [dispatch, dispatchState])
2503
2528
 
2504
2529
  useEffect(() => {
2505
- if (options.fetchOnMount) {
2530
+ if (optionsRef.current.fetchOnMount) {
2506
2531
  doExecute(${[
2507
- requestBody ? `options.body!` : undefined,
2508
- "options.params!"
2532
+ requestBody ? `optionsRef.current.body!` : undefined,
2533
+ "optionsRef.current.params!"
2509
2534
  ].filter((a)=>a).join(",")});
2510
2535
  }
2511
2536
 
2512
2537
  return () => {
2513
- if (options.clearOnUnmount) {
2538
+ if (optionsRef.current.clearOnUnmount) {
2514
2539
  clear();
2515
2540
  }
2516
2541
  }
2517
- }, [])
2542
+ }, [doExecute, clear])
2518
2543
 
2519
2544
  return [
2520
2545
  state,
@@ -2811,7 +2836,7 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2811
2836
  const modifiedRequestUrl = `${requestUrl == null ? void 0 : requestUrl.replace(/\{/g, "${")}`;
2812
2837
  const imports = new Set();
2813
2838
  imports.add(`import { z } from 'zod'`);
2814
- imports.add(`import { useCallback, useEffect } from 'react'`);
2839
+ imports.add(`import { useCallback, useEffect, useRef } from 'react'`);
2815
2840
  imports.add(`import {useNetworkState, NetworkState, DispatchState, pending, success, error, init, successfulDispatch, validationError, encode, isSuccess, requestValidationError} from "@intrig/react"`);
2816
2841
  const { hookShape, optionsShape } = extractHookShapeAndOptionsShape(response, requestBody, imports);
2817
2842
  const { paramExpression, paramType } = extractParamDeconstruction$1(variables, requestBody);
@@ -2857,7 +2882,7 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2857
2882
  const source = "${source}"
2858
2883
 
2859
2884
  function use${pascalCase(operationId)}Hook(options: ${optionsShape} = {}): [NetworkState<Response>, (${paramType}) => DispatchState<any>, () => void] {
2860
- let [state, dispatch, clear, dispatchState] = useNetworkState<Response>({
2885
+ const [state, dispatch, clear, dispatchState] = useNetworkState<Response>({
2861
2886
  key: options?.key ?? 'default',
2862
2887
  operation,
2863
2888
  source,
@@ -2865,6 +2890,11 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2865
2890
  errorSchema
2866
2891
  });
2867
2892
 
2893
+ const optionsRef = useRef(options);
2894
+ useEffect(() => {
2895
+ optionsRef.current = options;
2896
+ });
2897
+
2868
2898
  useEffect(() => {
2869
2899
  if (isSuccess(state)) {
2870
2900
  let a = document.createElement('a');
@@ -2897,10 +2927,10 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2897
2927
  document.body.removeChild(a);
2898
2928
  dispatchState(init())
2899
2929
  }
2900
- }, [state])
2930
+ }, [state, dispatchState])
2901
2931
 
2902
- let doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
2903
- let { ${paramExplode}} = p
2932
+ const doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
2933
+ const { ${paramExplode}} = p
2904
2934
 
2905
2935
  ${requestBody ? `
2906
2936
  const validationResult = requestBodySchema.safeParse(data);
@@ -2923,22 +2953,22 @@ async function downloadHookTemplate({ source, data: { paths, operationId, respon
2923
2953
  ${responseTypePart()}
2924
2954
  })
2925
2955
  return successfulDispatch();
2926
- }, [dispatch])
2956
+ }, [dispatch, dispatchState])
2927
2957
 
2928
2958
  useEffect(() => {
2929
- if (options.fetchOnMount) {
2959
+ if (optionsRef.current.fetchOnMount) {
2930
2960
  doExecute(${[
2931
- requestBody ? `options.body!` : undefined,
2932
- "options.params!"
2961
+ requestBody ? `optionsRef.current.body!` : undefined,
2962
+ "optionsRef.current.params!"
2933
2963
  ].filter((a)=>a).join(",")});
2934
2964
  }
2935
2965
 
2936
2966
  return () => {
2937
- if (options.clearOnUnmount) {
2967
+ if (optionsRef.current.clearOnUnmount) {
2938
2968
  clear();
2939
2969
  }
2940
2970
  }
2941
- }, [])
2971
+ }, [doExecute, clear]) // Added proper dependencies
2942
2972
 
2943
2973
  return [
2944
2974
  state,
@@ -3555,6 +3585,217 @@ function handleComplexSchema(schema, imports) {
3555
3585
  };
3556
3586
  }
3557
3587
 
3588
+ function serverFunctionDocs(descriptor) {
3589
+ const md = mdLiteral('server-function.md');
3590
+ var _descriptor_data_variables;
3591
+ // ===== Derived names (preserve these) =====
3592
+ const hasPathParams = ((_descriptor_data_variables = descriptor.data.variables) != null ? _descriptor_data_variables : []).some((v)=>{
3593
+ var _v_in;
3594
+ return ((_v_in = v.in) == null ? void 0 : _v_in.toUpperCase()) === 'PATH';
3595
+ });
3596
+ const actionName = camelCase(descriptor.name) // e.g. getUser
3597
+ ;
3598
+ const executeActionName = `execute${pascalCase(descriptor.name)}` // e.g. executeGetUser
3599
+ ;
3600
+ const requestBodyVar = descriptor.data.requestBody ? camelCase(descriptor.data.requestBody) // e.g. createUser
3601
+ : undefined;
3602
+ const requestBodyType = descriptor.data.requestBody ? pascalCase(descriptor.data.requestBody) // e.g. CreateUser
3603
+ : undefined;
3604
+ const paramsVar = hasPathParams ? `${actionName}Params` : undefined // e.g. getUserParams
3605
+ ;
3606
+ const paramsType = hasPathParams ? `${pascalCase(descriptor.name)}Params` : undefined // e.g. GetUserParams
3607
+ ;
3608
+ const responseTypeName = `${pascalCase(descriptor.name)}Response` // e.g. GetUserResponse
3609
+ ;
3610
+ const callArgs = [
3611
+ requestBodyVar,
3612
+ paramsVar
3613
+ ].filter(Boolean).join(', ');
3614
+ return md`
3615
+ # Server-Side Functions — Quick Guide
3616
+
3617
+ ## Copy-paste starter (fast lane)
3618
+
3619
+ ### 1) Function import (in your Next.js API route or server component)
3620
+ ${"```ts"}
3621
+ import { ${actionName}, ${executeActionName} } from '@intrig/react/${descriptor.path}/server';
3622
+ ${"```"}
3623
+
3624
+ ### 2) Use the async function
3625
+ ${"```ts"}
3626
+ // Simple usage - returns parsed response
3627
+ const result = await ${actionName}(${callArgs});
3628
+
3629
+ // Advanced usage - returns raw data + headers
3630
+ const { data, headers } = await ${executeActionName}(${callArgs});
3631
+ ${"```"}
3632
+
3633
+ Server-side functions are for **Next.js API routes** and **server components**. They return **awaitable promises** that directly call your backend API.
3634
+
3635
+ ---
3636
+
3637
+ ## TL;DR (copy–paste examples)
3638
+
3639
+ ### In API Route (\`pages/api\` or \`app/api\`)
3640
+ ${"```ts"}
3641
+ // pages/api/example.ts or app/api/example/route.ts
3642
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3643
+ import type { NextApiRequest, NextApiResponse } from 'next';
3644
+
3645
+ export default async function handler(req: NextApiRequest, res: NextApiResponse) {
3646
+ try {
3647
+ const result = await ${actionName}(${callArgs});
3648
+ res.status(200).json(result);
3649
+ } catch (error) {
3650
+ console.error('API call failed:', error);
3651
+ res.status(500).json({ error: 'Internal server error' });
3652
+ }
3653
+ }
3654
+ ${"```"}
3655
+
3656
+ ### In Server Component (App Router)
3657
+ ${"```tsx"}
3658
+ // app/example/page.tsx
3659
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3660
+
3661
+ export default async function ExamplePage() {
3662
+ try {
3663
+ const data = await ${actionName}(${callArgs});
3664
+
3665
+ return (
3666
+ <div>
3667
+ <h1>Server Data</h1>
3668
+ <pre>{JSON.stringify(data, null, 2)}</pre>
3669
+ </div>
3670
+ );
3671
+ } catch (error) {
3672
+ return <div>Error loading data: {error.message}</div>;
3673
+ }
3674
+ }
3675
+ ${"```"}
3676
+
3677
+ ### In Server Action (App Router)
3678
+ ${"```ts"}
3679
+ // app/actions.ts
3680
+ 'use server';
3681
+
3682
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3683
+
3684
+ export async function serverAction(formData: FormData) {
3685
+ try {
3686
+ const result = await ${actionName}(${callArgs});
3687
+ // Process result...
3688
+ return { success: true, data: result };
3689
+ } catch (error) {
3690
+ return { success: false, error: error.message };
3691
+ }
3692
+ }
3693
+ ${"```"}
3694
+
3695
+ ${requestBodyType || paramsType ? `### Optional types (if generated by your build)
3696
+ ${"```ts"}
3697
+ ${requestBodyType ? `import type { ${requestBodyType} } from '@intrig/react/${descriptor.source}/components/schemas/${requestBodyType}';
3698
+ ` : ''}${paramsType ? `import type { ${paramsType} } from '@intrig/react/${descriptor.path}/${pascalCase(descriptor.name)}.params';
3699
+ ` : ''}import type { ${responseTypeName} } from '@intrig/react/${descriptor.path}/${pascalCase(descriptor.name)}.response';
3700
+ ${"```"}
3701
+ ` : ''}
3702
+
3703
+ ---
3704
+
3705
+ ## Function API
3706
+
3707
+ ${"```ts"}
3708
+ // Prefer concrete types if your build emits them:
3709
+ // import type { ${responseTypeName} } from '@intrig/react/${descriptor.path}/${pascalCase(descriptor.name)}.response';
3710
+ // ${paramsType ? `import type { ${paramsType} } from '@intrig/react/${descriptor.path}/${pascalCase(descriptor.name)}.params';` : ''}
3711
+
3712
+ type ${pascalCase(descriptor.name)}Data = ${'unknown'}; // replace with ${responseTypeName} if generated
3713
+ type ${pascalCase(descriptor.name)}Request = {
3714
+ body?: ${requestBodyType != null ? requestBodyType : 'unknown'};
3715
+ params?: ${paramsType != null ? paramsType : 'unknown'};
3716
+ };
3717
+
3718
+ // Main function - returns parsed response
3719
+ declare function ${actionName}(
3720
+ ${requestBodyVar ? `body: ${pascalCase(descriptor.name)}Request['body'], ` : ''}${paramsVar ? `params: ${pascalCase(descriptor.name)}Request['params'], ` : ''}options?: AsyncRequestOptions
3721
+ ): Promise<${pascalCase(descriptor.name)}Data>;
3722
+
3723
+ // Advanced function - returns raw data + headers
3724
+ declare function ${executeActionName}(
3725
+ ${requestBodyVar ? `body: ${pascalCase(descriptor.name)}Request['body'], ` : ''}${paramsVar ? `params: ${pascalCase(descriptor.name)}Request['params'], ` : ''}options?: AsyncRequestOptions
3726
+ ): Promise<{ data: any, headers: any }>;
3727
+ ${"```"}
3728
+
3729
+ ### Why server-side functions?
3730
+ - **Server-only execution:** Perfect for Next.js API routes and server components.
3731
+ - **Direct API calls:** No client-side state management needed.
3732
+ - **SSR/SSG friendly:** Use in \`getServerSideProps\`, \`getStaticProps\`, or server components.
3733
+ - **Built-in error handling:** Automatic network and validation error handling.
3734
+
3735
+ ### Options
3736
+ Both functions accept an optional \`options\` parameter:
3737
+
3738
+ ${"```ts"}
3739
+ type AsyncRequestOptions = {
3740
+ hydrate?: boolean; // Cache response for client-side hydration
3741
+ key?: string; // Custom cache key (when hydrate is true)
3742
+ };
3743
+ ${"```"}
3744
+
3745
+ ### Error Handling
3746
+ Server-side functions throw errors for:
3747
+ - **Network errors:** Connection issues, HTTP error status codes
3748
+ - **Validation errors:** Response doesn't match expected schema
3749
+ - **Request errors:** Invalid request body or parameters
3750
+
3751
+ Always wrap calls in try-catch blocks for production use.
3752
+
3753
+ ---
3754
+
3755
+ ## Next.js Integration Patterns
3756
+
3757
+ ### 1. API Routes (Pages Router)
3758
+ Use server functions in your API routes to proxy requests or process data server-side.
3759
+
3760
+ ### 2. Server Components (App Router)
3761
+ Directly call server functions in your server components for SSR data fetching.
3762
+
3763
+ ### 3. Server Actions (App Router)
3764
+ Use server functions within server actions for form submissions and mutations.
3765
+
3766
+ ### 4. Middleware
3767
+ Server functions can be used in Next.js middleware for request preprocessing.
3768
+
3769
+ ### 5. getServerSideProps / getStaticProps (Pages Router)
3770
+ Perfect for data fetching in traditional Next.js data fetching methods.
3771
+
3772
+ ---
3773
+
3774
+ ## Best Practices
3775
+
3776
+ 1. **Error boundaries:** Always handle errors appropriately for your use case
3777
+ 2. **Caching:** Use the \`hydrate\` option for data that should be available client-side
3778
+ 3. **Types:** Import and use the generated TypeScript types for better DX
3779
+ 4. **Logging:** Server functions include built-in logging for debugging
3780
+
3781
+ ${"```ts"}
3782
+ // Example with proper error handling and types
3783
+ import { ${actionName} } from '@intrig/react/${descriptor.path}/server';
3784
+ ${paramsType ? `import type { ${paramsType} } from '@intrig/react/${descriptor.path}/${pascalCase(descriptor.name)}.params';` : ''}
3785
+ import type { ${responseTypeName} } from '@intrig/react/${descriptor.path}/${pascalCase(descriptor.name)}.response';
3786
+
3787
+ export async function fetchData(${paramsVar ? `params: ${paramsType}` : ''}): Promise<${responseTypeName} | null> {
3788
+ try {
3789
+ return await ${actionName}(${callArgs});
3790
+ } catch (error) {
3791
+ console.error('Failed to fetch data:', error);
3792
+ return null;
3793
+ }
3794
+ }
3795
+ ${"```"}
3796
+ `;
3797
+ }
3798
+
3558
3799
  async function generateCode(ctx) {
3559
3800
  // Root/project files
3560
3801
  await ctx.dump(packageJsonTemplate(ctx));
@@ -3588,6 +3829,7 @@ async function generateCode(ctx) {
3588
3829
  await ctx.dump(paramsTemplate(restDescriptor));
3589
3830
  await ctx.dump(asyncFunctionHookTemplate(restDescriptor, internalGeneratorContext));
3590
3831
  await ctx.dump(nextRequestMethodTemplate(restDescriptor, internalGeneratorContext));
3832
+ await ctx.dump(serverFunctionDocs(restDescriptor));
3591
3833
  if (restDescriptor.data.isDownloadable) {
3592
3834
  await ctx.dump(downloadHookTemplate(restDescriptor, internalGeneratorContext));
3593
3835
  }
@@ -3633,12 +3875,12 @@ Use this TypeScript type anywhere you need static typing for this object shape i
3633
3875
 
3634
3876
  ## Import
3635
3877
  ${'```ts'}
3636
- ${importContent}
3878
+ ${importContent.content}
3637
3879
  ${'```'}
3638
3880
 
3639
3881
  ## Definition
3640
3882
  ${'```ts'}
3641
- ${codeContent}
3883
+ ${codeContent.content}
3642
3884
  ${'```'}
3643
3885
  `;
3644
3886
  }
@@ -3660,12 +3902,12 @@ Use this JSON Schema with tools that consume JSON Schema: UI form builders (e.g.
3660
3902
 
3661
3903
  ## Import
3662
3904
  ${'```ts'}
3663
- ${importContent}
3905
+ ${importContent.content}
3664
3906
  ${'```'}
3665
3907
 
3666
3908
  ## Definition
3667
3909
  ${'```ts'}
3668
- ${codeContent}
3910
+ ${codeContent.content}
3669
3911
  ${'```'}
3670
3912
  `;
3671
3913
  }
@@ -3687,12 +3929,12 @@ Use this Zod schema for runtime validation and parsing: form validation, client/
3687
3929
 
3688
3930
  ## Import
3689
3931
  ${'```ts'}
3690
- ${importContent}
3932
+ ${importContent.content}
3691
3933
  ${'```'}
3692
3934
 
3693
3935
  ## Definition
3694
3936
  ${'```ts'}
3695
- ${codeContent}
3937
+ ${codeContent.content}
3696
3938
  ${'```'}
3697
3939
  `;
3698
3940
  }
@@ -4712,6 +4954,14 @@ async function initPlugin(ctx) {
4712
4954
  const apiRoutesDir = (options == null ? void 0 : options.apiRoutesDir) || 'src/app/api';
4713
4955
  // Add the directory with (generated) to gitignore
4714
4956
  updateGitIgnore(rootDir, `${apiRoutesDir}/(generated)`);
4957
+ return {
4958
+ postInit: ()=>{
4959
+ console.log(chalk.blue('\nšŸ“‹ Next Steps:'));
4960
+ console.log(chalk.white('To complete your Next.js setup, please refer to the post-initialization instructions at:'));
4961
+ console.log(chalk.cyan('https://intrig.dev/docs/next/initialization#3-post-initialization-steps'));
4962
+ console.log(chalk.gray('\nThis guide will show you how to add IntrigProvider to your Next.js application.\n'));
4963
+ }
4964
+ };
4715
4965
  }
4716
4966
 
4717
4967
  async function postBuild(ctx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intrig/plugin-next",
3
- "version": "0.0.2-2",
3
+ "version": "0.0.2-3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -15,7 +15,7 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@intrig/plugin-sdk": "^0.0.2-5",
18
+ "@intrig/plugin-sdk": "^0.0.2-6",
19
19
  "@swc/helpers": "~0.5.11"
20
20
  },
21
21
  "files": [