@pushmesh/sdk 0.7.3-rc.4 → 0.7.3
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/cjs/boot.js +1 -1
- package/dist/cjs/perfil.d.ts +1 -1
- package/dist/cjs/perfil.js +1 -1
- package/dist/cjs/permissions.d.ts +3 -1
- package/dist/cjs/permissions.js +1 -1
- package/package.json +1 -1
- package/plugin/index.js +114 -10
package/dist/cjs/boot.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.boot=boot;const auto_1=require("./inapp/auto"),permissions_1=require("./permissions"),players_1=require("./players");async function boot(config){if(true===config.inAppAutoMontar&&(0,auto_1.montarInAppAutomaticamente)(),await(0,players_1.init)(config),(0,permissions_1.attachAppStateHook)(),true===config.pedirPermissao)try{await(0,permissions_1.reativarNotificacoes)()}catch(e){console.warn("[PushMesh] pedirPermissao falhou",e)}(0,permissions_1.checkAndReport)().then(permissions_1.avisarSeMudo).catch(e=>console.warn("[PushMesh] checkAndReport falhou",e))}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.boot=boot;const auto_1=require("./inapp/auto"),permissions_1=require("./permissions"),players_1=require("./players");async function boot(config){if(true===config.inAppAutoMontar&&(0,auto_1.montarInAppAutomaticamente)(),await(0,players_1.init)(config),(0,permissions_1.attachAppStateHook)(),true===config.pedirPermissao)try{await(0,permissions_1.reativarNotificacoes)({comAjustes:false})}catch(e){console.warn("[PushMesh] pedirPermissao falhou",e)}(0,permissions_1.checkAndReport)().then(permissions_1.avisarSeMudo).catch(e=>console.warn("[PushMesh] checkAndReport falhou",e))}
|
package/dist/cjs/perfil.d.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* linha sozinho (script `version` → scripts/sync-versao.mjs); editando à mão,
|
|
21
21
|
* suba as duas.
|
|
22
22
|
*/
|
|
23
|
-
export declare const SDK_VERSAO = "0.7.3
|
|
23
|
+
export declare const SDK_VERSAO = "0.7.3";
|
|
24
24
|
export interface PerfilDispositivo {
|
|
25
25
|
device_os?: string;
|
|
26
26
|
fabricante?: string;
|
package/dist/cjs/perfil.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.SDK_VERSAO=void 0,exports.coletarPerfil=coletarPerfil;const react_native_1=require("react-native"),storage_1=require("./storage");function moduloPerfil(){const mods=react_native_1.NativeModules;return"ios"===react_native_1.Platform.OS?mods.PushMeshApns:mods.PushMeshFirebase}function timezoneId(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||void 0}catch{return}}function pais(){try{const loc=Intl.DateTimeFormat().resolvedOptions().locale,m=/[-_]([A-Za-z]{2})(?:[-_]|$)/.exec(loc);return m?m[1].toUpperCase():void 0}catch{return}}async function proximaSessao(){const atual=Number(await(0,storage_1.getItem)(storage_1.KEYS.sessoes)??"0"),proxima=Number.isFinite(atual)&&atual>=0?atual+1:1;return await(0,storage_1.setItem)(storage_1.KEYS.sessoes,String(proxima)),proxima}function semVazios(p){const out={};for(const[k,v]of Object.entries(p))null!=v&&""!==v&&(out[k]=v);return out}async function coletarPerfil(){const perfil={sdk_versao:exports.SDK_VERSAO,timezone_id:timezoneId(),pais:pais()};try{perfil.sessoes=await proximaSessao()}catch{}try{const nativo=moduloPerfil();if(nativo?.perfilDispositivo){const n=await nativo.perfilDispositivo();Object.assign(perfil,{device_os:n.device_os,fabricante:n.fabricante,modelo:n.modelo,net_type:n.net_type,carrier:n.carrier,rooted:n.rooted,standby_bucket:n.standby_bucket,bateria_irrestrita:n.bateria_irrestrita,notif_permissoes:n.notif_permissoes,instalacao_id:n.instalacao_id})}}catch{}if(!perfil.device_os){const v=react_native_1.Platform.Version;perfil.device_os="string"==typeof v?v:String(v)}if(!perfil.fabricante){const c=react_native_1.Platform.constants;perfil.fabricante="ios"===react_native_1.Platform.OS?"Apple":c?.Manufacturer}return semVazios(perfil)}exports.SDK_VERSAO="0.7.3
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true}),exports.SDK_VERSAO=void 0,exports.coletarPerfil=coletarPerfil;const react_native_1=require("react-native"),storage_1=require("./storage");function moduloPerfil(){const mods=react_native_1.NativeModules;return"ios"===react_native_1.Platform.OS?mods.PushMeshApns:mods.PushMeshFirebase}function timezoneId(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||void 0}catch{return}}function pais(){try{const loc=Intl.DateTimeFormat().resolvedOptions().locale,m=/[-_]([A-Za-z]{2})(?:[-_]|$)/.exec(loc);return m?m[1].toUpperCase():void 0}catch{return}}async function proximaSessao(){const atual=Number(await(0,storage_1.getItem)(storage_1.KEYS.sessoes)??"0"),proxima=Number.isFinite(atual)&&atual>=0?atual+1:1;return await(0,storage_1.setItem)(storage_1.KEYS.sessoes,String(proxima)),proxima}function semVazios(p){const out={};for(const[k,v]of Object.entries(p))null!=v&&""!==v&&(out[k]=v);return out}async function coletarPerfil(){const perfil={sdk_versao:exports.SDK_VERSAO,timezone_id:timezoneId(),pais:pais()};try{perfil.sessoes=await proximaSessao()}catch{}try{const nativo=moduloPerfil();if(nativo?.perfilDispositivo){const n=await nativo.perfilDispositivo();Object.assign(perfil,{device_os:n.device_os,fabricante:n.fabricante,modelo:n.modelo,net_type:n.net_type,carrier:n.carrier,rooted:n.rooted,standby_bucket:n.standby_bucket,bateria_irrestrita:n.bateria_irrestrita,notif_permissoes:n.notif_permissoes,instalacao_id:n.instalacao_id})}}catch{}if(!perfil.device_os){const v=react_native_1.Platform.Version;perfil.device_os="string"==typeof v?v:String(v)}if(!perfil.fabricante){const c=react_native_1.Platform.constants;perfil.fabricante="ios"===react_native_1.Platform.OS?"Apple":c?.Manufacturer}return semVazios(perfil)}exports.SDK_VERSAO="0.7.3";
|
|
@@ -35,7 +35,9 @@ export declare function openNotificationSettings(): Promise<void>;
|
|
|
35
35
|
*
|
|
36
36
|
* @returns true se, ao final, a permissão está concedida.
|
|
37
37
|
*/
|
|
38
|
-
export declare function reativarNotificacoes(
|
|
38
|
+
export declare function reativarNotificacoes(opcoes?: {
|
|
39
|
+
comAjustes?: boolean;
|
|
40
|
+
}): Promise<boolean>;
|
|
39
41
|
/**
|
|
40
42
|
* Lê a permissão e reporta ao servidor SE mudou desde o último reporte.
|
|
41
43
|
* Detecta a virada (reativação): se havia campanha Reativa aguardando e o
|
package/dist/cjs/permissions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:true,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(o,v){Object.defineProperty(o,"default",{enumerable:true,value:v})}:function(o,v){o.default=v}),__importStar=this&&this.__importStar||function(){var ownKeys=function(o){return ownKeys=Object.getOwnPropertyNames||function(o){var ar=[];for(var k in o)Object.prototype.hasOwnProperty.call(o,k)&&(ar[ar.length]=k);return ar},ownKeys(o)};return function(mod){if(mod&&mod.__esModule)return mod;var result={};if(null!=mod)for(var k=ownKeys(mod),i=0;i<k.length;i++)"default"!==k[i]&&__createBinding(result,mod,k[i]);return __setModuleDefault(result,mod),result}}();Object.defineProperty(exports,"__esModule",{value:true}),exports.mapAuthorizationStatus=mapAuthorizationStatus,exports.readNotificationTypes=readNotificationTypes,exports.canRequestNatively=canRequestNatively,exports.openNotificationSettings=openNotificationSettings,exports.reativarNotificacoes=reativarNotificacoes,exports.checkAndReport=checkAndReport,exports.markReativaPending=markReativaPending,exports.attachAppStateHook=attachAppStateHook,exports.detachAppStateHook=detachAppStateHook,exports.avisarSeMudo=avisarSeMudo;const react_native_1=__importStar(require("@notifee/react-native")),react_native_2=require("react-native"),queue_1=require("./queue"),state_1=require("./state"),storage_1=require("./storage"),types_1=require("./types");function mapAuthorizationStatus(status){switch(status){case react_native_1.AuthorizationStatus.AUTHORIZED:case react_native_1.AuthorizationStatus.PROVISIONAL:return types_1.RpNotificationTypes.Ativo;case react_native_1.AuthorizationStatus.DENIED:return types_1.RpNotificationTypes.Bloqueado;case react_native_1.AuthorizationStatus.NOT_DETERMINED:default:return types_1.RpNotificationTypes.NuncaPerguntou}}async function readNotificationTypes(){return mapAuthorizationStatus((await react_native_1.default.getNotificationSettings()).authorizationStatus)}async function canRequestNatively(){
|
|
1
|
+
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:true,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(o,v){Object.defineProperty(o,"default",{enumerable:true,value:v})}:function(o,v){o.default=v}),__importStar=this&&this.__importStar||function(){var ownKeys=function(o){return ownKeys=Object.getOwnPropertyNames||function(o){var ar=[];for(var k in o)Object.prototype.hasOwnProperty.call(o,k)&&(ar[ar.length]=k);return ar},ownKeys(o)};return function(mod){if(mod&&mod.__esModule)return mod;var result={};if(null!=mod)for(var k=ownKeys(mod),i=0;i<k.length;i++)"default"!==k[i]&&__createBinding(result,mod,k[i]);return __setModuleDefault(result,mod),result}}();Object.defineProperty(exports,"__esModule",{value:true}),exports.mapAuthorizationStatus=mapAuthorizationStatus,exports.readNotificationTypes=readNotificationTypes,exports.canRequestNatively=canRequestNatively,exports.openNotificationSettings=openNotificationSettings,exports.reativarNotificacoes=reativarNotificacoes,exports.checkAndReport=checkAndReport,exports.markReativaPending=markReativaPending,exports.attachAppStateHook=attachAppStateHook,exports.detachAppStateHook=detachAppStateHook,exports.avisarSeMudo=avisarSeMudo;const react_native_1=__importStar(require("@notifee/react-native")),react_native_2=require("react-native"),queue_1=require("./queue"),state_1=require("./state"),storage_1=require("./storage"),types_1=require("./types");function mapAuthorizationStatus(status){switch(status){case react_native_1.AuthorizationStatus.AUTHORIZED:case react_native_1.AuthorizationStatus.PROVISIONAL:return types_1.RpNotificationTypes.Ativo;case react_native_1.AuthorizationStatus.DENIED:return types_1.RpNotificationTypes.Bloqueado;case react_native_1.AuthorizationStatus.NOT_DETERMINED:default:return types_1.RpNotificationTypes.NuncaPerguntou}}async function readNotificationTypes(){return mapAuthorizationStatus((await react_native_1.default.getNotificationSettings()).authorizationStatus)}async function canRequestNatively(){const settings=await react_native_1.default.getNotificationSettings();return"android"===react_native_2.Platform.OS?settings.authorizationStatus!==react_native_1.AuthorizationStatus.AUTHORIZED&&Number(react_native_2.Platform.Version)>=33:settings.authorizationStatus===react_native_1.AuthorizationStatus.NOT_DETERMINED}async function openNotificationSettings(){if("android"===react_native_2.Platform.OS)return void await react_native_1.default.openNotificationSettings();const nativo=react_native_2.NativeModules.PushMeshApns;if(nativo?.abrirAjustesDeNotificacao)try{if(await nativo.abrirAjustesDeNotificacao())return}catch{}await react_native_2.Linking.openSettings()}async function reativarNotificacoes(opcoes={}){const{comAjustes:comAjustes=true}=opcoes;if(await canRequestNatively()){if(await react_native_1.default.requestPermission(),1===await checkAndReport())return true;if("android"!==react_native_2.Platform.OS)return false}return!!comAjustes&&(await openNotificationSettings(),1===await checkAndReport())}async function checkAndReport(){const current=await readNotificationTypes(),previousRaw=await(0,storage_1.getItem)(storage_1.KEYS.notificationTypes),previous=null===previousRaw?null:Number(previousRaw);if(previous===current)return current;const playerId=state_1.state.playerId??await(0,storage_1.getItem)(storage_1.KEYS.playerId);if(playerId&&state_1.state.config){const{sendOrQueue:sendOrQueue}=await Promise.resolve().then(()=>__importStar(require("./queue")));await sendOrQueue("PUT",`/api/v1/players/${playerId}`,{app_id:(0,state_1.requireConfig)().appId,notification_types:current}),await(0,storage_1.setItem)(storage_1.KEYS.notificationTypes,String(current))}if(current===types_1.RpNotificationTypes.Ativo&&null!==previous&&previous!==types_1.RpNotificationTypes.Ativo){const reativaPending=await(0,storage_1.getItem)(storage_1.KEYS.reativaPending);if(reativaPending){const{track:track}=await Promise.resolve().then(()=>__importStar(require("./inapp")));await track("reativou",reativaPending),await(0,storage_1.setItem)(storage_1.KEYS.reativaPending,"")}}return current}async function markReativaPending(messageId){await(0,storage_1.setItem)(storage_1.KEYS.reativaPending,messageId)}function attachAppStateHook(){state_1.state.appStateSubscription||(state_1.state.appStateSubscription=react_native_2.AppState.addEventListener("change",nextState=>{if("active"===nextState){const bgDesde=state_1.state.emBackgroundDesde;state_1.state.emBackgroundDesde=null,!state_1.state.playerId&&state_1.state.token&&state_1.state.config?Promise.resolve().then(()=>__importStar(require("./players"))).then(m=>m.register()).catch(()=>{}).finally(()=>{(0,queue_1.flushQueue)().catch(()=>{})}):(0,queue_1.flushQueue)().catch(()=>{}),checkAndReport().catch(e=>console.warn("[PushMesh] checkAndReport falhou",e)),Promise.resolve().then(()=>__importStar(require("./inapp/lifecycle"))).then(m=>m.aoVoltarAoForeground(bgDesde)).catch(()=>{})}else null===state_1.state.emBackgroundDesde&&(state_1.state.emBackgroundDesde=Date.now())}))}function detachAppStateHook(){state_1.state.appStateSubscription?.remove(),state_1.state.appStateSubscription=null}function avisarSeMudo(tipos){if(1===tipos)return;const comoResolver="chame await PushMesh.permissions.reativarNotificacoes() no momento certo do seu fluxo, ou passe { pedirPermissao: true } no init para pedir logo no boot.";console.warn(0===tipos?`[PushMesh] Este aparelho está com a notificação BLOQUEADA. O push vai ser aceito pelo FCM/APNs e NÃO vai aparecer na tela — e o recibo de entrega nunca chega. Como resolver: ${comoResolver}`:`[PushMesh] A permissão de notificação ainda não foi pedida a esta pessoa (Android 13+ e iOS exigem o pedido). Enquanto isso o push é entregue e não aparece. Como resolver: ${comoResolver}`)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushmesh/sdk",
|
|
3
|
-
"version": "0.7.3
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "React Native SDK for PushMesh — push notifications with real delivery receipts, permission re-activation and in-app banners. Classic API included. (Guia em português: README.pt-BR.md)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
package/plugin/index.js
CHANGED
|
@@ -51,6 +51,9 @@ const pkg = require('../package.json');
|
|
|
51
51
|
* lá faz a extensão não rodar EM SILÊNCIO. */
|
|
52
52
|
const ALVO_NSE = 'PushMeshNotificationService';
|
|
53
53
|
|
|
54
|
+
/** O pbxproj às vezes cita o valor, às vezes não — comparar cru erra metade. */
|
|
55
|
+
const desaspas = v => String(v ?? '').replace(/^"|"$/g, '');
|
|
56
|
+
|
|
54
57
|
// ---------------------------------------------------------------------------
|
|
55
58
|
// iOS — 1. capability Push Notifications
|
|
56
59
|
// ---------------------------------------------------------------------------
|
|
@@ -126,6 +129,27 @@ const comArquivosDaExtensao = config =>
|
|
|
126
129
|
},
|
|
127
130
|
]);
|
|
128
131
|
|
|
132
|
+
/**
|
|
133
|
+
* UUID do grupo RAIZ do projeto.
|
|
134
|
+
*
|
|
135
|
+
* Primeiro pela API (`getFirstProject`), que é o caminho certo. O laço pelo hash
|
|
136
|
+
* é rede de proteção para versões do node-xcode sem esse método — e é o que a
|
|
137
|
+
* versão anterior fazia sozinha, adivinhando "o grupo sem nome e sem caminho".
|
|
138
|
+
* Adivinhar era o problema: quando errava, ninguém ficava sabendo.
|
|
139
|
+
*/
|
|
140
|
+
const grupoRaiz = projeto => {
|
|
141
|
+
if (typeof projeto.getFirstProject === 'function') {
|
|
142
|
+
const uuid = projeto.getFirstProject()?.firstProject?.mainGroup;
|
|
143
|
+
if (uuid) return uuid;
|
|
144
|
+
}
|
|
145
|
+
const projetos = projeto.hash?.project?.objects?.PBXProject ?? {};
|
|
146
|
+
for (const chave of Object.keys(projetos)) {
|
|
147
|
+
const uuid = projetos[chave]?.mainGroup;
|
|
148
|
+
if (uuid) return uuid;
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
};
|
|
152
|
+
|
|
129
153
|
/** Cria o alvo da extensão no projeto do Xcode. */
|
|
130
154
|
const comAlvoDaExtensao = config =>
|
|
131
155
|
withXcodeProject(config, cfg => {
|
|
@@ -148,34 +172,114 @@ const comAlvoDaExtensao = config =>
|
|
|
148
172
|
ALVO_NSE,
|
|
149
173
|
ALVO_NSE,
|
|
150
174
|
);
|
|
151
|
-
// Pendura o grupo
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
175
|
+
// Pendura o grupo no grupo RAIZ declarado pelo próprio projeto.
|
|
176
|
+
//
|
|
177
|
+
// Antes isto procurava "o grupo sem nome e sem caminho" e torcia para ser a
|
|
178
|
+
// raiz. Quando o palpite errava, o grupo ficava ÓRFÃO — e aí vem a parte
|
|
179
|
+
// cruel: o `pod install`, que o prebuild roda logo em seguida, abre o
|
|
180
|
+
// projeto com a gem `xcodeproj` e PODA objetos inalcançáveis ao salvar. O
|
|
181
|
+
// grupo e o NotificationService.swift sumiam, o alvo continuava lá, e a
|
|
182
|
+
// extensão era compilada VAZIA — .appex com Info.plist e nenhum executável.
|
|
183
|
+
// O sintoma aparecia só na instalação ("is missing its bundle executable"),
|
|
184
|
+
// longe da causa, e no aparelho a imagem do push simplesmente não baixava.
|
|
185
|
+
const raiz = grupoRaiz(projeto);
|
|
186
|
+
if (!raiz) {
|
|
187
|
+
// FALHAR ALTO. Sem raiz, o grupo fica órfão, o `pod install` o poda, e a
|
|
188
|
+
// extensão é compilada vazia — o app nem instala, com um erro que fala de
|
|
189
|
+
// "bundle executable" e não diz nada sobre a causa. Melhor quebrar aqui.
|
|
190
|
+
throw new Error(
|
|
191
|
+
'[@pushmesh/sdk] não encontrei o grupo raiz do projeto do Xcode para ' +
|
|
192
|
+
'pendurar a extensão de notificação. Rode `npx expo prebuild --clean` ' +
|
|
193
|
+
'e, se persistir, abra uma issue com a versão do @expo/config-plugins.',
|
|
194
|
+
);
|
|
158
195
|
}
|
|
196
|
+
projeto.addToPbxGroup(grupo.uuid, raiz);
|
|
159
197
|
|
|
160
198
|
const alvo = projeto.addTarget(ALVO_NSE, 'app_extension', ALVO_NSE, `${bundleApp}.${ALVO_NSE}`);
|
|
161
|
-
|
|
199
|
+
// O arquivo entra JUNTO com a fase. Criar a fase vazia e depois chamar
|
|
200
|
+
// addSourceFile deixava o PBXBuildFile solto, fora da fase — e o
|
|
201
|
+
// `pod install` seguinte podava esse objeto inalcançável. O alvo compilava
|
|
202
|
+
// sem nenhuma fonte e o .appex saía sem executável.
|
|
203
|
+
projeto.addBuildPhase(
|
|
204
|
+
['NotificationService.swift'],
|
|
205
|
+
'PBXSourcesBuildPhase',
|
|
206
|
+
'Sources',
|
|
207
|
+
alvo.uuid,
|
|
208
|
+
);
|
|
162
209
|
projeto.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', alvo.uuid);
|
|
163
210
|
projeto.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', alvo.uuid);
|
|
164
|
-
projeto.addSourceFile('NotificationService.swift', { target: alvo.uuid }, grupo.uuid);
|
|
165
211
|
|
|
166
212
|
// O alvo TEM de aceitar as mesmas versões de iOS que o app: o Xcode cria a
|
|
167
213
|
// extensão no iOS mais novo, e aí ela simplesmente NÃO RODA em aparelho
|
|
168
214
|
// com versão anterior — sem erro, sem aviso, a imagem só não aparece.
|
|
169
215
|
const minimoDoApp = cfg.ios?.deploymentTarget ?? '15.1';
|
|
216
|
+
|
|
217
|
+
// O TIME de assinatura precisa ser HERDADO do app. Sem ele a build morre
|
|
218
|
+
// com "Signing for PushMeshNotificationService requires a development
|
|
219
|
+
// team" — e o desenvolvedor, que nunca pediu esta extensão, fica olhando
|
|
220
|
+
// um erro sobre um alvo que ele não criou. Ordem de busca: o que o Expo
|
|
221
|
+
// configurou (`ios.appleTeamId`), senão o que já está no alvo do APP.
|
|
170
222
|
const configs = projeto.pbxXCBuildConfigurationSection();
|
|
223
|
+
|
|
224
|
+
// As versões da extensão TÊM de ser as mesmas do app. O Info.plist dela
|
|
225
|
+
// referencia $(MARKETING_VERSION) e $(CURRENT_PROJECT_VERSION); sem essas
|
|
226
|
+
// duas no alvo, o Xcode substitui por vazio, as chaves SOMEM do plist
|
|
227
|
+
// gerado, e o iOS recusa instalar o APP INTEIRO com "Invalid placeholder
|
|
228
|
+
// attributes" — um erro que fala de uma extensão que o desenvolvedor nunca
|
|
229
|
+
// criou e não diz o que fazer.
|
|
230
|
+
let versaoMarketing;
|
|
231
|
+
let versaoProjeto;
|
|
232
|
+
{
|
|
233
|
+
const nomeApp = desaspas(`"${cfg.modRequest?.projectName ?? ''}"`);
|
|
234
|
+
for (const chave of Object.keys(configs)) {
|
|
235
|
+
const b = configs[chave].buildSettings;
|
|
236
|
+
if (!b || desaspas(b.PRODUCT_NAME) !== nomeApp) continue;
|
|
237
|
+
if (b.MARKETING_VERSION) versaoMarketing = b.MARKETING_VERSION;
|
|
238
|
+
if (b.CURRENT_PROJECT_VERSION) versaoProjeto = b.CURRENT_PROJECT_VERSION;
|
|
239
|
+
if (versaoMarketing && versaoProjeto) break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
versaoMarketing = versaoMarketing ?? `"${cfg.version ?? '1.0.0'}"`;
|
|
243
|
+
versaoProjeto = versaoProjeto ?? `"${cfg.ios?.buildNumber ?? '1'}"`;
|
|
244
|
+
|
|
245
|
+
let time = cfg.ios?.appleTeamId;
|
|
246
|
+
if (!time) {
|
|
247
|
+
const nomeApp = `"${cfg.modRequest?.projectName ?? ''}"`;
|
|
248
|
+
for (const chave of Object.keys(configs)) {
|
|
249
|
+
const b = configs[chave].buildSettings;
|
|
250
|
+
if (b?.DEVELOPMENT_TEAM && desaspas(b.PRODUCT_NAME) === desaspas(nomeApp)) {
|
|
251
|
+
time = b.DEVELOPMENT_TEAM;
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (!time) {
|
|
257
|
+
// Último recurso: QUALQUER alvo que já tenha time (o app, em projeto
|
|
258
|
+
// gerado pelo Expo, é o único com um antes de a extensão existir).
|
|
259
|
+
for (const chave of Object.keys(configs)) {
|
|
260
|
+
const t = configs[chave].buildSettings?.DEVELOPMENT_TEAM;
|
|
261
|
+
if (t && t !== '""') {
|
|
262
|
+
time = String(t).replace(/"/g, '');
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
171
268
|
for (const chave of Object.keys(configs)) {
|
|
172
269
|
const build = configs[chave].buildSettings;
|
|
173
|
-
|
|
270
|
+
// O pbxproj grava PRODUCT_NAME SEM aspas quando o nome não tem espaço —
|
|
271
|
+
// comparar só com a forma entre aspas fazia este laço não casar NUNCA, e
|
|
272
|
+
// todos os ajustes abaixo (inclusive o time de assinatura) silenciosamente
|
|
273
|
+
// não aconteciam. A build só morria lá na frente, no CodeSign.
|
|
274
|
+
if (!build || desaspas(build.PRODUCT_NAME) !== ALVO_NSE) continue;
|
|
174
275
|
build.IPHONEOS_DEPLOYMENT_TARGET = minimoDoApp;
|
|
175
276
|
build.INFOPLIST_FILE = `"${ALVO_NSE}/Info.plist"`;
|
|
176
277
|
build.SWIFT_VERSION = '5.0';
|
|
177
278
|
build.TARGETED_DEVICE_FAMILY = '"1,2"';
|
|
279
|
+
build.MARKETING_VERSION = versaoMarketing;
|
|
280
|
+
build.CURRENT_PROJECT_VERSION = versaoProjeto;
|
|
178
281
|
build.CODE_SIGN_STYLE = 'Automatic';
|
|
282
|
+
if (time) build.DEVELOPMENT_TEAM = time;
|
|
179
283
|
}
|
|
180
284
|
return cfg;
|
|
181
285
|
});
|