@c15t/cli 1.6.0 → 1.7.0-canary-20251012181938
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/dist/commands/generate/options/utils/generate-files.d.ts.map +1 -1
- package/dist/commands/generate/templates/config.d.ts.map +1 -1
- package/dist/commands/generate/templates/layout.d.ts +4 -0
- package/dist/commands/generate/templates/layout.d.ts.map +1 -1
- package/dist/commands/generate/templates/next/app/components.d.ts +44 -0
- package/dist/commands/generate/templates/next/app/components.d.ts.map +1 -0
- package/dist/commands/generate/templates/next/app/layout.d.ts +23 -1
- package/dist/commands/generate/templates/next/app/layout.d.ts.map +1 -1
- package/dist/commands/generate/templates/next/index.d.ts +4 -0
- package/dist/commands/generate/templates/next/index.d.ts.map +1 -1
- package/dist/commands/generate/templates/next/pages/components.d.ts +22 -0
- package/dist/commands/generate/templates/next/pages/components.d.ts.map +1 -0
- package/dist/commands/generate/templates/next/pages/layout.d.ts +26 -1
- package/dist/commands/generate/templates/next/pages/layout.d.ts.map +1 -1
- package/dist/commands/generate/templates/react/components.d.ts +21 -0
- package/dist/commands/generate/templates/react/components.d.ts.map +1 -0
- package/dist/index.mjs +477 -206
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/telemetry.d.ts +1 -1
- package/dist/utils/telemetry.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-files.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/options/utils/generate-files.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACxD,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"generate-files.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/options/utils/generate-files.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACxD,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAqOD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EACnC,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,WAAW,EACX,UAAU,GACV,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiErD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAC1C,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE,SAAS,GAChB,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAC1C,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE,SAAS,GAChB,MAAM,CAuER"}
|
|
@@ -12,10 +12,14 @@ interface UpdateReactLayoutOptions {
|
|
|
12
12
|
pkg: AvailablePackages;
|
|
13
13
|
proxyNextjs?: boolean;
|
|
14
14
|
}
|
|
15
|
+
interface ComponentFilePaths {
|
|
16
|
+
consentManager: string;
|
|
17
|
+
}
|
|
15
18
|
export declare function updateReactLayout(options: UpdateReactLayoutOptions): Promise<{
|
|
16
19
|
updated: boolean;
|
|
17
20
|
filePath: string | null;
|
|
18
21
|
alreadyModified: boolean;
|
|
22
|
+
componentFiles?: ComponentFilePaths;
|
|
19
23
|
}>;
|
|
20
24
|
export {};
|
|
21
25
|
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAKvE,UAAU,wBAAwB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC3B,cAAc,EAAE,MAAM,CAAC;CACvB;AA2UD,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,wBAAwB,GAC/B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC,CAkBD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component template generators for Next.js App Directory
|
|
3
|
+
* Generates consent-manager.tsx and consent-manager.client.tsx components
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generates the server-side consent-manager.tsx component template
|
|
7
|
+
*
|
|
8
|
+
* @param optionsText - The stringified options object for ConsentManagerProvider
|
|
9
|
+
* @returns The complete component file content
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* This component is rendered on the server and contains:
|
|
13
|
+
* - ConsentManagerProvider with server-side configuration
|
|
14
|
+
* - CookieBanner component
|
|
15
|
+
* - ConsentManagerDialog component
|
|
16
|
+
* - ConsentManagerClient wrapper for client-side features
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const content = generateConsentManagerTemplate('{ mode: "c15t", backendURL: "/api/c15t" }');
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function generateConsentManagerTemplate(optionsText: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Generates the client-side consent-manager.client.tsx component template
|
|
26
|
+
*
|
|
27
|
+
* @returns The complete client component file content
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* This component is marked with 'use client' directive and handles:
|
|
31
|
+
* - ClientSideOptionsProvider for callbacks and scripts
|
|
32
|
+
* - Integration scripts (Google Tag Manager, Meta Pixel, etc.)
|
|
33
|
+
* - Client-side callbacks (onConsentSet, onError, etc.)
|
|
34
|
+
*
|
|
35
|
+
* Users should customize this file to add their specific scripts and callbacks.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const content = generateConsentManagerClientTemplate();
|
|
40
|
+
* await fs.writeFile('consent-manager.client.tsx', content);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function generateConsentManagerClientTemplate(): string;
|
|
44
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/app/components.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA4D1E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oCAAoC,IAAI,MAAM,CAyD7D"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* App Directory layout template generator
|
|
3
3
|
* Handles updating Next.js App Directory layout files with ConsentManagerProvider
|
|
4
|
+
* and creates separate consent-manager component files
|
|
4
5
|
*/
|
|
5
6
|
import type { AvailablePackages } from '../../../../../context/framework-detection';
|
|
6
7
|
interface UpdateAppLayoutOptions {
|
|
@@ -11,10 +12,31 @@ interface UpdateAppLayoutOptions {
|
|
|
11
12
|
pkg: AvailablePackages;
|
|
12
13
|
proxyNextjs?: boolean;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
interface ComponentFilePaths {
|
|
16
|
+
consentManager: string;
|
|
17
|
+
consentManagerClient: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Updates Next.js App Directory layout with consent management components
|
|
21
|
+
*
|
|
22
|
+
* @param options - Configuration options for the update
|
|
23
|
+
* @returns Information about the update operation including file paths
|
|
24
|
+
*
|
|
25
|
+
* @throws {Error} When component files cannot be created or layout cannot be updated
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* This function performs the following steps:
|
|
29
|
+
* 1. Locates the App Directory layout file
|
|
30
|
+
* 2. Checks if consent management is already configured
|
|
31
|
+
* 3. Creates consent-manager.tsx and consent-manager.client.tsx files
|
|
32
|
+
* 4. Adds ConsentManager import to layout
|
|
33
|
+
* 5. Wraps layout content with ConsentManager component
|
|
34
|
+
*/
|
|
35
|
+
export declare function updateAppLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs, }: UpdateAppLayoutOptions): Promise<{
|
|
15
36
|
updated: boolean;
|
|
16
37
|
filePath: string | null;
|
|
17
38
|
alreadyModified: boolean;
|
|
39
|
+
componentFiles?: ComponentFilePaths;
|
|
18
40
|
}>;
|
|
19
41
|
export {};
|
|
20
42
|
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/app/layout.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/app/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAYvE,UAAU,sBAAsB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAgQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,EACrC,WAAW,EACX,IAAI,EACJ,UAAU,EACV,UAAU,EACV,WAAW,GACX,EAAE,sBAAsB,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC,CA6ED"}
|
|
@@ -18,6 +18,10 @@ export declare function updateNextLayout(options: UpdateNextLayoutOptions): Prom
|
|
|
18
18
|
filePath: string | null;
|
|
19
19
|
alreadyModified: boolean;
|
|
20
20
|
structureType: NextStructure;
|
|
21
|
+
componentFiles?: {
|
|
22
|
+
consentManager: string;
|
|
23
|
+
consentManagerClient?: string;
|
|
24
|
+
};
|
|
21
25
|
}>;
|
|
22
26
|
export {};
|
|
23
27
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/templates/next/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,UAAU,uBAAuB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,KAAK,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;AAsC5C,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/templates/next/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,UAAU,uBAAuB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,KAAK,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;AAsC5C,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,CAAC,EAAE;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;CACF,CAAC,CAgCD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component template generators for Next.js Pages Directory
|
|
3
|
+
* Generates consent-manager.tsx component
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generates the consent-manager.tsx component template for Pages Directory
|
|
7
|
+
*
|
|
8
|
+
* @param optionsText - The stringified options object for ConsentManagerProvider
|
|
9
|
+
* @returns The complete component file content
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* This component wraps the Pages Directory app with consent management.
|
|
13
|
+
* Unlike App Directory, Pages Directory doesn't need a separate client component
|
|
14
|
+
* because it doesn't use the 'use client' directive pattern.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const content = generateConsentManagerTemplate('{ mode: "c15t", backendURL: "/api/c15t" }');
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateConsentManagerTemplate(optionsText: string): string;
|
|
22
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/pages/components.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA+D1E"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pages Directory layout template generator
|
|
3
3
|
* Handles updating Next.js Pages Directory _app.tsx files with ConsentManagerProvider
|
|
4
|
+
* and creates separate consent-manager component files
|
|
4
5
|
*/
|
|
5
6
|
import type { AvailablePackages } from '../../../../../context/framework-detection';
|
|
6
7
|
interface UpdatePagesLayoutOptions {
|
|
@@ -11,10 +12,34 @@ interface UpdatePagesLayoutOptions {
|
|
|
11
12
|
pkg: AvailablePackages;
|
|
12
13
|
proxyNextjs?: boolean;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
interface ComponentFilePaths {
|
|
16
|
+
consentManager: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Updates Next.js Pages Directory _app with consent management component
|
|
20
|
+
*
|
|
21
|
+
* @param options - Configuration options for the update
|
|
22
|
+
* @returns Information about the update operation including file paths
|
|
23
|
+
*
|
|
24
|
+
* @throws {Error} When component file cannot be created or _app cannot be updated
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* This function performs the following steps:
|
|
28
|
+
* 1. Locates the Pages Directory _app file
|
|
29
|
+
* 2. Checks if consent management is already configured
|
|
30
|
+
* 3. Creates consent-manager.tsx file
|
|
31
|
+
* 4. Adds ConsentManager import to _app
|
|
32
|
+
* 5. Wraps _app content with ConsentManager component
|
|
33
|
+
* 6. Adds helpful comment about withInitialC15TData
|
|
34
|
+
*
|
|
35
|
+
* Unlike App Directory, Pages Directory only needs one component file because
|
|
36
|
+
* it doesn't use the 'use client' directive pattern.
|
|
37
|
+
*/
|
|
38
|
+
export declare function updatePagesLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs, }: UpdatePagesLayoutOptions): Promise<{
|
|
15
39
|
updated: boolean;
|
|
16
40
|
filePath: string | null;
|
|
17
41
|
alreadyModified: boolean;
|
|
42
|
+
componentFiles?: ComponentFilePaths;
|
|
18
43
|
}>;
|
|
19
44
|
export {};
|
|
20
45
|
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/pages/layout.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/pages/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,UAAU,wBAAwB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC3B,cAAc,EAAE,MAAM,CAAC;CACvB;AAqRD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iBAAiB,CAAC,EACvC,WAAW,EACX,IAAI,EACJ,UAAU,EACV,UAAU,EACV,WAAW,GACX,EAAE,wBAAwB,GAAG,OAAO,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC,CA+ED"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component template generators for React
|
|
3
|
+
* Generates consent-manager.tsx component
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generates the consent-manager.tsx component template for React
|
|
7
|
+
*
|
|
8
|
+
* @param optionsText - The stringified options object for ConsentManagerProvider
|
|
9
|
+
* @returns The complete component file content
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* This component wraps the React app with consent management.
|
|
13
|
+
* Since React is client-only, we don't need to worry about SSR or separate client components.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const content = generateConsentManagerTemplate('{ mode: "c15t", backendURL: "https://your-instance.c15t.dev" }');
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateConsentManagerTemplate(optionsText: string): string;
|
|
21
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/templates/react/components.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6C1E"}
|
package/dist/index.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_os_74b4b876__ from "node:os";
|
|
|
10
10
|
import * as __WEBPACK_EXTERNAL_MODULE_posthog_node_1b07bdf4__ from "posthog-node";
|
|
11
11
|
import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:child_process";
|
|
12
12
|
import * as __WEBPACK_EXTERNAL_MODULE_node_events_0a6aefe7__ from "node:events";
|
|
13
|
-
import * as
|
|
13
|
+
import * as __WEBPACK_EXTERNAL_MODULE__c15t_logger_04a510d4__ from "@c15t/logger";
|
|
14
14
|
import * as __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__ from "ts-morph";
|
|
15
15
|
import * as __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_migrator_64e67b79__ from "@c15t/backend/v2/db/migrator";
|
|
16
16
|
import * as __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_schema_c18e255b__ from "@c15t/backend/v2/db/schema";
|
|
@@ -499,7 +499,7 @@ const logMessage = (logLevel, message, ...args)=>{
|
|
|
499
499
|
}
|
|
500
500
|
};
|
|
501
501
|
const createCliLogger = (level)=>{
|
|
502
|
-
const baseLogger = (0,
|
|
502
|
+
const baseLogger = (0, __WEBPACK_EXTERNAL_MODULE__c15t_logger_04a510d4__.createLogger)({
|
|
503
503
|
level,
|
|
504
504
|
appName: 'c15t',
|
|
505
505
|
log: (logLevel, message, ...args)=>{
|
|
@@ -538,82 +538,56 @@ function generateClientConfigContent(mode, backendURL, useEnvFile, logger) {
|
|
|
538
538
|
];
|
|
539
539
|
switch(mode){
|
|
540
540
|
case 'c15t':
|
|
541
|
-
configContent =
|
|
542
|
-
import
|
|
541
|
+
configContent = `
|
|
542
|
+
import {
|
|
543
|
+
type ConsentManagerOptions,
|
|
544
|
+
configureConsentManager,
|
|
545
|
+
createConsentManagerStore
|
|
546
|
+
} from "c15t";
|
|
543
547
|
|
|
544
|
-
export const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
ignoreGeoLocation: true, // Useful for development to always view the banner.
|
|
550
|
-
|
|
551
|
-
// Optional: Add callback functions for various events
|
|
552
|
-
callbacks: {
|
|
553
|
-
onConsentSet: (response) => {
|
|
554
|
-
console.log('Consent has been saved');
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
} satisfies ConsentManagerOptions;
|
|
548
|
+
export const consentManager = configureConsentManager({ mode: "c15t", backendURL: ${useEnvFile ? 'process.env.NEXT_PUBLIC_C15T_URL' : `'${backendURL || 'https://your-instance.c15t.dev'}'`}, });
|
|
549
|
+
export const store = createConsentManagerStore(consentManager, {
|
|
550
|
+
initialGdprTypes: ["necessary", "marketing"], // Optional: Specify which consent categories to show in the banner.
|
|
551
|
+
ignoreGeoLocation: true // Useful for development to always view the banner.
|
|
552
|
+
});
|
|
558
553
|
|
|
559
|
-
//
|
|
560
|
-
|
|
561
|
-
// {children}
|
|
562
|
-
// <CookieBanner />
|
|
563
|
-
// <ConsentManagerDialog />
|
|
564
|
-
// </ConsentManagerProvider>
|
|
554
|
+
store.getState().setConsent("marketing", true); // set consent to marketing
|
|
555
|
+
store.getState().showPopup;
|
|
565
556
|
`;
|
|
566
557
|
break;
|
|
567
558
|
case 'offline':
|
|
568
|
-
configContent =
|
|
569
|
-
import
|
|
559
|
+
configContent = `
|
|
560
|
+
import {
|
|
561
|
+
type ConsentManagerOptions,
|
|
562
|
+
configureConsentManager,
|
|
563
|
+
createConsentManagerStore
|
|
564
|
+
} from "c15t";
|
|
570
565
|
|
|
571
|
-
export const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
// Optional: Add callback functions for various events
|
|
576
|
-
callbacks: {
|
|
577
|
-
onConsentSet: (response) => {
|
|
578
|
-
console.log('Consent has been saved locally');
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
} satisfies ConsentManagerOptions;
|
|
566
|
+
export const consentManager = configureConsentManager({ mode: "offline" });
|
|
567
|
+
export const store = createConsentManagerStore(consentManager, {
|
|
568
|
+
initialGdprTypes: ["necessary", "marketing"], // Optional: Specify which consent categories to show in the banner.
|
|
569
|
+
});
|
|
582
570
|
|
|
583
|
-
//
|
|
584
|
-
//
|
|
585
|
-
|
|
586
|
-
// <CookieBanner />
|
|
587
|
-
// <ConsentManagerDialog />
|
|
588
|
-
// </ConsentManagerProvider>
|
|
571
|
+
store.getState().setConsent("marketing", true); // set consent to marketing
|
|
572
|
+
store.getState().showPopup; // should show popup?
|
|
573
|
+
|
|
589
574
|
`;
|
|
590
575
|
break;
|
|
591
576
|
case 'custom':
|
|
592
|
-
configContent =
|
|
593
|
-
|
|
594
|
-
|
|
577
|
+
configContent = `import {
|
|
578
|
+
type ConsentManagerOptions,
|
|
579
|
+
configureConsentManager,
|
|
580
|
+
createConsentManagerStore
|
|
581
|
+
} from "c15t";
|
|
595
582
|
|
|
596
|
-
export const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
// Optional: Add callback functions for various events
|
|
602
|
-
callbacks: {
|
|
603
|
-
onConsentSet: (response) => {
|
|
604
|
-
console.log('Consent has been saved');
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
} satisfies ConsentManagerOptions;
|
|
608
|
-
|
|
609
|
-
// Use in your app layout:
|
|
610
|
-
// <ConsentManagerProvider options={c15tConfig}>
|
|
611
|
-
// {children}
|
|
612
|
-
// <CookieBanner />
|
|
613
|
-
// <ConsentManagerDialog />
|
|
614
|
-
// </ConsentManagerProvider>
|
|
583
|
+
export const consentManager = configureConsentManager({ mode: "custom", endpointHandlers: createCustomHandlers(), });
|
|
584
|
+
export const store = createConsentManagerStore(consentManager, {
|
|
585
|
+
initialGdprTypes: ["necessary", "marketing"], // Optional: Specify which consent categories to show in the banner.
|
|
586
|
+
ignoreGeoLocation: true // Useful for development to always view the banner.
|
|
587
|
+
});
|
|
615
588
|
|
|
616
|
-
//
|
|
589
|
+
store.getState().setConsent("marketing", true); // set consent to marketing
|
|
590
|
+
store.getState().showPopup; // should show popup?
|
|
617
591
|
`;
|
|
618
592
|
break;
|
|
619
593
|
default:
|
|
@@ -665,21 +639,124 @@ function generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs) {
|
|
|
665
639
|
}`;
|
|
666
640
|
}
|
|
667
641
|
}
|
|
668
|
-
function
|
|
669
|
-
return
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
642
|
+
function generateConsentManagerTemplate(optionsText) {
|
|
643
|
+
return `import type { ReactNode } from 'react';
|
|
644
|
+
import {
|
|
645
|
+
ConsentManagerDialog,
|
|
646
|
+
ConsentManagerProvider,
|
|
647
|
+
CookieBanner,
|
|
648
|
+
} from '@c15t/nextjs';
|
|
649
|
+
// For client-only apps (non-SSR), you can use:
|
|
650
|
+
// import { ConsentManagerProvider } from '@c15t/nextjs/client';
|
|
651
|
+
import { ConsentManagerClient } from './consent-manager.client';
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Server-side rendered consent management wrapper for Next.js App Router
|
|
655
|
+
*
|
|
656
|
+
* This component provides SSR-compatible consent management by separating
|
|
657
|
+
* server-side configuration from client-side functionality. The server handles
|
|
658
|
+
* initial setup and configuration, while client-side features (callbacks,
|
|
659
|
+
* scripts) are delegated to the ConsentManagerClient component.
|
|
660
|
+
*
|
|
661
|
+
* @param props - Component properties
|
|
662
|
+
* @param props.children - Child components to render within the consent manager context
|
|
663
|
+
*
|
|
664
|
+
* @returns The consent manager provider with banner, dialog, and client wrapper
|
|
665
|
+
*
|
|
666
|
+
* @remarks
|
|
667
|
+
* This split architecture is necessary because certain options like callbacks
|
|
668
|
+
* and scripts cannot be serialized during server-side rendering. For
|
|
669
|
+
* client-only implementations, use \`<ConsentManagerProvider />\` from
|
|
670
|
+
* \`@c15t/nextjs/client\`.
|
|
671
|
+
*
|
|
672
|
+
* @example
|
|
673
|
+
* \`\`\`tsx
|
|
674
|
+
* // In your root layout.tsx
|
|
675
|
+
* import { ConsentManager } from './consent-manager';
|
|
676
|
+
*
|
|
677
|
+
* export default function RootLayout({ children }) {
|
|
678
|
+
* return (
|
|
679
|
+
* <html>
|
|
680
|
+
* <body>
|
|
681
|
+
* <ConsentManager>
|
|
682
|
+
* {children}
|
|
683
|
+
* </ConsentManager>
|
|
684
|
+
* </body>
|
|
685
|
+
* </html>
|
|
686
|
+
* );
|
|
687
|
+
* }
|
|
688
|
+
* \`\`\`
|
|
689
|
+
*/
|
|
690
|
+
export function ConsentManager({ children }: { children: ReactNode }) {
|
|
691
|
+
return (
|
|
692
|
+
<ConsentManagerProvider
|
|
693
|
+
options={${optionsText}}
|
|
694
|
+
>
|
|
695
|
+
<CookieBanner />
|
|
696
|
+
<ConsentManagerDialog />
|
|
697
|
+
<ConsentManagerClient>{children}</ConsentManagerClient>
|
|
698
|
+
</ConsentManagerProvider>
|
|
699
|
+
);
|
|
673
700
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
701
|
+
`;
|
|
702
|
+
}
|
|
703
|
+
function generateConsentManagerClientTemplate() {
|
|
704
|
+
return `'use client';
|
|
705
|
+
|
|
706
|
+
import type { ReactNode } from 'react';
|
|
707
|
+
import { ClientSideOptionsProvider } from '@c15t/nextjs/client';
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Client-side consent manager wrapper for handling scripts and callbacks
|
|
711
|
+
*
|
|
712
|
+
* This component is rendered on the client and provides the ability to:
|
|
713
|
+
* - Load integration scripts (Google Tag Manager, Meta Pixel, TikTok Pixel, etc.)
|
|
714
|
+
* - Handle client-side callbacks (onConsentSet, onError, onBannerFetched)
|
|
715
|
+
* - Manage script lifecycle (onLoad, onDelete)
|
|
716
|
+
*
|
|
717
|
+
* @param props - Component properties
|
|
718
|
+
* @param props.children - Child components to render within the client-side context
|
|
719
|
+
*
|
|
720
|
+
* @returns The client-side options provider with children
|
|
721
|
+
*
|
|
722
|
+
* @see https://c15t.com/docs/frameworks/next/callbacks
|
|
723
|
+
* @see https://c15t.com/docs/frameworks/next/script-loader
|
|
724
|
+
*/
|
|
725
|
+
export function ConsentManagerClient({
|
|
726
|
+
children,
|
|
727
|
+
}: {
|
|
728
|
+
children: ReactNode;
|
|
729
|
+
}) {
|
|
730
|
+
return (
|
|
731
|
+
<ClientSideOptionsProvider
|
|
732
|
+
// 📝 Add your integration scripts here
|
|
733
|
+
// Scripts are loaded when consent is given and removed when consent is revoked
|
|
734
|
+
scripts={[
|
|
735
|
+
// Example:
|
|
736
|
+
// googleTagManager({
|
|
737
|
+
// id: 'GTM-XXXXXX',
|
|
738
|
+
// script: {
|
|
739
|
+
// onLoad: () => console.log('GTM loaded'),
|
|
740
|
+
// },
|
|
741
|
+
// }),
|
|
742
|
+
]}
|
|
743
|
+
// 📝 Add your callbacks here
|
|
744
|
+
// Callbacks allow you to react to consent events
|
|
745
|
+
callbacks={{
|
|
746
|
+
// Example:
|
|
747
|
+
// onConsentSet(response) {
|
|
748
|
+
// console.log('Consent updated:', response);
|
|
749
|
+
// },
|
|
750
|
+
// onError(error) {
|
|
751
|
+
// console.error('Consent error:', error);
|
|
752
|
+
// },
|
|
753
|
+
}}
|
|
754
|
+
>
|
|
755
|
+
{children}
|
|
756
|
+
</ClientSideOptionsProvider>
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
`;
|
|
683
760
|
}
|
|
684
761
|
const HTML_TAG_REGEX = /<html[^>]*>([\s\S]*)<\/html>/;
|
|
685
762
|
const BODY_TAG_REGEX = /<body[^>]*>([\s\S]*)<\/body>/;
|
|
@@ -697,55 +774,78 @@ function findAppLayoutFile(project, projectRoot) {
|
|
|
697
774
|
if (files.length > 0) return files[0];
|
|
698
775
|
}
|
|
699
776
|
}
|
|
700
|
-
function
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
777
|
+
function getAppDirectory(layoutFilePath) {
|
|
778
|
+
const normalizedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].normalize(layoutFilePath);
|
|
779
|
+
const srcAppSegment = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'app');
|
|
780
|
+
if (normalizedPath.includes(srcAppSegment)) return __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'app');
|
|
781
|
+
return 'app';
|
|
782
|
+
}
|
|
783
|
+
function computeRelativeModuleSpecifier(fromFilePath, toFilePath) {
|
|
784
|
+
const fromDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fromFilePath);
|
|
785
|
+
let relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(fromDir, toFilePath);
|
|
786
|
+
relativePath = relativePath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
|
|
787
|
+
relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
|
|
788
|
+
if (!relativePath.startsWith('.')) relativePath = `./${relativePath}`;
|
|
789
|
+
return relativePath;
|
|
790
|
+
}
|
|
791
|
+
function addConsentManagerImport(layoutFile, consentManagerFilePath) {
|
|
792
|
+
const layoutFilePath = layoutFile.getFilePath();
|
|
793
|
+
const moduleSpecifier = computeRelativeModuleSpecifier(layoutFilePath, consentManagerFilePath);
|
|
794
|
+
const existingImports = layoutFile.getImportDeclarations();
|
|
795
|
+
const hasConsentManagerImport = existingImports.some((importDecl)=>{
|
|
796
|
+
const existingSpec = importDecl.getModuleSpecifierValue();
|
|
797
|
+
return existingSpec === moduleSpecifier || existingSpec.endsWith('consent-manager') || existingSpec.endsWith('consent-manager.tsx');
|
|
798
|
+
});
|
|
799
|
+
if (!hasConsentManagerImport) layoutFile.addImportDeclaration({
|
|
800
|
+
namedImports: [
|
|
801
|
+
'ConsentManager'
|
|
802
|
+
],
|
|
803
|
+
moduleSpecifier
|
|
716
804
|
});
|
|
717
|
-
if ('custom' === mode) for (const customImport of getCustomModeImports())layoutFile.addImportDeclaration(customImport);
|
|
718
805
|
}
|
|
719
|
-
function wrapAppJsxContent(originalJsx
|
|
806
|
+
function wrapAppJsxContent(originalJsx) {
|
|
720
807
|
const hasHtmlTag = originalJsx.includes('<html') || originalJsx.includes('</html>');
|
|
721
808
|
const hasBodyTag = originalJsx.includes('<body') || originalJsx.includes('</body>');
|
|
722
|
-
const
|
|
723
|
-
<
|
|
724
|
-
<CookieBanner />
|
|
725
|
-
<ConsentManagerDialog />
|
|
809
|
+
const consentWrapper = (content)=>`
|
|
810
|
+
<ConsentManager>
|
|
726
811
|
${content}
|
|
727
|
-
</
|
|
812
|
+
</ConsentManager>
|
|
728
813
|
`;
|
|
729
814
|
if (hasHtmlTag) {
|
|
730
815
|
const htmlMatch = originalJsx.match(HTML_TAG_REGEX);
|
|
731
816
|
const htmlContent = htmlMatch?.[1] || '';
|
|
732
|
-
if (!htmlContent) return
|
|
817
|
+
if (!htmlContent) return consentWrapper(originalJsx);
|
|
733
818
|
const bodyMatch = htmlContent.match(BODY_TAG_REGEX);
|
|
734
|
-
if (!bodyMatch) return originalJsx.replace(HTML_CONTENT_REGEX, `<html>${
|
|
819
|
+
if (!bodyMatch) return originalJsx.replace(HTML_CONTENT_REGEX, `<html>${consentWrapper('$1')}</html>`);
|
|
735
820
|
const bodyContent = bodyMatch[1] || '';
|
|
736
821
|
const bodyOpeningTag = originalJsx.match(BODY_OPENING_TAG_REGEX)?.[0] || '<body>';
|
|
737
|
-
return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${
|
|
822
|
+
return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${consentWrapper(bodyContent)}</body>`);
|
|
738
823
|
}
|
|
739
824
|
if (hasBodyTag) {
|
|
740
825
|
const bodyMatch = originalJsx.match(BODY_TAG_REGEX);
|
|
741
826
|
const bodyContent = bodyMatch?.[1] || '';
|
|
742
|
-
if (!bodyContent) return
|
|
827
|
+
if (!bodyContent) return consentWrapper(originalJsx);
|
|
743
828
|
const bodyOpeningTag = originalJsx.match(BODY_OPENING_TAG_REGEX)?.[0] || '<body>';
|
|
744
|
-
return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${
|
|
745
|
-
}
|
|
746
|
-
return
|
|
829
|
+
return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${consentWrapper(bodyContent)}</body>`);
|
|
830
|
+
}
|
|
831
|
+
return consentWrapper(originalJsx);
|
|
832
|
+
}
|
|
833
|
+
async function createConsentManagerComponents(projectRoot, appDir, optionsText) {
|
|
834
|
+
const appDirPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, appDir);
|
|
835
|
+
const consentManagerContent = generateConsentManagerTemplate(optionsText);
|
|
836
|
+
const consentManagerClientContent = generateConsentManagerClientTemplate();
|
|
837
|
+
const consentManagerPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(appDirPath, 'consent-manager.tsx');
|
|
838
|
+
const consentManagerClientPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(appDirPath, 'consent-manager.client.tsx');
|
|
839
|
+
await Promise.all([
|
|
840
|
+
__WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerPath, consentManagerContent, 'utf-8'),
|
|
841
|
+
__WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerClientPath, consentManagerClientContent, 'utf-8')
|
|
842
|
+
]);
|
|
843
|
+
return {
|
|
844
|
+
consentManager: consentManagerPath,
|
|
845
|
+
consentManagerClient: consentManagerClientPath
|
|
846
|
+
};
|
|
747
847
|
}
|
|
748
|
-
async function updateAppLayout({ projectRoot, mode,
|
|
848
|
+
async function updateAppLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs }) {
|
|
749
849
|
const project = new __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.Project();
|
|
750
850
|
const layoutFile = findAppLayoutFile(project, projectRoot);
|
|
751
851
|
if (!layoutFile) return {
|
|
@@ -753,37 +853,105 @@ async function updateAppLayout({ projectRoot, mode, pkg, backendURL, useEnvFile,
|
|
|
753
853
|
filePath: null,
|
|
754
854
|
alreadyModified: false
|
|
755
855
|
};
|
|
856
|
+
const layoutFilePath = layoutFile.getFilePath();
|
|
857
|
+
const appDir = getAppDirectory(layoutFilePath);
|
|
756
858
|
const existingImports = layoutFile.getImportDeclarations();
|
|
757
|
-
const
|
|
758
|
-
if (
|
|
859
|
+
const hasConsentManagerImport = existingImports.some((importDecl)=>'./consent-manager' === importDecl.getModuleSpecifierValue() || './consent-manager.tsx' === importDecl.getModuleSpecifierValue());
|
|
860
|
+
if (hasConsentManagerImport) return {
|
|
759
861
|
updated: false,
|
|
760
|
-
filePath:
|
|
862
|
+
filePath: layoutFilePath,
|
|
761
863
|
alreadyModified: true
|
|
762
864
|
};
|
|
763
|
-
updateAppImports(layoutFile, pkg, mode);
|
|
764
865
|
const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
|
|
866
|
+
const componentFiles = await createConsentManagerComponents(projectRoot, appDir, optionsText);
|
|
867
|
+
addConsentManagerImport(layoutFile, componentFiles.consentManager);
|
|
765
868
|
const returnStatement = layoutFile.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
|
|
766
869
|
if (!returnStatement) return {
|
|
767
870
|
updated: false,
|
|
768
|
-
filePath:
|
|
871
|
+
filePath: layoutFilePath,
|
|
769
872
|
alreadyModified: false
|
|
770
873
|
};
|
|
771
874
|
const expression = returnStatement.getExpression();
|
|
772
875
|
if (!expression) return {
|
|
773
876
|
updated: false,
|
|
774
|
-
filePath:
|
|
877
|
+
filePath: layoutFilePath,
|
|
775
878
|
alreadyModified: false
|
|
776
879
|
};
|
|
777
880
|
const originalJsx = expression.getText();
|
|
778
|
-
const newJsx = wrapAppJsxContent(originalJsx
|
|
881
|
+
const newJsx = wrapAppJsxContent(originalJsx);
|
|
779
882
|
returnStatement.replaceWithText(`return ${newJsx}`);
|
|
780
883
|
await layoutFile.save();
|
|
781
884
|
return {
|
|
782
885
|
updated: true,
|
|
783
|
-
filePath:
|
|
784
|
-
alreadyModified: false
|
|
886
|
+
filePath: layoutFilePath,
|
|
887
|
+
alreadyModified: false,
|
|
888
|
+
componentFiles
|
|
785
889
|
};
|
|
786
890
|
}
|
|
891
|
+
function components_generateConsentManagerTemplate(optionsText) {
|
|
892
|
+
return `import type { ReactNode } from 'react';
|
|
893
|
+
import {
|
|
894
|
+
ConsentManagerDialog,
|
|
895
|
+
ConsentManagerProvider,
|
|
896
|
+
CookieBanner,
|
|
897
|
+
} from '@c15t/nextjs/pages';
|
|
898
|
+
// For client-only apps (non-SSR), you can use:
|
|
899
|
+
// import { ConsentManagerProvider } from '@c15t/nextjs/client';
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Consent management wrapper for Next.js Pages Router
|
|
903
|
+
*
|
|
904
|
+
* This component wraps your app with consent management functionality,
|
|
905
|
+
* including the cookie banner, consent dialog, and provider.
|
|
906
|
+
*
|
|
907
|
+
* @param props - Component properties
|
|
908
|
+
* @param props.children - Child components to render within the consent manager context
|
|
909
|
+
* @param props.initialData - Initial consent data from server-side props (optional)
|
|
910
|
+
*
|
|
911
|
+
* @returns The consent manager provider with banner and dialog
|
|
912
|
+
*
|
|
913
|
+
* @remarks
|
|
914
|
+
* To get initial server-side data on other pages, use:
|
|
915
|
+
* \`\`\`tsx
|
|
916
|
+
* import { withInitialC15TData } from '@c15t/nextjs/pages';
|
|
917
|
+
*
|
|
918
|
+
* export const getServerSideProps = withInitialC15TData('/api/c15t');
|
|
919
|
+
* \`\`\`
|
|
920
|
+
*
|
|
921
|
+
* @example
|
|
922
|
+
* \`\`\`tsx
|
|
923
|
+
* // In your pages/_app.tsx
|
|
924
|
+
* import { ConsentManager } from './consent-manager';
|
|
925
|
+
*
|
|
926
|
+
* export default function MyApp({ Component, pageProps }) {
|
|
927
|
+
* return (
|
|
928
|
+
* <ConsentManager initialData={pageProps.initialC15TData}>
|
|
929
|
+
* <Component {...pageProps} />
|
|
930
|
+
* </ConsentManager>
|
|
931
|
+
* );
|
|
932
|
+
* }
|
|
933
|
+
* \`\`\`
|
|
934
|
+
*/
|
|
935
|
+
export function ConsentManager({
|
|
936
|
+
children,
|
|
937
|
+
initialData,
|
|
938
|
+
}: {
|
|
939
|
+
children: ReactNode;
|
|
940
|
+
initialData?: unknown;
|
|
941
|
+
}) {
|
|
942
|
+
return (
|
|
943
|
+
<ConsentManagerProvider
|
|
944
|
+
initialData={initialData}
|
|
945
|
+
options={${optionsText}}
|
|
946
|
+
>
|
|
947
|
+
<CookieBanner />
|
|
948
|
+
<ConsentManagerDialog />
|
|
949
|
+
{children}
|
|
950
|
+
</ConsentManagerProvider>
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
`;
|
|
954
|
+
}
|
|
787
955
|
function findPagesAppFile(project, projectRoot) {
|
|
788
956
|
const appPatterns = [
|
|
789
957
|
'pages/_app.tsx',
|
|
@@ -796,42 +964,55 @@ function findPagesAppFile(project, projectRoot) {
|
|
|
796
964
|
if (files.length > 0) return files[0];
|
|
797
965
|
}
|
|
798
966
|
}
|
|
799
|
-
function
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
967
|
+
function getPagesDirectory(appFilePath) {
|
|
968
|
+
const normalizedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].normalize(appFilePath);
|
|
969
|
+
const srcPagesSegment = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'pages');
|
|
970
|
+
if (normalizedPath.includes(srcPagesSegment)) return __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'pages');
|
|
971
|
+
return 'pages';
|
|
972
|
+
}
|
|
973
|
+
function layout_computeRelativeModuleSpecifier(fromFilePath, toFilePath) {
|
|
974
|
+
const fromDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fromFilePath);
|
|
975
|
+
let relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(fromDir, toFilePath);
|
|
976
|
+
relativePath = relativePath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
|
|
977
|
+
relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
|
|
978
|
+
if (!relativePath.startsWith('.')) relativePath = `./${relativePath}`;
|
|
979
|
+
return relativePath;
|
|
980
|
+
}
|
|
981
|
+
function layout_addConsentManagerImport(appFile, consentManagerFilePath) {
|
|
982
|
+
const appFilePath = appFile.getFilePath();
|
|
983
|
+
const moduleSpecifier = layout_computeRelativeModuleSpecifier(appFilePath, consentManagerFilePath);
|
|
984
|
+
const existingImports = appFile.getImportDeclarations();
|
|
985
|
+
const hasConsentManagerImport = existingImports.some((importDecl)=>{
|
|
986
|
+
const existingSpec = importDecl.getModuleSpecifierValue();
|
|
987
|
+
return existingSpec === moduleSpecifier || existingSpec.endsWith('consent-manager') || existingSpec.endsWith('consent-manager.tsx');
|
|
988
|
+
});
|
|
989
|
+
if (!hasConsentManagerImport) appFile.addImportDeclaration({
|
|
990
|
+
namedImports: [
|
|
991
|
+
'ConsentManager'
|
|
992
|
+
],
|
|
993
|
+
moduleSpecifier
|
|
816
994
|
});
|
|
817
|
-
if ('custom' === mode) for (const customImport of getCustomModeImports())appFile.addImportDeclaration(customImport);
|
|
818
995
|
}
|
|
819
|
-
function wrapPagesJsxContent(originalJsx
|
|
996
|
+
function wrapPagesJsxContent(originalJsx) {
|
|
820
997
|
const trimmedJsx = originalJsx.trim();
|
|
821
998
|
const hasParentheses = trimmedJsx.startsWith('(') && trimmedJsx.endsWith(')');
|
|
822
999
|
const cleanJsx = hasParentheses ? trimmedJsx.slice(1, -1).trim() : originalJsx;
|
|
823
1000
|
const wrappedContent = `
|
|
824
|
-
<
|
|
825
|
-
initialData={pageProps.initialC15TData}
|
|
826
|
-
options={${optionsText}}
|
|
827
|
-
>
|
|
828
|
-
<CookieBanner />
|
|
829
|
-
<ConsentManagerDialog />
|
|
1001
|
+
<ConsentManager initialData={pageProps.initialC15TData}>
|
|
830
1002
|
${cleanJsx}
|
|
831
|
-
</
|
|
1003
|
+
</ConsentManager>
|
|
832
1004
|
`;
|
|
833
1005
|
return `(${wrappedContent})`;
|
|
834
1006
|
}
|
|
1007
|
+
async function createConsentManagerComponent(projectRoot, pagesDir, optionsText) {
|
|
1008
|
+
const pagesDirPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, pagesDir);
|
|
1009
|
+
const consentManagerContent = components_generateConsentManagerTemplate(optionsText);
|
|
1010
|
+
const consentManagerPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(pagesDirPath, 'consent-manager.tsx');
|
|
1011
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerPath, consentManagerContent, 'utf-8');
|
|
1012
|
+
return {
|
|
1013
|
+
consentManager: consentManagerPath
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
835
1016
|
function addServerSideDataComment(appFile, backendURL, useEnvFile, proxyNextjs) {
|
|
836
1017
|
const existingComments = appFile.getLeadingCommentRanges();
|
|
837
1018
|
let urlExample;
|
|
@@ -864,7 +1045,7 @@ function updateAppComponentTyping(appFile) {
|
|
|
864
1045
|
});
|
|
865
1046
|
}
|
|
866
1047
|
}
|
|
867
|
-
async function updatePagesLayout({ projectRoot, mode,
|
|
1048
|
+
async function updatePagesLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs }) {
|
|
868
1049
|
const project = new __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.Project();
|
|
869
1050
|
const appFile = findPagesAppFile(project, projectRoot);
|
|
870
1051
|
if (!appFile) return {
|
|
@@ -872,38 +1053,41 @@ async function updatePagesLayout({ projectRoot, mode, pkg, backendURL, useEnvFil
|
|
|
872
1053
|
filePath: null,
|
|
873
1054
|
alreadyModified: false
|
|
874
1055
|
};
|
|
1056
|
+
const appFilePath = appFile.getFilePath();
|
|
1057
|
+
const pagesDir = getPagesDirectory(appFilePath);
|
|
875
1058
|
const existingImports = appFile.getImportDeclarations();
|
|
876
|
-
const
|
|
877
|
-
|
|
878
|
-
if (hasPackageImport) return {
|
|
1059
|
+
const hasConsentManagerImport = existingImports.some((importDecl)=>'./consent-manager' === importDecl.getModuleSpecifierValue() || './consent-manager.tsx' === importDecl.getModuleSpecifierValue());
|
|
1060
|
+
if (hasConsentManagerImport) return {
|
|
879
1061
|
updated: false,
|
|
880
|
-
filePath:
|
|
1062
|
+
filePath: appFilePath,
|
|
881
1063
|
alreadyModified: true
|
|
882
1064
|
};
|
|
883
|
-
|
|
1065
|
+
const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
|
|
1066
|
+
const componentFiles = await createConsentManagerComponent(projectRoot, pagesDir, optionsText);
|
|
1067
|
+
layout_addConsentManagerImport(appFile, componentFiles.consentManager);
|
|
884
1068
|
updateAppComponentTyping(appFile);
|
|
885
1069
|
addServerSideDataComment(appFile, backendURL, useEnvFile, proxyNextjs);
|
|
886
|
-
const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
|
|
887
1070
|
const returnStatement = appFile.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
|
|
888
1071
|
if (!returnStatement) return {
|
|
889
1072
|
updated: false,
|
|
890
|
-
filePath:
|
|
1073
|
+
filePath: appFilePath,
|
|
891
1074
|
alreadyModified: false
|
|
892
1075
|
};
|
|
893
1076
|
const expression = returnStatement.getExpression();
|
|
894
1077
|
if (!expression) return {
|
|
895
1078
|
updated: false,
|
|
896
|
-
filePath:
|
|
1079
|
+
filePath: appFilePath,
|
|
897
1080
|
alreadyModified: false
|
|
898
1081
|
};
|
|
899
1082
|
const originalJsx = expression.getText();
|
|
900
|
-
const newJsx = wrapPagesJsxContent(originalJsx
|
|
1083
|
+
const newJsx = wrapPagesJsxContent(originalJsx);
|
|
901
1084
|
returnStatement.replaceWithText(`return ${newJsx}`);
|
|
902
1085
|
await appFile.save();
|
|
903
1086
|
return {
|
|
904
1087
|
updated: true,
|
|
905
|
-
filePath:
|
|
906
|
-
alreadyModified: false
|
|
1088
|
+
filePath: appFilePath,
|
|
1089
|
+
alreadyModified: false,
|
|
1090
|
+
componentFiles
|
|
907
1091
|
};
|
|
908
1092
|
}
|
|
909
1093
|
function detectNextJsStructure(projectRoot) {
|
|
@@ -945,57 +1129,119 @@ async function updateNextLayout(options) {
|
|
|
945
1129
|
structureType
|
|
946
1130
|
};
|
|
947
1131
|
}
|
|
948
|
-
function
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1132
|
+
function react_components_generateConsentManagerTemplate(optionsText) {
|
|
1133
|
+
return `import type { ReactNode } from 'react';
|
|
1134
|
+
import {
|
|
1135
|
+
ConsentManagerDialog,
|
|
1136
|
+
ConsentManagerProvider,
|
|
1137
|
+
CookieBanner,
|
|
1138
|
+
} from '@c15t/react';
|
|
1139
|
+
|
|
1140
|
+
/**
|
|
1141
|
+
* Consent management wrapper for React
|
|
1142
|
+
*
|
|
1143
|
+
* This component wraps your app with consent management functionality,
|
|
1144
|
+
* including the cookie banner, consent dialog, and provider.
|
|
1145
|
+
*
|
|
1146
|
+
* @param props - Component properties
|
|
1147
|
+
* @param props.children - Child components to render within the consent manager context
|
|
1148
|
+
*
|
|
1149
|
+
* @returns The consent manager provider with banner and dialog
|
|
1150
|
+
*
|
|
1151
|
+
* @example
|
|
1152
|
+
* \`\`\`tsx
|
|
1153
|
+
* // In your App.tsx
|
|
1154
|
+
* import { ConsentManager } from './consent-manager';
|
|
1155
|
+
*
|
|
1156
|
+
* export default function App() {
|
|
1157
|
+
* return (
|
|
1158
|
+
* <ConsentManager>
|
|
1159
|
+
* <YourApp />
|
|
1160
|
+
* </ConsentManager>
|
|
1161
|
+
* );
|
|
1162
|
+
* }
|
|
1163
|
+
* \`\`\`
|
|
1164
|
+
*/
|
|
1165
|
+
export function ConsentManager({ children }: { children: ReactNode }) {
|
|
1166
|
+
return (
|
|
1167
|
+
<ConsentManagerProvider
|
|
1168
|
+
options={${optionsText}}
|
|
1169
|
+
>
|
|
1170
|
+
<CookieBanner />
|
|
1171
|
+
<ConsentManagerDialog />
|
|
1172
|
+
{children}
|
|
1173
|
+
</ConsentManagerProvider>
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
`;
|
|
1177
|
+
}
|
|
1178
|
+
function templates_layout_computeRelativeModuleSpecifier(fromFilePath, toFilePath) {
|
|
1179
|
+
const fromDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fromFilePath);
|
|
1180
|
+
let relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(fromDir, toFilePath);
|
|
1181
|
+
relativePath = relativePath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
|
|
1182
|
+
relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
|
|
1183
|
+
if (!relativePath.startsWith('.')) relativePath = `./${relativePath}`;
|
|
1184
|
+
return relativePath;
|
|
1185
|
+
}
|
|
1186
|
+
function templates_layout_addConsentManagerImport(layoutFile, consentManagerFilePath) {
|
|
1187
|
+
const layoutFilePath = layoutFile.getFilePath();
|
|
1188
|
+
const moduleSpecifier = templates_layout_computeRelativeModuleSpecifier(layoutFilePath, consentManagerFilePath);
|
|
1189
|
+
const existingImports = layoutFile.getImportDeclarations();
|
|
1190
|
+
const hasConsentManagerImport = existingImports.some((importDecl)=>{
|
|
1191
|
+
const existingSpec = importDecl.getModuleSpecifierValue();
|
|
1192
|
+
return existingSpec === moduleSpecifier || existingSpec.endsWith('consent-manager') || existingSpec.endsWith('consent-manager.tsx');
|
|
1193
|
+
});
|
|
1194
|
+
if (!hasConsentManagerImport) layoutFile.addImportDeclaration({
|
|
1195
|
+
namedImports: [
|
|
1196
|
+
'ConsentManager'
|
|
1197
|
+
],
|
|
1198
|
+
moduleSpecifier
|
|
964
1199
|
});
|
|
965
|
-
if ('custom' === mode) for (const customImport of getCustomModeImports())layoutFile.addImportDeclaration(customImport);
|
|
966
1200
|
}
|
|
967
|
-
function
|
|
1201
|
+
function getSourceDirectory(layoutFilePath) {
|
|
1202
|
+
const normalizedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].normalize(layoutFilePath);
|
|
1203
|
+
const segments = normalizedPath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep);
|
|
1204
|
+
if (segments.includes('src')) return 'src';
|
|
1205
|
+
return '';
|
|
1206
|
+
}
|
|
1207
|
+
function updateGenericReactJsx(layoutFile) {
|
|
968
1208
|
const functionDeclarations = layoutFile.getFunctions();
|
|
969
1209
|
const variableDeclarations = layoutFile.getVariableDeclarations();
|
|
970
1210
|
for (const func of functionDeclarations){
|
|
971
1211
|
const returnStatement = func.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
|
|
972
|
-
if (returnStatement) return
|
|
1212
|
+
if (returnStatement) return wrapReturnStatementWithConsentManager(returnStatement);
|
|
973
1213
|
}
|
|
974
1214
|
for (const varDecl of variableDeclarations){
|
|
975
1215
|
const initializer = varDecl.getInitializer();
|
|
976
1216
|
if (initializer) {
|
|
977
1217
|
const returnStatement = initializer.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
|
|
978
|
-
if (returnStatement) return
|
|
1218
|
+
if (returnStatement) return wrapReturnStatementWithConsentManager(returnStatement);
|
|
979
1219
|
}
|
|
980
1220
|
}
|
|
981
1221
|
return false;
|
|
982
1222
|
}
|
|
983
|
-
function
|
|
1223
|
+
function wrapReturnStatementWithConsentManager(returnStatement) {
|
|
984
1224
|
const expression = returnStatement.getExpression();
|
|
985
1225
|
if (!expression) return false;
|
|
986
1226
|
const originalJsx = expression.getText();
|
|
987
|
-
const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
|
|
988
1227
|
const newJsx = `(
|
|
989
|
-
<
|
|
990
|
-
<CookieBanner />
|
|
991
|
-
<ConsentManagerDialog />
|
|
1228
|
+
<ConsentManager>
|
|
992
1229
|
${originalJsx}
|
|
993
|
-
</
|
|
1230
|
+
</ConsentManager>
|
|
994
1231
|
)`;
|
|
995
1232
|
returnStatement.replaceWithText(`return ${newJsx}`);
|
|
996
1233
|
return true;
|
|
997
1234
|
}
|
|
998
|
-
async function
|
|
1235
|
+
async function layout_createConsentManagerComponent(projectRoot, sourceDir, optionsText) {
|
|
1236
|
+
const targetDir = sourceDir ? __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, sourceDir) : projectRoot;
|
|
1237
|
+
const consentManagerContent = react_components_generateConsentManagerTemplate(optionsText);
|
|
1238
|
+
const consentManagerPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(targetDir, 'consent-manager.tsx');
|
|
1239
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerPath, consentManagerContent, 'utf-8');
|
|
1240
|
+
return {
|
|
1241
|
+
consentManager: consentManagerPath
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
async function updateGenericReactLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs }) {
|
|
999
1245
|
const layoutPatterns = [
|
|
1000
1246
|
'app.tsx',
|
|
1001
1247
|
'App.tsx',
|
|
@@ -1024,27 +1270,32 @@ async function updateGenericReactLayout({ projectRoot, mode, pkg, backendURL, us
|
|
|
1024
1270
|
filePath: null,
|
|
1025
1271
|
alreadyModified: false
|
|
1026
1272
|
};
|
|
1273
|
+
const layoutFilePath = layoutFile.getFilePath();
|
|
1274
|
+
const sourceDir = getSourceDirectory(layoutFilePath);
|
|
1027
1275
|
const existingImports = layoutFile.getImportDeclarations();
|
|
1028
|
-
const
|
|
1029
|
-
if (
|
|
1276
|
+
const hasConsentManagerImport = existingImports.some((importDecl)=>'./consent-manager' === importDecl.getModuleSpecifierValue() || './consent-manager.tsx' === importDecl.getModuleSpecifierValue());
|
|
1277
|
+
if (hasConsentManagerImport) return {
|
|
1030
1278
|
updated: false,
|
|
1031
|
-
filePath:
|
|
1279
|
+
filePath: layoutFilePath,
|
|
1032
1280
|
alreadyModified: true
|
|
1033
1281
|
};
|
|
1034
1282
|
try {
|
|
1035
|
-
|
|
1036
|
-
const
|
|
1283
|
+
const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
|
|
1284
|
+
const componentFiles = await layout_createConsentManagerComponent(projectRoot, sourceDir, optionsText);
|
|
1285
|
+
templates_layout_addConsentManagerImport(layoutFile, componentFiles.consentManager);
|
|
1286
|
+
const updated = updateGenericReactJsx(layoutFile);
|
|
1037
1287
|
if (updated) {
|
|
1038
1288
|
await layoutFile.save();
|
|
1039
1289
|
return {
|
|
1040
1290
|
updated: true,
|
|
1041
|
-
filePath:
|
|
1042
|
-
alreadyModified: false
|
|
1291
|
+
filePath: layoutFilePath,
|
|
1292
|
+
alreadyModified: false,
|
|
1293
|
+
componentFiles
|
|
1043
1294
|
};
|
|
1044
1295
|
}
|
|
1045
1296
|
return {
|
|
1046
1297
|
updated: false,
|
|
1047
|
-
filePath:
|
|
1298
|
+
filePath: layoutFilePath,
|
|
1048
1299
|
alreadyModified: false
|
|
1049
1300
|
};
|
|
1050
1301
|
} catch (error) {
|
|
@@ -1057,7 +1308,8 @@ async function updateReactLayout(options) {
|
|
|
1057
1308
|
if (nextResult.structureType) return {
|
|
1058
1309
|
updated: nextResult.updated,
|
|
1059
1310
|
filePath: nextResult.filePath,
|
|
1060
|
-
alreadyModified: nextResult.alreadyModified
|
|
1311
|
+
alreadyModified: nextResult.alreadyModified,
|
|
1312
|
+
componentFiles: nextResult.componentFiles
|
|
1061
1313
|
};
|
|
1062
1314
|
}
|
|
1063
1315
|
return updateGenericReactLayout(options);
|
|
@@ -1232,7 +1484,7 @@ function addNewRewritesMethod(configObject, destination, isTemplateLiteral) {
|
|
|
1232
1484
|
return true;
|
|
1233
1485
|
}
|
|
1234
1486
|
async function handleReactLayout(options) {
|
|
1235
|
-
const { projectRoot, mode, backendURL, useEnvFile, proxyNextjs, pkg, spinner } = options;
|
|
1487
|
+
const { projectRoot, mode, backendURL, useEnvFile, proxyNextjs, pkg, spinner, cwd } = options;
|
|
1236
1488
|
spinner.start('Updating layout file...');
|
|
1237
1489
|
const layoutResult = await updateReactLayout({
|
|
1238
1490
|
projectRoot,
|
|
@@ -1244,13 +1496,31 @@ async function handleReactLayout(options) {
|
|
|
1244
1496
|
});
|
|
1245
1497
|
const spinnerMessage = ()=>{
|
|
1246
1498
|
if (layoutResult.alreadyModified) return {
|
|
1247
|
-
message: '
|
|
1248
|
-
type: 'info'
|
|
1249
|
-
};
|
|
1250
|
-
if (layoutResult.updated) return {
|
|
1251
|
-
message: `Layout file updated: ${layoutResult.filePath}`,
|
|
1499
|
+
message: 'ConsentManager is already imported. Skipped layout file update.',
|
|
1252
1500
|
type: 'info'
|
|
1253
1501
|
};
|
|
1502
|
+
if (layoutResult.updated) {
|
|
1503
|
+
const typedResult = layoutResult;
|
|
1504
|
+
if (typedResult.componentFiles) {
|
|
1505
|
+
const relativeConsentManager = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, typedResult.componentFiles.consentManager);
|
|
1506
|
+
const relativeLayout = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, layoutResult.filePath || '');
|
|
1507
|
+
if (typedResult.componentFiles.consentManagerClient) {
|
|
1508
|
+
const relativeConsentManagerClient = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, typedResult.componentFiles.consentManagerClient);
|
|
1509
|
+
return {
|
|
1510
|
+
message: `Layout setup complete!\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConsentManager)}\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConsentManagerClient)}\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Updated: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeLayout)}`,
|
|
1511
|
+
type: 'info'
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
return {
|
|
1515
|
+
message: `Layout setup complete!\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConsentManager)}\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Updated: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeLayout)}`,
|
|
1516
|
+
type: 'info'
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
return {
|
|
1520
|
+
message: `Layout file updated: ${layoutResult.filePath}`,
|
|
1521
|
+
type: 'info'
|
|
1522
|
+
};
|
|
1523
|
+
}
|
|
1254
1524
|
return {
|
|
1255
1525
|
message: 'Layout file not updated.',
|
|
1256
1526
|
type: 'error'
|
|
@@ -1337,7 +1607,8 @@ async function generateFiles({ context, mode, spinner, useEnvFile, proxyNextjs,
|
|
|
1337
1607
|
useEnvFile,
|
|
1338
1608
|
proxyNextjs,
|
|
1339
1609
|
pkg,
|
|
1340
|
-
spinner
|
|
1610
|
+
spinner,
|
|
1611
|
+
cwd: context.cwd
|
|
1341
1612
|
});
|
|
1342
1613
|
result.layoutUpdated = layoutResult.layoutUpdated;
|
|
1343
1614
|
result.layoutPath = layoutResult.layoutPath;
|
|
@@ -2203,11 +2474,11 @@ async function handleGitHubStar(context) {
|
|
|
2203
2474
|
|
|
2204
2475
|
We're building c15t as an ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].bold('open source')} project to make consent management more accessible.
|
|
2205
2476
|
If you find this useful, we'd really appreciate a GitHub star - it helps others discover the project!`, '🎉 Thanks for using c15t');
|
|
2206
|
-
const
|
|
2477
|
+
const shouldOpenGitHub = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
2207
2478
|
message: 'Would you like to star c15t on GitHub now?',
|
|
2208
2479
|
initialValue: true
|
|
2209
2480
|
});
|
|
2210
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(
|
|
2481
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(shouldOpenGitHub)) {
|
|
2211
2482
|
telemetry.trackEvent(TelemetryEventName.ONBOARDING_GITHUB_STAR, {
|
|
2212
2483
|
action: 'cancelled'
|
|
2213
2484
|
});
|
|
@@ -2217,9 +2488,9 @@ If you find this useful, we'd really appreciate a GitHub star - it helps others
|
|
|
2217
2488
|
});
|
|
2218
2489
|
}
|
|
2219
2490
|
telemetry.trackEvent(TelemetryEventName.ONBOARDING_GITHUB_STAR, {
|
|
2220
|
-
action:
|
|
2491
|
+
action: shouldOpenGitHub ? 'opened_browser' : 'declined'
|
|
2221
2492
|
});
|
|
2222
|
-
if (
|
|
2493
|
+
if (shouldOpenGitHub) try {
|
|
2223
2494
|
__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.note('Your support helps us continue improving c15t.\nThank you for being part of our community!', '⭐ Star Us on GitHub');
|
|
2224
2495
|
await (0, __WEBPACK_EXTERNAL_MODULE_open__["default"])('https://github.com/c15t/c15t');
|
|
2225
2496
|
logger.success('GitHub repository opened. Thank you for your support!');
|
|
@@ -2656,7 +2927,7 @@ const src_commands = [
|
|
|
2656
2927
|
},
|
|
2657
2928
|
{
|
|
2658
2929
|
name: 'github',
|
|
2659
|
-
label: '
|
|
2930
|
+
label: 'GitHub',
|
|
2660
2931
|
hint: 'Star us on GitHub',
|
|
2661
2932
|
description: 'Open our GitHub repository to give us a star.',
|
|
2662
2933
|
action: async (context)=>{
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAKzD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D,eAAO,MAAM,cAAc,EAAE,QAAQ,EAAuC,CAAC;AAC7E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;AAG/C,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvD,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtD;AASD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC5B,UAAU,QAAQ,GAAG,MAAM,EAC3B,SAAS,OAAO,EAChB,OAAM,OAAO,EAAO,KAClB,MA6BF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GACtB,UAAU,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,EAClD,SAAS,OAAO,EAChB,GAAG,MAAM,OAAO,EAAE,KAChB,IAqBF,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,OAAO,QAAQ,KAAG,SAgDjD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/utils/telemetry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/utils/telemetry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAMvC,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DrB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAC7B,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAE9D;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAqB;IAEnC;;;;OAIG;gBACS,OAAO,CAAC,EAAE,gBAAgB;IA+BtC;;;;;OAKG;IACH,UAAU,CACT,SAAS,EAAE,kBAAkB,EAC7B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GACpE,IAAI;IA4CP;;;;;;;OAOG;IACH,cAAc,CACb,SAAS,EAAE,kBAAkB,EAC7B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GACpE,IAAI;IAgDP;;;;;;OAMG;IACH,YAAY,CACX,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GAC/D,IAAI;IAqBP;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAahD;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,MAAM,IAAI,IAAI;IAOd;;;;OAIG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAgFlB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;OAIG;IACH,SAAS,IAAI,IAAI;CAgBjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c15t/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0-canary-20251012181938",
|
|
4
4
|
"description": "CLI for rapid c15t setup. Scaffold React and Next.js cookie banners and a preferences centre, generate types and config, and run migration tooling for self-hosted deployments.",
|
|
5
5
|
"homepage": "https://c15t.com",
|
|
6
6
|
"repository": {
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@clack/prompts": "^0.10.1",
|
|
24
|
-
"@doubletie/logger": "1.0.4",
|
|
25
24
|
"@mrleebo/prisma-ast": "^0.12.1",
|
|
26
25
|
"@types/better-sqlite3": "^7.6.13",
|
|
27
26
|
"better-sqlite3": "^11.9.1",
|
|
@@ -36,8 +35,9 @@
|
|
|
36
35
|
"posthog-node": "^4.11.7",
|
|
37
36
|
"ts-morph": "^25.0.1",
|
|
38
37
|
"zod": "^3.24.2",
|
|
39
|
-
"@c15t/backend": "1.
|
|
40
|
-
"@c15t/
|
|
38
|
+
"@c15t/backend": "1.7.0-canary-20251012181938",
|
|
39
|
+
"@c15t/logger": "1.0.0-canary-20251012181938",
|
|
40
|
+
"@c15t/react": "1.7.0-canary-20251012181938"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/figlet": "^1.7.0",
|