voltra 2.0.0 → 2.1.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.
- package/build/cjs/config/normalize.js +93 -0
- package/build/cjs/config/normalize.js.map +1 -1
- package/build/cjs/index.js +5 -2
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/platforms/android/apply.js +11 -2
- package/build/cjs/platforms/android/apply.js.map +1 -1
- package/build/cjs/platforms/android/generated.js +152 -130
- package/build/cjs/platforms/android/generated.js.map +1 -1
- package/build/cjs/platforms/android/gradle.js +120 -0
- package/build/cjs/platforms/android/gradle.js.map +1 -0
- package/build/cjs/platforms/ios/generated.js +246 -142
- package/build/cjs/platforms/ios/generated.js.map +1 -1
- package/build/cjs/platforms/ios/xcodeTarget.js +68 -0
- package/build/cjs/platforms/ios/xcodeTarget.js.map +1 -1
- package/build/cjs/platforms/shared/widgetModule.js +151 -0
- package/build/cjs/platforms/shared/widgetModule.js.map +1 -0
- package/build/esm/config/normalize.js +93 -0
- package/build/esm/config/normalize.js.map +1 -1
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/platforms/android/apply.js +11 -2
- package/build/esm/platforms/android/apply.js.map +1 -1
- package/build/esm/platforms/android/generated.js +152 -97
- package/build/esm/platforms/android/generated.js.map +1 -1
- package/build/esm/platforms/android/gradle.js +112 -0
- package/build/esm/platforms/android/gradle.js.map +1 -0
- package/build/esm/platforms/ios/generated.js +246 -109
- package/build/esm/platforms/ios/generated.js.map +1 -1
- package/build/esm/platforms/ios/xcodeTarget.js +69 -1
- package/build/esm/platforms/ios/xcodeTarget.js.map +1 -1
- package/build/esm/platforms/shared/widgetModule.js +111 -0
- package/build/esm/platforms/shared/widgetModule.js.map +1 -0
- package/build/types/config/normalize.d.ts.map +1 -1
- package/build/types/config/types.d.ts +32 -0
- package/build/types/config/types.d.ts.map +1 -1
- package/build/types/index.d.ts +3 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/platforms/android/apply.d.ts.map +1 -1
- package/build/types/platforms/android/generated.d.ts.map +1 -1
- package/build/types/platforms/android/gradle.d.ts +18 -0
- package/build/types/platforms/android/gradle.d.ts.map +1 -0
- package/build/types/platforms/ios/generated.d.ts.map +1 -1
- package/build/types/platforms/ios/xcodeTarget.d.ts.map +1 -1
- package/build/types/platforms/shared/widgetModule.d.ts +9 -0
- package/build/types/platforms/shared/widgetModule.d.ts.map +1 -0
- package/package.json +2 -1
- package/src/apply/index.ts +309 -0
- package/src/apply/preflight.ts +172 -0
- package/src/bin.ts +14 -0
- package/src/commands/apply.ts +114 -0
- package/src/config/defaults.ts +34 -0
- package/src/config/load.ts +100 -0
- package/src/config/normalize.ts +562 -0
- package/src/config/types.ts +317 -0
- package/src/cosmiconfig.d.ts +21 -0
- package/src/dependencies/platformPackages.ts +75 -0
- package/src/discovery/android.ts +233 -0
- package/src/discovery/ios.ts +579 -0
- package/src/fs/path.ts +25 -0
- package/src/fs/readWrite.ts +102 -0
- package/src/git/status.ts +205 -0
- package/src/index.ts +204 -0
- package/src/platforms/android/apply.ts +106 -0
- package/src/platforms/android/generated.ts +1284 -0
- package/src/platforms/android/gradle.ts +155 -0
- package/src/platforms/android/manifest.ts +379 -0
- package/src/platforms/ios/apply.ts +139 -0
- package/src/platforms/ios/deploymentTarget.ts +47 -0
- package/src/platforms/ios/entitlements.ts +146 -0
- package/src/platforms/ios/generated.ts +1233 -0
- package/src/platforms/ios/mainAppEntitlements.ts +11 -0
- package/src/platforms/ios/plist.ts +321 -0
- package/src/platforms/ios/podfile.ts +255 -0
- package/src/platforms/ios/targetName.ts +11 -0
- package/src/platforms/ios/xcode.ts +181 -0
- package/src/platforms/ios/xcodeTarget.ts +899 -0
- package/src/platforms/shared/widgetModule.ts +153 -0
- package/src/reporting/clack.ts +67 -0
- package/src/reporting/summary.ts +116 -0
- package/src/state/diff.ts +21 -0
- package/src/state/files.ts +52 -0
- package/src/state/load.ts +66 -0
- package/src/state/save.ts +31 -0
- package/src/xml2js.d.ts +23 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const VOLTRA_MIN_IOS_DEPLOYMENT_TARGET = '16.4'
|
|
2
|
+
|
|
3
|
+
export function compareIOSDeploymentTargets(left: string, right: string): number | undefined {
|
|
4
|
+
const leftParts = parseIOSDeploymentTarget(left)
|
|
5
|
+
const rightParts = parseIOSDeploymentTarget(right)
|
|
6
|
+
|
|
7
|
+
if (!leftParts || !rightParts) {
|
|
8
|
+
return undefined
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const length = Math.max(leftParts.length, rightParts.length)
|
|
12
|
+
|
|
13
|
+
for (let index = 0; index < length; index += 1) {
|
|
14
|
+
const leftPart = leftParts[index] ?? 0
|
|
15
|
+
const rightPart = rightParts[index] ?? 0
|
|
16
|
+
|
|
17
|
+
if (leftPart > rightPart) {
|
|
18
|
+
return 1
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (leftPart < rightPart) {
|
|
22
|
+
return -1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return 0
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isIOSDeploymentTargetAtLeast(value: string, minimum: string): boolean | undefined {
|
|
30
|
+
const comparison = compareIOSDeploymentTargets(value, minimum)
|
|
31
|
+
return comparison === undefined ? undefined : comparison >= 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function maxIOSDeploymentTarget(left: string, right: string): string {
|
|
35
|
+
const comparison = compareIOSDeploymentTargets(left, right)
|
|
36
|
+
return comparison !== undefined && comparison >= 0 ? left : right
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseIOSDeploymentTarget(value: string): number[] | undefined {
|
|
40
|
+
const normalizedValue = value.trim().replace(/^"|"$/g, '').replace(/^'|'$/g, '')
|
|
41
|
+
|
|
42
|
+
if (!/^\d+(?:\.\d+){0,2}$/.test(normalizedValue)) {
|
|
43
|
+
return undefined
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return normalizedValue.split('.').map((part) => Number(part))
|
|
47
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { pathExists, readTextFile, writeTextFile } from '../../fs/readWrite'
|
|
2
|
+
import { toRelativePath } from '../../fs/path'
|
|
3
|
+
import { VoltraCliError } from '../../reporting/summary'
|
|
4
|
+
|
|
5
|
+
import { buildPlistXml, parsePlistFile } from './plist'
|
|
6
|
+
import { resolveMainAppEntitlementsPath } from './mainAppEntitlements'
|
|
7
|
+
|
|
8
|
+
import type { IOSProjectDiscovery } from '../../discovery/ios'
|
|
9
|
+
import type { NormalizedVoltraIOSConfig } from '../../config/types'
|
|
10
|
+
import type { ReportedChange } from '../../reporting/summary'
|
|
11
|
+
|
|
12
|
+
interface PreviousVoltraEntitlementValues {
|
|
13
|
+
appGroupIdentifier?: string
|
|
14
|
+
keychainGroup?: string
|
|
15
|
+
pushNotificationsEnabled: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface EnsureEntitlementsOptions {
|
|
19
|
+
projectRoot: string
|
|
20
|
+
ios: NormalizedVoltraIOSConfig
|
|
21
|
+
discovery: IOSProjectDiscovery
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface EnsureEntitlementsResult {
|
|
25
|
+
change?: ReportedChange
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class IOSEntitlementsMutationError extends VoltraCliError {
|
|
29
|
+
constructor(message: string) {
|
|
30
|
+
super(message, 'VOLTRA_IOS_ENTITLEMENTS_FAILED')
|
|
31
|
+
this.name = 'IOSEntitlementsMutationError'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function ensureEntitlements(options: EnsureEntitlementsOptions): Promise<EnsureEntitlementsResult> {
|
|
36
|
+
const { projectRoot, ios, discovery } = options
|
|
37
|
+
const entitlementsPath = resolveMainAppEntitlementsPath(discovery)
|
|
38
|
+
|
|
39
|
+
if (!discovery.entitlementsPath) {
|
|
40
|
+
if (!needsEntitlementsMutation(ios)) {
|
|
41
|
+
return {}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const entitlements: Record<string, unknown> = (await pathExists(entitlementsPath))
|
|
46
|
+
? await parsePlistFile(entitlementsPath, 'main app entitlements', createEntitlementsError)
|
|
47
|
+
: {}
|
|
48
|
+
const previousVoltraValues = await readPreviousVoltraEntitlementValues(discovery.infoPlistPath)
|
|
49
|
+
|
|
50
|
+
ensureStringArrayValue(
|
|
51
|
+
entitlements,
|
|
52
|
+
'com.apple.security.application-groups',
|
|
53
|
+
ios.groupIdentifier,
|
|
54
|
+
previousVoltraValues.appGroupIdentifier
|
|
55
|
+
)
|
|
56
|
+
ensureStringArrayValue(entitlements, 'keychain-access-groups', ios.keychainGroup, previousVoltraValues.keychainGroup)
|
|
57
|
+
|
|
58
|
+
if (ios.enablePushNotifications && entitlements['aps-environment'] === undefined) {
|
|
59
|
+
entitlements['aps-environment'] = 'development'
|
|
60
|
+
} else if (
|
|
61
|
+
!ios.enablePushNotifications &&
|
|
62
|
+
previousVoltraValues.pushNotificationsEnabled &&
|
|
63
|
+
entitlements['aps-environment'] === 'development'
|
|
64
|
+
) {
|
|
65
|
+
delete entitlements['aps-environment']
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const nextContent = buildPlistXml(entitlements, createEntitlementsError)
|
|
69
|
+
const change = await writeEntitlementsIfChanged(projectRoot, entitlementsPath, nextContent)
|
|
70
|
+
|
|
71
|
+
return { change }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function needsEntitlementsMutation(ios: NormalizedVoltraIOSConfig): boolean {
|
|
75
|
+
return ios.enablePushNotifications || ios.groupIdentifier !== undefined || ios.keychainGroup !== undefined
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function ensureStringArrayValue(
|
|
79
|
+
target: Record<string, unknown>,
|
|
80
|
+
key: string,
|
|
81
|
+
nextValue: string | undefined,
|
|
82
|
+
previousOwnedValue: string | undefined
|
|
83
|
+
): void {
|
|
84
|
+
const existingValues = Array.isArray(target[key])
|
|
85
|
+
? target[key].filter((value): value is string => typeof value === 'string' && value.length > 0)
|
|
86
|
+
: []
|
|
87
|
+
const dedupedValues = Array.from(new Set(existingValues))
|
|
88
|
+
const filteredValues = previousOwnedValue
|
|
89
|
+
? dedupedValues.filter((value) => value !== previousOwnedValue)
|
|
90
|
+
: dedupedValues
|
|
91
|
+
|
|
92
|
+
if (nextValue === undefined) {
|
|
93
|
+
if (filteredValues.length === 0) {
|
|
94
|
+
delete target[key]
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (filteredValues.length !== existingValues.length) {
|
|
99
|
+
target[key] = filteredValues
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Preserve unrelated user-managed values in shared entitlements.
|
|
106
|
+
// V1 does not attempt to undo historical shared-file mutations.
|
|
107
|
+
if (!filteredValues.includes(nextValue)) {
|
|
108
|
+
filteredValues.push(nextValue)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
target[key] = filteredValues
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function writeEntitlementsIfChanged(
|
|
115
|
+
projectRoot: string,
|
|
116
|
+
entitlementsPath: string,
|
|
117
|
+
nextContent: string
|
|
118
|
+
): Promise<ReportedChange | undefined> {
|
|
119
|
+
const previousContent = (await pathExists(entitlementsPath)) ? await readTextFile(entitlementsPath) : undefined
|
|
120
|
+
|
|
121
|
+
if (previousContent === nextContent) {
|
|
122
|
+
return undefined
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await writeTextFile(entitlementsPath, nextContent)
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
kind: previousContent === undefined ? 'created' : 'updated',
|
|
129
|
+
path: toRelativePath(projectRoot, entitlementsPath),
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function createEntitlementsError(message: string): IOSEntitlementsMutationError {
|
|
134
|
+
return new IOSEntitlementsMutationError(message)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function readPreviousVoltraEntitlementValues(infoPlistPath: string): Promise<PreviousVoltraEntitlementValues> {
|
|
138
|
+
const infoPlist = await parsePlistFile(infoPlistPath, 'main app Info.plist', createEntitlementsError)
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
appGroupIdentifier:
|
|
142
|
+
typeof infoPlist.Voltra_AppGroupIdentifier === 'string' ? infoPlist.Voltra_AppGroupIdentifier : undefined,
|
|
143
|
+
keychainGroup: typeof infoPlist.Voltra_KeychainGroup === 'string' ? infoPlist.Voltra_KeychainGroup : undefined,
|
|
144
|
+
pushNotificationsEnabled: infoPlist.Voltra_EnablePushNotifications === true,
|
|
145
|
+
}
|
|
146
|
+
}
|