@chipmobilesdk/rn-ads 0.4.0 → 0.5.1

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.
@@ -1,85 +1,85 @@
1
- /**
2
- * The production-traffic guarantee (FR-011, FR-011a).
3
- *
4
- * A pure function, deliberately. This is the single point where a production ad
5
- * unit can be replaced by an official test one, which is what makes SC-002
6
- * provable rather than merely intended: a guarantee enforced in one place can be
7
- * asserted; one spread across three call sites is a hope.
8
- *
9
- * The rule, from the 2026-09-02 clarification session:
10
- *
11
- * production -> use what the app configured, always, no exceptions
12
- * development / test -> if it is not one of our own official test units,
13
- * replace it and say so, loudly, naming the key
14
- *
15
- * Substitution rather than rejection is a deliberate trade. Rejecting would
16
- * block a developer whose only mistake was pulling a teammate's environment
17
- * file, and turn a configuration smell into a broken integration at every
18
- * startup. Substituting keeps the app working — which is what a non-production
19
- * build is for — and reports the problem as a first-class signal. The accepted
20
- * cost is that a warning can be ignored; it is bounded because production never
21
- * substitutes, so the misconfiguration surfaces there as ordinary behavior
22
- * rather than as hidden state.
23
- */
24
-
25
- import type { Environment, PlacementDefinition } from './types';
26
- import { isOfficialTestAdUnit, testAdUnitFor } from '../engine/testAdUnits';
27
-
28
- export interface ResolvedAdUnit {
29
- readonly effectiveAdUnitId: string;
30
- /** True when the configured identifier was replaced. Drives FR-011a's warning. */
31
- readonly substituted: boolean;
32
- }
33
-
34
- export function resolveAdUnit(
35
- placement: PlacementDefinition,
36
- environment: Environment,
37
- ): ResolvedAdUnit {
38
- const configured = placement.androidAdUnitId;
39
-
40
- // Production is the one environment where the package must not second-guess
41
- // the app. Substituting here would silently rewrite configuration that was
42
- // asked for on purpose, and would cost the publisher live revenue.
43
- if (environment === 'production') {
44
- return { effectiveAdUnitId: configured, substituted: false };
45
- }
46
-
47
- // Structural detection: anything that is not a known official test unit is
48
- // treated as production-owned. Not a parse of AdMob's publisher-id format —
49
- // see the note in engine/testAdUnits.ts on why that rule would be a liability.
50
- if (isOfficialTestAdUnit(configured)) {
51
- return { effectiveAdUnitId: configured, substituted: false };
52
- }
53
-
54
- return { effectiveAdUnitId: testAdUnitFor(placement.format), substituted: true };
55
- }
56
-
57
- export interface ResolvedCatalog {
58
- /** Placement key to the ad unit that will actually be requested. */
59
- readonly byKey: ReadonlyMap<string, string>;
60
- /** Every key whose identifier was replaced, in catalog order (FR-011a). */
61
- readonly substitutedKeys: readonly string[];
62
- }
63
-
64
- /**
65
- * Resolves a whole catalog at once, so the warning can name every affected
66
- * placement in a single event rather than trickling one out per load — an
67
- * integrator wants to fix the whole file, not discover it a placement at a time.
68
- */
69
- export function resolvePlacementAdUnits(
70
- placements: readonly PlacementDefinition[],
71
- environment: Environment,
72
- ): ResolvedCatalog {
73
- const byKey = new Map<string, string>();
74
- const substitutedKeys: string[] = [];
75
-
76
- for (const placement of placements) {
77
- const resolved = resolveAdUnit(placement, environment);
78
- byKey.set(placement.key, resolved.effectiveAdUnitId);
79
- if (resolved.substituted) {
80
- substitutedKeys.push(placement.key);
81
- }
82
- }
83
-
84
- return { byKey, substitutedKeys };
85
- }
1
+ /**
2
+ * The production-traffic guarantee (FR-011, FR-011a).
3
+ *
4
+ * A pure function, deliberately. This is the single point where a production ad
5
+ * unit can be replaced by an official test one, which is what makes SC-002
6
+ * provable rather than merely intended: a guarantee enforced in one place can be
7
+ * asserted; one spread across three call sites is a hope.
8
+ *
9
+ * The rule, from the 2026-09-02 clarification session:
10
+ *
11
+ * production -> use what the app configured, always, no exceptions
12
+ * development / test -> if it is not one of our own official test units,
13
+ * replace it and say so, loudly, naming the key
14
+ *
15
+ * Substitution rather than rejection is a deliberate trade. Rejecting would
16
+ * block a developer whose only mistake was pulling a teammate's environment
17
+ * file, and turn a configuration smell into a broken integration at every
18
+ * startup. Substituting keeps the app working — which is what a non-production
19
+ * build is for — and reports the problem as a first-class signal. The accepted
20
+ * cost is that a warning can be ignored; it is bounded because production never
21
+ * substitutes, so the misconfiguration surfaces there as ordinary behavior
22
+ * rather than as hidden state.
23
+ */
24
+
25
+ import type { Environment, PlacementDefinition } from './types';
26
+ import { isOfficialTestAdUnit, testAdUnitFor } from '../engine/testAdUnits';
27
+
28
+ export interface ResolvedAdUnit {
29
+ readonly effectiveAdUnitId: string;
30
+ /** True when the configured identifier was replaced. Drives FR-011a's warning. */
31
+ readonly substituted: boolean;
32
+ }
33
+
34
+ export function resolveAdUnit(
35
+ placement: PlacementDefinition,
36
+ environment: Environment,
37
+ ): ResolvedAdUnit {
38
+ const configured = placement.androidAdUnitId;
39
+
40
+ // Production is the one environment where the package must not second-guess
41
+ // the app. Substituting here would silently rewrite configuration that was
42
+ // asked for on purpose, and would cost the publisher live revenue.
43
+ if (environment === 'production') {
44
+ return { effectiveAdUnitId: configured, substituted: false };
45
+ }
46
+
47
+ // Structural detection: anything that is not a known official test unit is
48
+ // treated as production-owned. Not a parse of AdMob's publisher-id format —
49
+ // see the note in engine/testAdUnits.ts on why that rule would be a liability.
50
+ if (isOfficialTestAdUnit(configured)) {
51
+ return { effectiveAdUnitId: configured, substituted: false };
52
+ }
53
+
54
+ return { effectiveAdUnitId: testAdUnitFor(placement.format), substituted: true };
55
+ }
56
+
57
+ export interface ResolvedCatalog {
58
+ /** Placement key to the ad unit that will actually be requested. */
59
+ readonly byKey: ReadonlyMap<string, string>;
60
+ /** Every key whose identifier was replaced, in catalog order (FR-011a). */
61
+ readonly substitutedKeys: readonly string[];
62
+ }
63
+
64
+ /**
65
+ * Resolves a whole catalog at once, so the warning can name every affected
66
+ * placement in a single event rather than trickling one out per load — an
67
+ * integrator wants to fix the whole file, not discover it a placement at a time.
68
+ */
69
+ export function resolvePlacementAdUnits(
70
+ placements: readonly PlacementDefinition[],
71
+ environment: Environment,
72
+ ): ResolvedCatalog {
73
+ const byKey = new Map<string, string>();
74
+ const substitutedKeys: string[] = [];
75
+
76
+ for (const placement of placements) {
77
+ const resolved = resolveAdUnit(placement, environment);
78
+ byKey.set(placement.key, resolved.effectiveAdUnitId);
79
+ if (resolved.substituted) {
80
+ substitutedKeys.push(placement.key);
81
+ }
82
+ }
83
+
84
+ return { byKey, substitutedKeys };
85
+ }