@mpgd/target-config 0.3.2 → 0.3.4

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/effective.js CHANGED
@@ -121,13 +121,20 @@ function productPlatformId(product, target) {
121
121
  if (!isStoreBackedTarget(target)) {
122
122
  return undefined;
123
123
  }
124
- return product.platformProductIds[target];
124
+ return normalizePlatformId(product.platformProductIds[target]);
125
125
  }
126
126
  function adPlacementPlatformId(placement, target) {
127
127
  if (!isStoreBackedTarget(target)) {
128
128
  return undefined;
129
129
  }
130
- return placement.platformPlacementIds[target];
130
+ return normalizePlatformId(placement.platformPlacementIds[target]);
131
+ }
132
+ function normalizePlatformId(platformId) {
133
+ if (platformId === undefined) {
134
+ return undefined;
135
+ }
136
+ const trimmed = platformId.trim();
137
+ return trimmed.length === 0 ? undefined : trimmed;
131
138
  }
132
139
  function isStoreBackedTarget(target) {
133
140
  return target === 'android' || target === 'ios' || target === 'ait';
package/dist/index.d.ts CHANGED
@@ -2,5 +2,6 @@ import type { EffectiveTargetConfigMatrix } from './effective';
2
2
  import type { TargetConfigMatrix } from './runtime';
3
3
  export * from './effective';
4
4
  export * from './runtime';
5
+ export * from './viewport';
5
6
  export declare const assertEffectiveTargetConfigMatrix: (input: unknown) => EffectiveTargetConfigMatrix;
6
7
  export declare const assertTargetConfigMatrix: (input: unknown) => TargetConfigMatrix;
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ const __typia_transform__accessExpressionAsString = _b._accessExpressionAsString
4
4
  import typia from 'typia';
5
5
  export * from './effective';
6
6
  export * from './runtime';
7
+ export * from './viewport';
7
8
  export const assertEffectiveTargetConfigMatrix = (() => {
8
9
  const _ip0 = input => "string" === typeof input["version"];
9
10
  const _ip1 = input => "boolean" === typeof input["iap"];
@@ -225,10 +226,10 @@ export const assertEffectiveTargetConfigMatrix = (() => {
225
226
  path: _path + ".target",
226
227
  expected: "string",
227
228
  value: input.target
228
- }, _errorFactory)) && ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "web-preview" === input.runtime || _a._assertGuard(_exceptionable, {
229
+ }, _errorFactory)) && ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "microsoft-store-pwa" === input.runtime || "web-preview" === input.runtime || _a._assertGuard(_exceptionable, {
229
230
  method: "typia.createAssert",
230
231
  path: _path + ".runtime",
231
- expected: "(\"apps-in-toss\" | \"capacitor-android\" | \"capacitor-ios\" | \"devvit-web\" | \"web-preview\")",
232
+ expected: "(\"apps-in-toss\" | \"capacitor-android\" | \"capacitor-ios\" | \"devvit-web\" | \"microsoft-store-pwa\" | \"web-preview\")",
232
233
  value: input.runtime
233
234
  }, _errorFactory)) && (("object" === typeof input.release && null !== input.release || _a._assertGuard(_exceptionable, {
234
235
  method: "typia.createAssert",
@@ -331,10 +332,10 @@ export const assertEffectiveTargetConfigMatrix = (() => {
331
332
  expected: "EffectiveLocalizationConfig",
332
333
  value: input.localization
333
334
  }, _errorFactory));
334
- const _ao3 = (input, _path, _exceptionable = true) => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "web-preview" === input.profile || _a._assertGuard(_exceptionable, {
335
+ const _ao3 = (input, _path, _exceptionable = true) => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "microsoft-store" === input.profile || "web-preview" === input.profile || _a._assertGuard(_exceptionable, {
335
336
  method: "typia.createAssert",
336
337
  path: _path + ".profile",
337
- expected: "(\"app-store\" | \"apps-in-toss\" | \"devvit\" | \"google-play\" | \"web-preview\")",
338
+ expected: "(\"app-store\" | \"apps-in-toss\" | \"devvit\" | \"google-play\" | \"microsoft-store\" | \"web-preview\")",
338
339
  value: input.profile
339
340
  }, _errorFactory);
340
341
  const _ao4 = (input, _path, _exceptionable = true) => _ap1(input, _path, true && _exceptionable) && _ap2(input, _path, true && _exceptionable) && _ap3(input, _path, true && _exceptionable) && ("boolean" === typeof input.leaderboard || _a._assertGuard(_exceptionable, {
@@ -491,8 +492,8 @@ export const assertEffectiveTargetConfigMatrix = (() => {
491
492
  const _io17 = input => "boolean" === typeof input.native && _ip5(input) && ("available" === input.reason || "capability-unsupported" === input.reason || "target-disabled" === input.reason) && (undefined === input.defaultLeaderboardId || "string" === typeof input.defaultLeaderboardId);
492
493
  const _io18 = input => ("local" === input.support || "native" === input.support || "none" === input.support) && _ip5(input);
493
494
  const _io19 = input => _ip5(input);
494
- const _io2 = input => _ip0(input) && "string" === typeof input.target && ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "web-preview" === input.runtime) && ("object" === typeof input.release && null !== input.release && _io3(input.release)) && ("object" === typeof input.features && null !== input.features && _io4(input.features)) && ("object" === typeof input.capabilities && null !== input.capabilities && _io5(input.capabilities)) && ("object" === typeof input.policy && null !== input.policy && _io6(input.policy)) && ("object" === typeof input.sources && null !== input.sources && _io7(input.sources)) && ("object" === typeof input.monetization && null !== input.monetization && _io8(input.monetization)) && ("object" === typeof input.ads && null !== input.ads && _io12(input.ads)) && ("object" === typeof input.leaderboard && null !== input.leaderboard && _io17(input.leaderboard)) && ("object" === typeof input.storage && null !== input.storage && _io18(input.storage)) && ("object" === typeof input.localization && null !== input.localization && _io19(input.localization));
495
- const _io3 = input => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "web-preview" === input.profile;
495
+ const _io2 = input => _ip0(input) && "string" === typeof input.target && ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "microsoft-store-pwa" === input.runtime || "web-preview" === input.runtime) && ("object" === typeof input.release && null !== input.release && _io3(input.release)) && ("object" === typeof input.features && null !== input.features && _io4(input.features)) && ("object" === typeof input.capabilities && null !== input.capabilities && _io5(input.capabilities)) && ("object" === typeof input.policy && null !== input.policy && _io6(input.policy)) && ("object" === typeof input.sources && null !== input.sources && _io7(input.sources)) && ("object" === typeof input.monetization && null !== input.monetization && _io8(input.monetization)) && ("object" === typeof input.ads && null !== input.ads && _io12(input.ads)) && ("object" === typeof input.leaderboard && null !== input.leaderboard && _io17(input.leaderboard)) && ("object" === typeof input.storage && null !== input.storage && _io18(input.storage)) && ("object" === typeof input.localization && null !== input.localization && _io19(input.localization));
496
+ const _io3 = input => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "microsoft-store" === input.profile || "web-preview" === input.profile;
496
497
  const _io4 = input => _ip1(input) && _ip2(input) && _ip3(input) && "boolean" === typeof input.leaderboard && _ip4(input);
497
498
  const _io5 = input => ("local" === input.storage || "native" === input.storage || "none" === input.storage) && _ip4(input);
498
499
  const _io6 = input => "boolean" === typeof input.externalPaymentAllowed && "boolean" === typeof input.remoteExecutableCodeAllowed && "boolean" === typeof input.installOtherAppCTAAllowed && "boolean" === typeof input.requiresStoreReview && "boolean" === typeof input.requiresAitReview;
@@ -596,10 +597,10 @@ export const assertTargetConfigMatrix = (() => {
596
597
  value: value
597
598
  }, _errorFactory);
598
599
  });
599
- const _ao2 = (input, _path, _exceptionable = true) => ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "web-preview" === input.runtime || _a._assertGuard(_exceptionable, {
600
+ const _ao2 = (input, _path, _exceptionable = true) => ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "microsoft-store-pwa" === input.runtime || "web-preview" === input.runtime || _a._assertGuard(_exceptionable, {
600
601
  method: "typia.createAssert",
601
602
  path: _path + ".runtime",
602
- expected: "(\"apps-in-toss\" | \"capacitor-android\" | \"capacitor-ios\" | \"devvit-web\" | \"web-preview\")",
603
+ expected: "(\"apps-in-toss\" | \"capacitor-android\" | \"capacitor-ios\" | \"devvit-web\" | \"microsoft-store-pwa\" | \"web-preview\")",
603
604
  value: input.runtime
604
605
  }, _errorFactory)) && (("object" === typeof input.features && null !== input.features || _a._assertGuard(_exceptionable, {
605
606
  method: "typia.createAssert",
@@ -681,10 +682,10 @@ export const assertTargetConfigMatrix = (() => {
681
682
  expected: "boolean",
682
683
  value: input.native
683
684
  }, _errorFactory);
684
- const _ao7 = (input, _path, _exceptionable = true) => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "web-preview" === input.profile || _a._assertGuard(_exceptionable, {
685
+ const _ao7 = (input, _path, _exceptionable = true) => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "microsoft-store" === input.profile || "web-preview" === input.profile || _a._assertGuard(_exceptionable, {
685
686
  method: "typia.createAssert",
686
687
  path: _path + ".profile",
687
- expected: "(\"app-store\" | \"apps-in-toss\" | \"devvit\" | \"google-play\" | \"web-preview\")",
688
+ expected: "(\"app-store\" | \"apps-in-toss\" | \"devvit\" | \"google-play\" | \"microsoft-store\" | \"web-preview\")",
688
689
  value: input.profile
689
690
  }, _errorFactory);
690
691
  const _ao8 = (input, _path, _exceptionable = true) => ("boolean" === typeof input.externalPaymentAllowed || _a._assertGuard(_exceptionable, {
@@ -720,12 +721,12 @@ export const assertTargetConfigMatrix = (() => {
720
721
  return true;
721
722
  return "object" === typeof value && null !== value && _io2(value);
722
723
  });
723
- const _io2 = input => ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "web-preview" === input.runtime) && ("object" === typeof input.features && null !== input.features && _io3(input.features)) && ("object" === typeof input.capabilities && null !== input.capabilities && _io4(input.capabilities)) && ("object" === typeof input.monetization && null !== input.monetization && _io5(input.monetization)) && ("object" === typeof input.leaderboard && null !== input.leaderboard && _io6(input.leaderboard)) && ("object" === typeof input.release && null !== input.release && _io7(input.release)) && ("object" === typeof input.policy && null !== input.policy && _io8(input.policy));
724
+ const _io2 = input => ("apps-in-toss" === input.runtime || "capacitor-android" === input.runtime || "capacitor-ios" === input.runtime || "devvit-web" === input.runtime || "microsoft-store-pwa" === input.runtime || "web-preview" === input.runtime) && ("object" === typeof input.features && null !== input.features && _io3(input.features)) && ("object" === typeof input.capabilities && null !== input.capabilities && _io4(input.capabilities)) && ("object" === typeof input.monetization && null !== input.monetization && _io5(input.monetization)) && ("object" === typeof input.leaderboard && null !== input.leaderboard && _io6(input.leaderboard)) && ("object" === typeof input.release && null !== input.release && _io7(input.release)) && ("object" === typeof input.policy && null !== input.policy && _io8(input.policy));
724
725
  const _io3 = input => _ip0(input) && _ip1(input) && _ip2(input) && "boolean" === typeof input.leaderboard && _ip3(input);
725
726
  const _io4 = input => ("local" === input.storage || "native" === input.storage || "none" === input.storage) && _ip3(input);
726
727
  const _io5 = input => _ip0(input) && _ip1(input) && _ip2(input);
727
728
  const _io6 = input => "boolean" === typeof input.native;
728
- const _io7 = input => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "web-preview" === input.profile;
729
+ const _io7 = input => "app-store" === input.profile || "apps-in-toss" === input.profile || "devvit" === input.profile || "google-play" === input.profile || "microsoft-store" === input.profile || "web-preview" === input.profile;
729
730
  const _io8 = input => "boolean" === typeof input.externalPaymentAllowed && "boolean" === typeof input.remoteExecutableCodeAllowed && "boolean" === typeof input.installOtherAppCTAAllowed && "boolean" === typeof input.requiresStoreReview && "boolean" === typeof input.requiresAitReview;
730
731
  const __is = input => "object" === typeof input && null !== input && _io0(input);
731
732
  let _errorFactory;
package/dist/runtime.d.ts CHANGED
@@ -3,8 +3,8 @@ import type { EffectiveTargetConfig } from './effective';
3
3
  export type PlatformFeature = 'iap' | 'rewardedAds' | 'interstitialAds' | 'leaderboard' | 'localization';
4
4
  export type AdPlacementType = 'rewarded' | 'interstitial';
5
5
  type PlatformConfigTarget = PlatformGateway['target'];
6
- export type TargetRuntimeKind = 'web-preview' | 'capacitor-android' | 'capacitor-ios' | 'apps-in-toss' | 'devvit-web';
7
- export type ReleaseProfile = 'web-preview' | 'google-play' | 'app-store' | 'apps-in-toss' | 'devvit';
6
+ export type TargetRuntimeKind = 'web-preview' | 'microsoft-store-pwa' | 'capacitor-android' | 'capacitor-ios' | 'apps-in-toss' | 'devvit-web';
7
+ export type ReleaseProfile = 'web-preview' | 'microsoft-store' | 'google-play' | 'app-store' | 'apps-in-toss' | 'devvit';
8
8
  export type StorageSupport = 'local' | 'native' | 'none';
9
9
  export interface TargetFeatureConfig {
10
10
  readonly iap: boolean;
@@ -0,0 +1,47 @@
1
+ import type { TargetConfig, TargetRuntimeKind } from './runtime';
2
+ export type TargetViewportOrientation = 'portrait' | 'landscape';
3
+ export type TargetViewportSizeClass = 'compact' | 'medium' | 'expanded';
4
+ export type TargetViewportShell = 'browser' | 'mobile-webview' | 'embedded-webview';
5
+ export type TargetViewportMeasurementSource = 'container' | 'visual-viewport' | 'window' | 'unknown';
6
+ export type TargetViewportControlPlacement = 'bottom' | 'side';
7
+ export type TargetViewportPanelPlacement = 'below' | 'side' | 'drawer';
8
+ export interface TargetViewportBreakpoints {
9
+ readonly compactMaxWidth: number;
10
+ readonly expandedMinWidth: number;
11
+ }
12
+ export interface TargetViewportInput {
13
+ readonly width: number;
14
+ readonly height: number;
15
+ readonly runtime?: TargetRuntimeKind;
16
+ readonly source?: TargetViewportMeasurementSource;
17
+ }
18
+ export interface TargetViewportLayout {
19
+ readonly width: number;
20
+ readonly height: number;
21
+ readonly shortSide: number;
22
+ readonly longSide: number;
23
+ readonly aspectRatio: number;
24
+ readonly orientation: TargetViewportOrientation;
25
+ readonly sizeClass: TargetViewportSizeClass;
26
+ readonly shell: TargetViewportShell;
27
+ readonly source: TargetViewportMeasurementSource;
28
+ }
29
+ export interface TargetViewportRecommendation {
30
+ readonly primaryControls: TargetViewportControlPlacement;
31
+ readonly secondaryPanels: TargetViewportPanelPlacement;
32
+ readonly safeAreaAware: boolean;
33
+ }
34
+ export interface TargetViewportPlan {
35
+ readonly layout: TargetViewportLayout;
36
+ readonly recommendation: TargetViewportRecommendation;
37
+ }
38
+ export declare const defaultTargetViewportBreakpoints: {
39
+ readonly compactMaxWidth: 599;
40
+ readonly expandedMinWidth: 900;
41
+ };
42
+ export declare function targetViewportShellForRuntime(runtime: TargetRuntimeKind): TargetViewportShell;
43
+ export declare function targetViewportShellForConfig(config: Pick<TargetConfig, 'runtime'>): TargetViewportShell;
44
+ export declare function resolveTargetViewportLayout(input: TargetViewportInput, breakpoints?: TargetViewportBreakpoints): TargetViewportLayout;
45
+ export declare function resolveTargetViewportSizeClass(width: number, breakpoints?: TargetViewportBreakpoints): TargetViewportSizeClass;
46
+ export declare function resolveTargetViewportRecommendation(layout: TargetViewportLayout): TargetViewportRecommendation;
47
+ export declare function resolveTargetViewportPlan(input: TargetViewportInput, breakpoints?: TargetViewportBreakpoints): TargetViewportPlan;
@@ -0,0 +1,99 @@
1
+ export const defaultTargetViewportBreakpoints = {
2
+ compactMaxWidth: 599,
3
+ expandedMinWidth: 900,
4
+ };
5
+ export function targetViewportShellForRuntime(runtime) {
6
+ switch (runtime) {
7
+ case 'capacitor-android':
8
+ case 'capacitor-ios':
9
+ case 'apps-in-toss':
10
+ return 'mobile-webview';
11
+ case 'devvit-web':
12
+ return 'embedded-webview';
13
+ case 'web-preview':
14
+ case 'microsoft-store-pwa':
15
+ return 'browser';
16
+ }
17
+ const exhaustive = runtime;
18
+ return exhaustive;
19
+ }
20
+ export function targetViewportShellForConfig(config) {
21
+ return targetViewportShellForRuntime(config.runtime);
22
+ }
23
+ export function resolveTargetViewportLayout(input, breakpoints = defaultTargetViewportBreakpoints) {
24
+ const normalizedBreakpoints = normalizeTargetViewportBreakpoints(breakpoints);
25
+ const width = normalizeViewportDimension(input.width, 'width');
26
+ const height = normalizeViewportDimension(input.height, 'height');
27
+ const aspectRatio = width / height;
28
+ return {
29
+ width,
30
+ height,
31
+ shortSide: Math.min(width, height),
32
+ longSide: Math.max(width, height),
33
+ aspectRatio,
34
+ orientation: width >= height ? 'landscape' : 'portrait',
35
+ sizeClass: classifyTargetViewportSize(width, normalizedBreakpoints),
36
+ shell: input.runtime === undefined ? 'browser' : targetViewportShellForRuntime(input.runtime),
37
+ source: input.source ?? 'unknown',
38
+ };
39
+ }
40
+ export function resolveTargetViewportSizeClass(width, breakpoints = defaultTargetViewportBreakpoints) {
41
+ return classifyTargetViewportSize(normalizeViewportDimension(width, 'width'), normalizeTargetViewportBreakpoints(breakpoints));
42
+ }
43
+ export function resolveTargetViewportRecommendation(layout) {
44
+ const narrowOrPortrait = layout.sizeClass === 'compact' || layout.orientation === 'portrait';
45
+ const browserSafeAreaRisk = layout.shell === 'browser' &&
46
+ layout.orientation === 'landscape' &&
47
+ layout.shortSide <= defaultTargetViewportBreakpoints.compactMaxWidth;
48
+ return {
49
+ primaryControls: narrowOrPortrait ? 'bottom' : 'side',
50
+ secondaryPanels: resolveTargetViewportPanelPlacement(layout),
51
+ safeAreaAware: layout.shell !== 'browser' || layout.sizeClass === 'compact' || browserSafeAreaRisk,
52
+ };
53
+ }
54
+ export function resolveTargetViewportPlan(input, breakpoints = defaultTargetViewportBreakpoints) {
55
+ const layout = resolveTargetViewportLayout(input, breakpoints);
56
+ return {
57
+ layout,
58
+ recommendation: resolveTargetViewportRecommendation(layout),
59
+ };
60
+ }
61
+ function classifyTargetViewportSize(width, breakpoints) {
62
+ if (width <= breakpoints.compactMaxWidth) {
63
+ return 'compact';
64
+ }
65
+ if (width < breakpoints.expandedMinWidth) {
66
+ return 'medium';
67
+ }
68
+ return 'expanded';
69
+ }
70
+ function resolveTargetViewportPanelPlacement(layout) {
71
+ if (layout.sizeClass === 'compact') {
72
+ return 'drawer';
73
+ }
74
+ if (layout.orientation === 'portrait') {
75
+ return 'below';
76
+ }
77
+ return 'side';
78
+ }
79
+ function normalizeTargetViewportBreakpoints(breakpoints) {
80
+ const compactMaxWidth = normalizeViewportDimension(breakpoints.compactMaxWidth, 'compactMaxWidth');
81
+ const expandedMinWidth = normalizeViewportDimension(breakpoints.expandedMinWidth, 'expandedMinWidth');
82
+ if (compactMaxWidth + 1 >= expandedMinWidth) {
83
+ throw new Error('compactMaxWidth must leave at least one integer width below expandedMinWidth for medium viewports.');
84
+ }
85
+ return {
86
+ compactMaxWidth,
87
+ expandedMinWidth,
88
+ };
89
+ }
90
+ function normalizeViewportDimension(value, name) {
91
+ if (!Number.isFinite(value) || value <= 0) {
92
+ throw new Error(`Viewport ${name} must be a positive finite number.`);
93
+ }
94
+ const rounded = Math.round(value);
95
+ if (rounded <= 0) {
96
+ throw new Error(`Viewport ${name} must round to at least 1.`);
97
+ }
98
+ return rounded;
99
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpgd/target-config",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Target-specific platform feature availability and effective config helpers for mpgd.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/targets.json CHANGED
@@ -33,6 +33,38 @@
33
33
  "requiresAitReview": false
34
34
  }
35
35
  },
36
+ "microsoft-store": {
37
+ "runtime": "microsoft-store-pwa",
38
+ "features": {
39
+ "iap": false,
40
+ "rewardedAds": false,
41
+ "interstitialAds": false,
42
+ "leaderboard": false,
43
+ "localization": true
44
+ },
45
+ "capabilities": {
46
+ "storage": "local",
47
+ "localization": true
48
+ },
49
+ "monetization": {
50
+ "iap": false,
51
+ "rewardedAds": false,
52
+ "interstitialAds": false
53
+ },
54
+ "leaderboard": {
55
+ "native": false
56
+ },
57
+ "release": {
58
+ "profile": "microsoft-store"
59
+ },
60
+ "policy": {
61
+ "externalPaymentAllowed": false,
62
+ "remoteExecutableCodeAllowed": false,
63
+ "installOtherAppCTAAllowed": false,
64
+ "requiresStoreReview": true,
65
+ "requiresAitReview": false
66
+ }
67
+ },
36
68
  "android": {
37
69
  "runtime": "capacitor-android",
38
70
  "features": {