@theplaintheory/angular 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @theplaintheory/angular
|
|
2
|
+
|
|
3
|
+
Angular bindings for [Plain Theory](https://www.theplaintheory.in) consent: a signals service, `providePlainConsent()` and the `*plainConsentAllowed` directive, with types. Angular 17.1 and later, standalone, SSR-safe.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @theplaintheory/angular
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Set up
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// main.ts
|
|
13
|
+
import { bootstrapApplication } from "@angular/platform-browser";
|
|
14
|
+
import { providePlainConsent } from "@theplaintheory/angular";
|
|
15
|
+
import { App } from "./app/app";
|
|
16
|
+
|
|
17
|
+
bootstrapApplication(App, { providers: [providePlainConsent({ siteKey: "pk_YOUR_SITE_KEY" })] });
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For trackers written into your HTML, also put the script tag first in `<head>` in `index.html` (from the dashboard's **Install** page); the provider detects it and doesn't add a second copy. During server rendering nothing is loaded and the state stays `null`.
|
|
21
|
+
|
|
22
|
+
## Use it
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { Component, inject } from "@angular/core";
|
|
26
|
+
import { PlainConsentAllowedDirective, PlainConsentService } from "@theplaintheory/angular";
|
|
27
|
+
|
|
28
|
+
@Component({
|
|
29
|
+
selector: "app-video",
|
|
30
|
+
imports: [PlainConsentAllowedDirective],
|
|
31
|
+
template: `
|
|
32
|
+
<iframe *plainConsentAllowed="'marketing'; else blocked" src="https://www.youtube.com/embed/…" title="Video"></iframe>
|
|
33
|
+
<ng-template #blocked><p>Allow marketing cookies to watch this video.</p></ng-template>
|
|
34
|
+
<button type="button" (click)="consent.open()">Privacy choices</button>
|
|
35
|
+
`,
|
|
36
|
+
})
|
|
37
|
+
export class VideoComponent {
|
|
38
|
+
readonly consent = inject(PlainConsentService);
|
|
39
|
+
readonly analytics = this.consent.allowed("analytics"); // Signal<boolean>
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`PlainConsentService`: `state` and `ready` signals, `allowed(category)` returning a signal, and `acceptAll`, `rejectAll`, `set`, `open`, `revoke`, `setLanguage`, `init`. Everything from [`@theplaintheory/consent`](https://www.npmjs.com/package/@theplaintheory/consent) is re-exported.
|
|
44
|
+
|
|
45
|
+
MIT · [Docs](https://www.theplaintheory.in/docs#frameworks)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, PLATFORM_ID, signal, computed, Injectable, TemplateRef, ViewContainerRef, input, effect, Directive, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
3
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
4
|
+
import { consentActions, consentStore, loadPlainConsent, isAllowed } from '@theplaintheory/consent';
|
|
5
|
+
export { getConsent, isAllowed, loadPlainConsent, loadScriptWhenAllowed, onConsentChange, whenAllowed } from '@theplaintheory/consent';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Plain Theory consent as Angular signals. SSR-safe: on the server the state stays null and nothing
|
|
9
|
+
* is loaded. Load the script with `providePlainConsent({ siteKey })` in your app config, or call
|
|
10
|
+
* `init()` yourself.
|
|
11
|
+
*
|
|
12
|
+
* private readonly consent = inject(PlainConsentService);
|
|
13
|
+
* readonly analytics = this.consent.allowed("analytics");
|
|
14
|
+
*/
|
|
15
|
+
class PlainConsentService {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.browser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
18
|
+
this._state = signal(null, ...(ngDevMode ? [{ debugName: "_state" }] : /* istanbul ignore next */ []));
|
|
19
|
+
this.off = () => undefined;
|
|
20
|
+
/** null on the server and until the script is ready */
|
|
21
|
+
this.state = this._state.asReadonly();
|
|
22
|
+
this.ready = computed(() => this._state() !== null, ...(ngDevMode ? [{ debugName: "ready" }] : /* istanbul ignore next */ []));
|
|
23
|
+
this.acceptAll = consentActions.acceptAll;
|
|
24
|
+
this.rejectAll = consentActions.rejectAll;
|
|
25
|
+
this.set = consentActions.set;
|
|
26
|
+
/** open the preferences panel (wire it to a "Privacy choices" link in your footer) */
|
|
27
|
+
this.open = consentActions.open;
|
|
28
|
+
/** forget the choice and ask again */
|
|
29
|
+
this.revoke = consentActions.revoke;
|
|
30
|
+
/** show the notice in one of the site's languages; "" for the default */
|
|
31
|
+
this.setLanguage = consentActions.setLanguage;
|
|
32
|
+
if (!this.browser)
|
|
33
|
+
return;
|
|
34
|
+
this._state.set(consentStore.getSnapshot());
|
|
35
|
+
this.off = consentStore.subscribe(() => this._state.set(consentStore.getSnapshot()));
|
|
36
|
+
}
|
|
37
|
+
/** Load plain-consent.js once. No-op on the server. */
|
|
38
|
+
init(options) {
|
|
39
|
+
if (!this.browser)
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
return loadPlainConsent(options).then(() => undefined, (e) => console.warn(e));
|
|
42
|
+
}
|
|
43
|
+
/** A signal that is true while `category` is allowed (`essential` is always true). */
|
|
44
|
+
allowed(category) {
|
|
45
|
+
return computed(() => isAllowed(category, this._state()));
|
|
46
|
+
}
|
|
47
|
+
ngOnDestroy() {
|
|
48
|
+
this.off();
|
|
49
|
+
}
|
|
50
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PlainConsentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
51
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PlainConsentService, providedIn: "root" }); }
|
|
52
|
+
}
|
|
53
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PlainConsentService, decorators: [{
|
|
54
|
+
type: Injectable,
|
|
55
|
+
args: [{ providedIn: "root" }]
|
|
56
|
+
}], ctorParameters: () => [] });
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Render a template only while a consent category is allowed, with an optional `else` template:
|
|
60
|
+
* Angular's ConsentGate.
|
|
61
|
+
*
|
|
62
|
+
* <iframe *plainConsentAllowed="'marketing'; else blocked" src="https://www.youtube.com/embed/…"></iframe>
|
|
63
|
+
* <ng-template #blocked><p>Allow marketing cookies to watch this video.</p></ng-template>
|
|
64
|
+
*/
|
|
65
|
+
class PlainConsentAllowedDirective {
|
|
66
|
+
constructor() {
|
|
67
|
+
this.template = inject((TemplateRef));
|
|
68
|
+
this.container = inject(ViewContainerRef);
|
|
69
|
+
this.consent = inject(PlainConsentService);
|
|
70
|
+
this.category = input.required({ ...(ngDevMode ? { debugName: "category" } : /* istanbul ignore next */ {}), alias: "plainConsentAllowed" });
|
|
71
|
+
this.elseTemplate = input(null, { ...(ngDevMode ? { debugName: "elseTemplate" } : /* istanbul ignore next */ {}), alias: "plainConsentAllowedElse" });
|
|
72
|
+
this.shown = null;
|
|
73
|
+
effect(() => {
|
|
74
|
+
const next = isAllowed(this.category(), this.consent.state()) ? this.template : this.elseTemplate();
|
|
75
|
+
if (next === this.shown)
|
|
76
|
+
return;
|
|
77
|
+
this.container.clear();
|
|
78
|
+
if (next)
|
|
79
|
+
this.container.createEmbeddedView(next);
|
|
80
|
+
this.shown = next;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PlainConsentAllowedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
84
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: PlainConsentAllowedDirective, isStandalone: true, selector: "[plainConsentAllowed]", inputs: { category: { classPropertyName: "category", publicName: "plainConsentAllowed", isSignal: true, isRequired: true, transformFunction: null }, elseTemplate: { classPropertyName: "elseTemplate", publicName: "plainConsentAllowedElse", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
85
|
+
}
|
|
86
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PlainConsentAllowedDirective, decorators: [{
|
|
87
|
+
type: Directive,
|
|
88
|
+
args: [{ selector: "[plainConsentAllowed]", standalone: true }]
|
|
89
|
+
}], ctorParameters: () => [], propDecorators: { category: [{ type: i0.Input, args: [{ isSignal: true, alias: "plainConsentAllowed", required: true }] }], elseTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "plainConsentAllowedElse", required: false }] }] } });
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Load plain-consent.js when the app starts (browser only; nothing happens during server rendering).
|
|
93
|
+
*
|
|
94
|
+
* bootstrapApplication(App, { providers: [providePlainConsent({ siteKey: "pk_YOUR_SITE_KEY" })] });
|
|
95
|
+
*/
|
|
96
|
+
function providePlainConsent(options) {
|
|
97
|
+
return makeEnvironmentProviders([
|
|
98
|
+
{
|
|
99
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
100
|
+
multi: true,
|
|
101
|
+
useValue: () => {
|
|
102
|
+
void inject(PlainConsentService).init(options);
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* @theplaintheory/angular: Plain Theory consent for Angular 17.1+ (signals, standalone, SSR-safe).
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Generated bundle index. Do not edit.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
export { PlainConsentAllowedDirective, PlainConsentService, providePlainConsent };
|
|
117
|
+
//# sourceMappingURL=theplaintheory-angular.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theplaintheory-angular.mjs","sources":["../../src/plain-consent.service.ts","../../src/consent-allowed.directive.ts","../../src/provide.ts","../../src/public-api.ts","../../src/theplaintheory-angular.ts"],"sourcesContent":["import { computed, inject, Injectable, PLATFORM_ID, signal, type OnDestroy, type Signal } from \"@angular/core\";\r\nimport { isPlatformBrowser } from \"@angular/common\";\r\nimport { consentActions, consentStore, isAllowed, loadPlainConsent, type Category, type ConsentState, type LoadOptions } from \"@theplaintheory/consent\";\r\n\r\n/**\r\n * Plain Theory consent as Angular signals. SSR-safe: on the server the state stays null and nothing\r\n * is loaded. Load the script with `providePlainConsent({ siteKey })` in your app config, or call\r\n * `init()` yourself.\r\n *\r\n * private readonly consent = inject(PlainConsentService);\r\n * readonly analytics = this.consent.allowed(\"analytics\");\r\n */\r\n@Injectable({ providedIn: \"root\" })\r\nexport class PlainConsentService implements OnDestroy {\r\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\r\n private readonly _state = signal<ConsentState | null>(null);\r\n private off: () => void = () => undefined;\r\n\r\n /** null on the server and until the script is ready */\r\n readonly state: Signal<ConsentState | null> = this._state.asReadonly();\r\n readonly ready = computed(() => this._state() !== null);\r\n\r\n readonly acceptAll = consentActions.acceptAll;\r\n readonly rejectAll = consentActions.rejectAll;\r\n readonly set = consentActions.set;\r\n /** open the preferences panel (wire it to a \"Privacy choices\" link in your footer) */\r\n readonly open = consentActions.open;\r\n /** forget the choice and ask again */\r\n readonly revoke = consentActions.revoke;\r\n /** show the notice in one of the site's languages; \"\" for the default */\r\n readonly setLanguage = consentActions.setLanguage;\r\n\r\n constructor() {\r\n if (!this.browser) return;\r\n this._state.set(consentStore.getSnapshot());\r\n this.off = consentStore.subscribe(() => this._state.set(consentStore.getSnapshot()));\r\n }\r\n\r\n /** Load plain-consent.js once. No-op on the server. */\r\n init(options: LoadOptions): Promise<void> {\r\n if (!this.browser) return Promise.resolve();\r\n return loadPlainConsent(options).then(\r\n () => undefined,\r\n (e: unknown) => console.warn(e),\r\n );\r\n }\r\n\r\n /** A signal that is true while `category` is allowed (`essential` is always true). */\r\n allowed(category: Category): Signal<boolean> {\r\n return computed(() => isAllowed(category, this._state()));\r\n }\r\n\r\n ngOnDestroy() {\r\n this.off();\r\n }\r\n}\r\n","import { Directive, effect, inject, input, TemplateRef, ViewContainerRef } from \"@angular/core\";\r\nimport { isAllowed, type Category } from \"@theplaintheory/consent\";\r\nimport { PlainConsentService } from \"./plain-consent.service\";\r\n\r\n/**\r\n * Render a template only while a consent category is allowed, with an optional `else` template:\r\n * Angular's ConsentGate.\r\n *\r\n * <iframe *plainConsentAllowed=\"'marketing'; else blocked\" src=\"https://www.youtube.com/embed/…\"></iframe>\r\n * <ng-template #blocked><p>Allow marketing cookies to watch this video.</p></ng-template>\r\n */\r\n@Directive({ selector: \"[plainConsentAllowed]\", standalone: true })\r\nexport class PlainConsentAllowedDirective {\r\n private readonly template = inject(TemplateRef<unknown>);\r\n private readonly container = inject(ViewContainerRef);\r\n private readonly consent = inject(PlainConsentService);\r\n\r\n readonly category = input.required<Category>({ alias: \"plainConsentAllowed\" });\r\n readonly elseTemplate = input<TemplateRef<unknown> | null>(null, { alias: \"plainConsentAllowedElse\" });\r\n\r\n private shown: TemplateRef<unknown> | null = null;\r\n\r\n constructor() {\r\n effect(() => {\r\n const next = isAllowed(this.category(), this.consent.state()) ? this.template : this.elseTemplate();\r\n if (next === this.shown) return;\r\n this.container.clear();\r\n if (next) this.container.createEmbeddedView(next);\r\n this.shown = next;\r\n });\r\n }\r\n}\r\n","import { ENVIRONMENT_INITIALIZER, inject, makeEnvironmentProviders, type EnvironmentProviders } from \"@angular/core\";\r\nimport type { LoadOptions } from \"@theplaintheory/consent\";\r\nimport { PlainConsentService } from \"./plain-consent.service\";\r\n\r\n/**\r\n * Load plain-consent.js when the app starts (browser only; nothing happens during server rendering).\r\n *\r\n * bootstrapApplication(App, { providers: [providePlainConsent({ siteKey: \"pk_YOUR_SITE_KEY\" })] });\r\n */\r\nexport function providePlainConsent(options: LoadOptions): EnvironmentProviders {\r\n return makeEnvironmentProviders([\r\n {\r\n provide: ENVIRONMENT_INITIALIZER,\r\n multi: true,\r\n useValue: () => {\r\n void inject(PlainConsentService).init(options);\r\n },\r\n },\r\n ]);\r\n}\r\n","/*\r\n * @theplaintheory/angular: Plain Theory consent for Angular 17.1+ (signals, standalone, SSR-safe).\r\n */\r\nexport { PlainConsentService } from \"./plain-consent.service\";\r\nexport { PlainConsentAllowedDirective } from \"./consent-allowed.directive\";\r\nexport { providePlainConsent } from \"./provide\";\r\nexport type { Categories, Category, ConsentState, Framework, LoadOptions, PlainConsentApi } from \"@theplaintheory/consent\";\r\nexport { getConsent, isAllowed, loadPlainConsent, loadScriptWhenAllowed, onConsentChange, whenAllowed } from \"@theplaintheory/consent\";\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;AAIA;;;;;;;AAOG;MAEU,mBAAmB,CAAA;AAmB9B,IAAA,WAAA,GAAA;QAlBiB,IAAA,CAAA,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAChD,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAsB,IAAI,6EAAC;AACnD,QAAA,IAAA,CAAA,GAAG,GAAe,MAAM,SAAS;;AAGhC,QAAA,IAAA,CAAA,KAAK,GAAgC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AAC7D,QAAA,IAAA,CAAA,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,4EAAC;AAE9C,QAAA,IAAA,CAAA,SAAS,GAAG,cAAc,CAAC,SAAS;AACpC,QAAA,IAAA,CAAA,SAAS,GAAG,cAAc,CAAC,SAAS;AACpC,QAAA,IAAA,CAAA,GAAG,GAAG,cAAc,CAAC,GAAG;;AAExB,QAAA,IAAA,CAAA,IAAI,GAAG,cAAc,CAAC,IAAI;;AAE1B,QAAA,IAAA,CAAA,MAAM,GAAG,cAAc,CAAC,MAAM;;AAE9B,QAAA,IAAA,CAAA,WAAW,GAAG,cAAc,CAAC,WAAW;QAG/C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;QACnB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IACtF;;AAGA,IAAA,IAAI,CAAC,OAAoB,EAAA;QACvB,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,OAAO,CAAC,OAAO,EAAE;QAC3C,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CACnC,MAAM,SAAS,EACf,CAAC,CAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAChC;IACH;;AAGA,IAAA,OAAO,CAAC,QAAkB,EAAA;AACxB,QAAA,OAAO,QAAQ,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D;IAEA,WAAW,GAAA;QACT,IAAI,CAAC,GAAG,EAAE;IACZ;+GAzCW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,cADN,MAAM,EAAA,CAAA,CAAA;;4FACnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACRlC;;;;;;AAMG;MAEU,4BAA4B,CAAA;AAUvC,IAAA,WAAA,GAAA;AATiB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,EAAC,WAAoB,EAAC;AACvC,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACpC,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC;QAE7C,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAC,QAAQ,+EAAa,KAAK,EAAE,qBAAqB,EAAA,CAAG;QACrE,IAAA,CAAA,YAAY,GAAG,KAAK,CAA8B,IAAI,oFAAI,KAAK,EAAE,yBAAyB,EAAA,CAAG;QAE9F,IAAA,CAAA,KAAK,GAAgC,IAAI;QAG/C,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE;AACnG,YAAA,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK;gBAAE;AACzB,YAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;AACtB,YAAA,IAAI,IAAI;AAAE,gBAAA,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC;AACjD,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACnB,QAAA,CAAC,CAAC;IACJ;+GAlBW,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAA5B,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,yBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;4FAA5B,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBADxC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA,EAAE,QAAQ,EAAE,uBAAuB,EAAE,UAAU,EAAE,IAAI,EAAE;;;ACPlE;;;;AAIG;AACG,SAAU,mBAAmB,CAAC,OAAoB,EAAA;AACtD,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,uBAAuB;AAChC,YAAA,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,MAAK;gBACb,KAAK,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YAChD,CAAC;AACF,SAAA;AACF,KAAA,CAAC;AACJ;;ACnBA;;AAEG;;ACFH;;AAEG;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theplaintheory/angular",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Angular 17.1+ bindings for Plain Theory consent: a signals service, providePlainConsent() and the *plainConsentAllowed directive. SSR-safe.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@theplaintheory/consent": "^1.0.0",
|
|
9
|
+
"tslib": "^2.6.0"
|
|
10
|
+
},
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"@angular/common": ">=17.1.0",
|
|
13
|
+
"@angular/core": ">=17.1.0"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/gagankarthik/theplaintheory.git",
|
|
21
|
+
"directory": "packages/angular"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://www.theplaintheory.in/docs#frameworks",
|
|
24
|
+
"keywords": [
|
|
25
|
+
"consent",
|
|
26
|
+
"cmp",
|
|
27
|
+
"cookie banner",
|
|
28
|
+
"gdpr",
|
|
29
|
+
"ccpa",
|
|
30
|
+
"dpdpa",
|
|
31
|
+
"angular",
|
|
32
|
+
"signals"
|
|
33
|
+
],
|
|
34
|
+
"module": "fesm2022/theplaintheory-angular.mjs",
|
|
35
|
+
"typings": "types/theplaintheory-angular.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
"./package.json": {
|
|
38
|
+
"default": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./types/theplaintheory-angular.d.ts",
|
|
42
|
+
"default": "./fesm2022/theplaintheory-angular.mjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"type": "module"
|
|
6
46
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnDestroy, Signal, TemplateRef, EnvironmentProviders } from '@angular/core';
|
|
3
|
+
import { ConsentState, Category, LoadOptions } from '@theplaintheory/consent';
|
|
4
|
+
export { Categories, Category, ConsentState, Framework, LoadOptions, PlainConsentApi, getConsent, isAllowed, loadPlainConsent, loadScriptWhenAllowed, onConsentChange, whenAllowed } from '@theplaintheory/consent';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Plain Theory consent as Angular signals. SSR-safe: on the server the state stays null and nothing
|
|
8
|
+
* is loaded. Load the script with `providePlainConsent({ siteKey })` in your app config, or call
|
|
9
|
+
* `init()` yourself.
|
|
10
|
+
*
|
|
11
|
+
* private readonly consent = inject(PlainConsentService);
|
|
12
|
+
* readonly analytics = this.consent.allowed("analytics");
|
|
13
|
+
*/
|
|
14
|
+
declare class PlainConsentService implements OnDestroy {
|
|
15
|
+
private readonly browser;
|
|
16
|
+
private readonly _state;
|
|
17
|
+
private off;
|
|
18
|
+
/** null on the server and until the script is ready */
|
|
19
|
+
readonly state: Signal<ConsentState | null>;
|
|
20
|
+
readonly ready: Signal<boolean>;
|
|
21
|
+
readonly acceptAll: () => void;
|
|
22
|
+
readonly rejectAll: () => void;
|
|
23
|
+
readonly set: (partial: Partial<Record<Category, boolean>>) => void;
|
|
24
|
+
/** open the preferences panel (wire it to a "Privacy choices" link in your footer) */
|
|
25
|
+
readonly open: () => void;
|
|
26
|
+
/** forget the choice and ask again */
|
|
27
|
+
readonly revoke: () => void;
|
|
28
|
+
/** show the notice in one of the site's languages; "" for the default */
|
|
29
|
+
readonly setLanguage: (code: string) => void;
|
|
30
|
+
constructor();
|
|
31
|
+
/** Load plain-consent.js once. No-op on the server. */
|
|
32
|
+
init(options: LoadOptions): Promise<void>;
|
|
33
|
+
/** A signal that is true while `category` is allowed (`essential` is always true). */
|
|
34
|
+
allowed(category: Category): Signal<boolean>;
|
|
35
|
+
ngOnDestroy(): void;
|
|
36
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PlainConsentService, never>;
|
|
37
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PlainConsentService>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Render a template only while a consent category is allowed, with an optional `else` template:
|
|
42
|
+
* Angular's ConsentGate.
|
|
43
|
+
*
|
|
44
|
+
* <iframe *plainConsentAllowed="'marketing'; else blocked" src="https://www.youtube.com/embed/…"></iframe>
|
|
45
|
+
* <ng-template #blocked><p>Allow marketing cookies to watch this video.</p></ng-template>
|
|
46
|
+
*/
|
|
47
|
+
declare class PlainConsentAllowedDirective {
|
|
48
|
+
private readonly template;
|
|
49
|
+
private readonly container;
|
|
50
|
+
private readonly consent;
|
|
51
|
+
readonly category: i0.InputSignal<Category>;
|
|
52
|
+
readonly elseTemplate: i0.InputSignal<TemplateRef<unknown> | null>;
|
|
53
|
+
private shown;
|
|
54
|
+
constructor();
|
|
55
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PlainConsentAllowedDirective, never>;
|
|
56
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<PlainConsentAllowedDirective, "[plainConsentAllowed]", never, { "category": { "alias": "plainConsentAllowed"; "required": true; "isSignal": true; }; "elseTemplate": { "alias": "plainConsentAllowedElse"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Load plain-consent.js when the app starts (browser only; nothing happens during server rendering).
|
|
61
|
+
*
|
|
62
|
+
* bootstrapApplication(App, { providers: [providePlainConsent({ siteKey: "pk_YOUR_SITE_KEY" })] });
|
|
63
|
+
*/
|
|
64
|
+
declare function providePlainConsent(options: LoadOptions): EnvironmentProviders;
|
|
65
|
+
|
|
66
|
+
export { PlainConsentAllowedDirective, PlainConsentService, providePlainConsent };
|
|
67
|
+
//# sourceMappingURL=theplaintheory-angular.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theplaintheory-angular.d.ts","sources":["../../src/plain-consent.service.ts","../../src/consent-allowed.directive.ts","../../src/provide.ts"],"mappings":";;;;;AAIA;;;;;;;AAOG;AACH,cACa,mBAAoB,YAAW,SAAS;AACnD;AACA;;;oBAIgB,MAAM,CAAC,YAAY;oBACrB,MAAA;;;4BAIF,OAAA,CAAA,MAAA,CAAA,QAAA;;;;;;;;;kBAeE,WAAW,GAAG,OAAO;;sBASjB,QAAQ,GAAG,MAAM;;yCAnCxB,mBAAmB;6CAAnB,mBAAmB;AA0C/B;;ACnDD;;;;;;AAMG;AACH,cACa,4BAA4B;AACvC;AACA;AACA;uBAEiBA,EAAA,CAAA,WAAA,CAAA,QAAA;2BACIA,EAAA,CAAA,WAAA,CAAA,WAAA;;;yCANV,4BAA4B;2CAA5B,4BAA4B;AAmBxC;;AC3BD;;;;AAIG;AACH,iBAAgB,mBAAmB,UAAU,WAAW,GAAG,oBAAoB;;","names":["_angular_core"]}
|