first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
/**
* Copyright © 2023-present 650 Industries, Inc. (aka Expo)
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { ExpoConfig } from '@expo/config-types';
import xcode, { PBXFile, PBXGroup, PBXNativeTarget, PBXProject, UUID, XCBuildConfiguration, XCConfigurationList, XcodeProject } from 'xcode';
export type ProjectSectionEntry = [string, PBXProject];
export type NativeTargetSection = Record<string, PBXNativeTarget>;
export type NativeTargetSectionEntry = [string, PBXNativeTarget];
export type ConfigurationLists = Record<string, XCConfigurationList>;
export type ConfigurationListEntry = [string, XCConfigurationList];
export type ConfigurationSectionEntry = [string, XCBuildConfiguration];
export declare function getProjectName(projectRoot: string): string;
export declare function resolvePathOrProject(projectRootOrProject: string | XcodeProject): XcodeProject | null;
export declare function sanitizedName(name: string): string;
export declare function getHackyProjectName(projectRoot: string, config: ExpoConfig): string;
/**
* Add a resource file (ex: `SplashScreen.storyboard`, `Images.xcassets`) to an Xcode project.
* This is akin to creating a new code file in Xcode with `⌘+n`.
*/
export declare function addResourceFileToGroup({ filepath, groupName, isBuildFile, project, verbose, targetUuid, }: {
filepath: string;
groupName: string;
isBuildFile?: boolean;
project: XcodeProject;
verbose?: boolean;
targetUuid?: string;
}): XcodeProject;
/**
* Add a build source file (ex: `AppDelegate.m`, `ViewController.swift`) to an Xcode project.
* This is akin to creating a new code file in Xcode with `⌘+n`.
*/
export declare function addBuildSourceFileToGroup({ filepath, groupName, project, verbose, targetUuid, }: {
filepath: string;
groupName: string;
project: XcodeProject;
verbose?: boolean;
targetUuid?: string;
}): XcodeProject;
export declare function addFileToGroupAndLink({ filepath, groupName, project, verbose, addFileToProject, targetUuid, }: {
filepath: string;
groupName: string;
project: XcodeProject;
verbose?: boolean;
targetUuid?: string;
addFileToProject: (props: {
file: PBXFile;
project: XcodeProject;
}) => void;
}): XcodeProject;
export declare function getApplicationNativeTarget({ project, projectName, }: {
project: XcodeProject;
projectName: string;
}): {
uuid: UUID;
target: PBXNativeTarget;
};
/**
* Add a framework to the default app native target.
*
* @param projectName Name of the PBX project.
* @param framework String ending in `.framework`, i.e. `StoreKit.framework`
*/
export declare function addFramework({ project, projectName, framework, }: {
project: XcodeProject;
projectName: string;
framework: string;
}): unknown;
export declare function ensureGroupRecursively(project: XcodeProject, filepath: string): PBXGroup | null;
/**
* Get the pbxproj for the given path
*/
export declare function getPbxproj(projectRoot: string): XcodeProject;
/**
* Get the productName for a project, if the name is using a variable `$(TARGET_NAME)`, then attempt to get the value of that variable.
*
* @param project
*/
export declare function getProductName(project: XcodeProject): string;
export declare function getProjectSection(project: XcodeProject): Record<string, xcode.PBXProject> & Record<string, string>;
export declare function getXCConfigurationListEntries(project: XcodeProject): ConfigurationListEntry[];
export declare function getBuildConfigurationsForListId(project: XcodeProject, configurationListId: string): ConfigurationSectionEntry[];
export declare function getBuildConfigurationForListIdAndName(project: XcodeProject, { configurationListId, buildConfiguration, }: {
configurationListId: string;
buildConfiguration: string;
}): ConfigurationSectionEntry;
export declare function isBuildConfig([, sectionItem]: ConfigurationSectionEntry): boolean;
export declare function isNotTestHost([, sectionItem]: ConfigurationSectionEntry): boolean;
export declare function isNotComment([key]: ConfigurationSectionEntry | ProjectSectionEntry | ConfigurationListEntry | NativeTargetSectionEntry): boolean;
export declare function unquote(value: string): string;
export declare function resolveXcodeBuildSetting(value: string, lookup: (buildSetting: string) => string | undefined): string;

View File

@@ -0,0 +1,484 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addBuildSourceFileToGroup = addBuildSourceFileToGroup;
exports.addFileToGroupAndLink = addFileToGroupAndLink;
exports.addFramework = addFramework;
exports.addResourceFileToGroup = addResourceFileToGroup;
exports.ensureGroupRecursively = ensureGroupRecursively;
exports.getApplicationNativeTarget = getApplicationNativeTarget;
exports.getBuildConfigurationForListIdAndName = getBuildConfigurationForListIdAndName;
exports.getBuildConfigurationsForListId = getBuildConfigurationsForListId;
exports.getHackyProjectName = getHackyProjectName;
exports.getPbxproj = getPbxproj;
exports.getProductName = getProductName;
exports.getProjectName = getProjectName;
exports.getProjectSection = getProjectSection;
exports.getXCConfigurationListEntries = getXCConfigurationListEntries;
exports.isBuildConfig = isBuildConfig;
exports.isNotComment = isNotComment;
exports.isNotTestHost = isNotTestHost;
exports.resolvePathOrProject = resolvePathOrProject;
exports.resolveXcodeBuildSetting = resolveXcodeBuildSetting;
exports.sanitizedName = sanitizedName;
exports.unquote = unquote;
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _slugify() {
const data = _interopRequireDefault(require("slugify"));
_slugify = function () {
return data;
};
return data;
}
function _xcode() {
const data = _interopRequireDefault(require("xcode"));
_xcode = function () {
return data;
};
return data;
}
function _pbxFile() {
const data = _interopRequireDefault(require("xcode/lib/pbxFile"));
_pbxFile = function () {
return data;
};
return data;
}
function _string() {
const data = require("./string");
_string = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
function Paths() {
const data = _interopRequireWildcard(require("../Paths"));
Paths = function () {
return data;
};
return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright © 2023-present 650 Industries, Inc. (aka Expo)
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function getProjectName(projectRoot) {
const sourceRoot = Paths().getSourceRoot(projectRoot);
return _path().default.basename(sourceRoot);
}
function resolvePathOrProject(projectRootOrProject) {
if (typeof projectRootOrProject === 'string') {
try {
return getPbxproj(projectRootOrProject);
} catch {
return null;
}
}
return projectRootOrProject;
}
// TODO: come up with a better solution for using app.json expo.name in various places
function sanitizedName(name) {
// Default to the name `app` when every safe character has been sanitized
return sanitizedNameForProjects(name) || sanitizedNameForProjects((0, _slugify().default)(name)) || 'app';
}
function sanitizedNameForProjects(name) {
return name.replace(/[\W_]+/g, '').normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
// TODO: it's silly and kind of fragile that we look at app config to determine
// the ios project paths. Overall this function needs to be revamped, just a
// placeholder for now! Make this more robust when we support applying config
// at any time (currently it's only applied on eject).
function getHackyProjectName(projectRoot, config) {
// Attempt to get the current ios folder name (apply).
try {
return getProjectName(projectRoot);
} catch {
// If no iOS project exists then create a new one (eject).
const projectName = config.name;
(0, _assert().default)(projectName, 'Your project needs a name in app.json/app.config.js.');
return sanitizedName(projectName);
}
}
function createProjectFileForGroup({
filepath,
group
}) {
const file = new (_pbxFile().default)(filepath);
const conflictingFile = group.children.find(child => child.comment === file.basename);
if (conflictingFile) {
// This can happen when a file like the GoogleService-Info.plist needs to be added and the eject command is run twice.
// Not much we can do here since it might be a conflicting file.
return null;
}
return file;
}
/**
* Add a resource file (ex: `SplashScreen.storyboard`, `Images.xcassets`) to an Xcode project.
* This is akin to creating a new code file in Xcode with `⌘+n`.
*/
function addResourceFileToGroup({
filepath,
groupName,
// Should add to `PBXBuildFile Section`
isBuildFile,
project,
verbose,
targetUuid
}) {
return addFileToGroupAndLink({
filepath,
groupName,
project,
verbose,
targetUuid,
addFileToProject({
project,
file
}) {
project.addToPbxFileReferenceSection(file);
if (isBuildFile) {
project.addToPbxBuildFileSection(file);
}
project.addToPbxResourcesBuildPhase(file);
}
});
}
/**
* Add a build source file (ex: `AppDelegate.m`, `ViewController.swift`) to an Xcode project.
* This is akin to creating a new code file in Xcode with `⌘+n`.
*/
function addBuildSourceFileToGroup({
filepath,
groupName,
project,
verbose,
targetUuid
}) {
return addFileToGroupAndLink({
filepath,
groupName,
project,
verbose,
targetUuid,
addFileToProject({
project,
file
}) {
project.addToPbxFileReferenceSection(file);
project.addToPbxBuildFileSection(file);
project.addToPbxSourcesBuildPhase(file);
}
});
}
// TODO(brentvatne): I couldn't figure out how to do this with an existing
// higher level function exposed by the xcode library, but we should find out how to do
// that and replace this with it
function addFileToGroupAndLink({
filepath,
groupName,
project,
verbose,
addFileToProject,
targetUuid
}) {
const group = pbxGroupByPathOrAssert(project, groupName);
const file = createProjectFileForGroup({
filepath,
group
});
if (!file) {
if (verbose) {
// This can happen when a file like the GoogleService-Info.plist needs to be added and the eject command is run twice.
// Not much we can do here since it might be a conflicting file.
(0, _warnings().addWarningIOS)('ios-xcode-project', `Skipped adding duplicate file "${filepath}" to PBXGroup named "${groupName}"`);
}
return project;
}
if (targetUuid != null) {
file.target = targetUuid;
} else {
const applicationNativeTarget = project.getTarget('com.apple.product-type.application');
file.target = applicationNativeTarget?.uuid;
}
file.uuid = project.generateUuid();
file.fileRef = project.generateUuid();
addFileToProject({
project,
file
});
group.children.push({
value: file.fileRef,
comment: file.basename
});
return project;
}
function getApplicationNativeTarget({
project,
projectName
}) {
const applicationNativeTarget = project.getTarget('com.apple.product-type.application');
(0, _assert().default)(applicationNativeTarget, `Couldn't locate application PBXNativeTarget in '.xcodeproj' file.`);
(0, _assert().default)(String(applicationNativeTarget.target.name) === projectName, `Application native target name mismatch. Expected ${projectName}, but found ${applicationNativeTarget.target.name}.`);
return applicationNativeTarget;
}
/**
* Add a framework to the default app native target.
*
* @param projectName Name of the PBX project.
* @param framework String ending in `.framework`, i.e. `StoreKit.framework`
*/
function addFramework({
project,
projectName,
framework
}) {
const target = getApplicationNativeTarget({
project,
projectName
});
return project.addFramework(framework, {
target: target.uuid
});
}
function splitPath(path) {
// TODO: Should we account for other platforms that may not use `/`
return path.split('/');
}
const findGroup = (group, name) => {
if (!group) {
return undefined;
}
return group.children.find(group => group.comment === name);
};
function findGroupInsideGroup(project, group, name) {
const foundGroup = findGroup(group, name);
if (foundGroup) {
return project.getPBXGroupByKey(foundGroup.value) ?? null;
}
return null;
}
function pbxGroupByPathOrAssert(project, path) {
const {
firstProject
} = project.getFirstProject();
let group = project.getPBXGroupByKey(firstProject.mainGroup);
const components = splitPath(path);
for (const name of components) {
const nextGroup = findGroupInsideGroup(project, group, name);
if (nextGroup) {
group = nextGroup;
} else {
break;
}
}
if (!group) {
throw Error(`Xcode PBXGroup with name "${path}" could not be found in the Xcode project.`);
}
return group;
}
function ensureGroupRecursively(project, filepath) {
const components = splitPath(filepath);
const hasChild = (group, name) => group.children.find(({
comment
}) => comment === name);
const {
firstProject
} = project.getFirstProject();
let topMostGroup = project.getPBXGroupByKey(firstProject.mainGroup);
for (const pathComponent of components) {
if (topMostGroup && !hasChild(topMostGroup, pathComponent)) {
topMostGroup.children.push({
comment: pathComponent,
value: project.pbxCreateGroup(pathComponent, '""')
});
}
topMostGroup = project.pbxGroupByName(pathComponent);
}
return topMostGroup ?? null;
}
/**
* Get the pbxproj for the given path
*/
function getPbxproj(projectRoot) {
const projectPath = Paths().getPBXProjectPath(projectRoot);
const project = _xcode().default.project(projectPath);
project.parseSync();
return project;
}
/**
* Get the productName for a project, if the name is using a variable `$(TARGET_NAME)`, then attempt to get the value of that variable.
*
* @param project
*/
function getProductName(project) {
let productName = '$(TARGET_NAME)';
try {
// If the product name is numeric, this will fail (it's a getter).
// If the bundle identifier' final component is only numeric values, then the PRODUCT_NAME
// will be a numeric value, this results in a bug where the product name isn't useful,
// i.e. `com.bacon.001` -> `1` -- in this case, use the first target name.
productName = project.productName;
} catch {}
if (productName === '$(TARGET_NAME)') {
const targetName = project.getFirstTarget()?.firstTarget?.productName;
productName = targetName ?? productName;
}
return productName;
}
function getProjectSection(project) {
return project.pbxProjectSection();
}
function getXCConfigurationListEntries(project) {
const lists = project.pbxXCConfigurationList();
return Object.entries(lists).filter(isNotComment);
}
function getBuildConfigurationsForListId(project, configurationListId) {
const configurationListEntries = getXCConfigurationListEntries(project);
const [, configurationList] = configurationListEntries.find(([key]) => key === configurationListId);
const buildConfigurations = configurationList.buildConfigurations.map(i => i.value);
return Object.entries(project.pbxXCBuildConfigurationSection()).filter(isNotComment).filter(isBuildConfig).filter(([key]) => buildConfigurations.includes(key));
}
function getBuildConfigurationForListIdAndName(project, {
configurationListId,
buildConfiguration
}) {
const xcBuildConfigurationEntry = getBuildConfigurationsForListId(project, configurationListId).find(i => (0, _string().trimQuotes)(i[1].name) === buildConfiguration);
if (!xcBuildConfigurationEntry) {
throw new Error(`Build configuration '${buildConfiguration}' does not exist in list with id '${configurationListId}'`);
}
return xcBuildConfigurationEntry;
}
function isBuildConfig([, sectionItem]) {
return sectionItem.isa === 'XCBuildConfiguration';
}
function isNotTestHost([, sectionItem]) {
return !sectionItem.buildSettings.TEST_HOST;
}
function isNotComment([key]) {
return !key.endsWith(`_comment`);
}
// Remove surrounding double quotes if they exist.
function unquote(value) {
// projects with numeric names will fail due to a bug in the xcode package.
if (typeof value === 'number') {
value = String(value);
}
return value.match(/^"(.*)"$/)?.[1] ?? value;
}
function resolveXcodeBuildSetting(value, lookup) {
const parsedValue = value?.replace(/\$\(([^()]*|\([^)]*\))\)/g, match => {
// Remove the `$(` and `)`, then split modifier(s) from the variable name.
const [variable, ...transformations] = match.slice(2, -1).split(':');
// Resolve the variable recursively.
let lookedUp = lookup(variable);
if (lookedUp) {
lookedUp = resolveXcodeBuildSetting(lookedUp, lookup);
}
let resolved = lookedUp;
// Ref: http://codeworkshop.net/posts/xcode-build-setting-transformations
transformations.forEach(modifier => {
switch (modifier) {
case 'lower':
// A lowercase representation.
resolved = resolved?.toLowerCase();
break;
case 'upper':
// An uppercase representation.
resolved = resolved?.toUpperCase();
break;
case 'suffix':
if (resolved) {
// The extension of a path including the '.' divider.
resolved = _path().default.extname(resolved);
}
break;
case 'file':
if (resolved) {
// The file portion of a path.
resolved = _path().default.basename(resolved);
}
break;
case 'dir':
if (resolved) {
// The directory portion of a path.
resolved = _path().default.dirname(resolved);
}
break;
case 'base':
if (resolved) {
// The base name of a path - the last path component with any extension removed.
const b = _path().default.basename(resolved);
const extensionIndex = b.lastIndexOf('.');
resolved = extensionIndex === -1 ? b : b.slice(0, extensionIndex);
}
break;
case 'rfc1034identifier':
// A representation suitable for use in a DNS name.
// TODO: Check the spec if there is one, this is just what we had before.
resolved = resolved?.replace(/[^a-zA-Z0-9]/g, '-');
// resolved = resolved.replace(/[\/\*\s]/g, '-');
break;
case 'c99extidentifier':
// Like identifier, but with support for extended characters allowed by C99. Added in Xcode 6.
// TODO: Check the spec if there is one.
resolved = resolved?.replace(/[-\s]/g, '_');
break;
case 'standardizepath':
if (resolved) {
// The equivalent of calling stringByStandardizingPath on the string.
// https://developer.apple.com/documentation/foundation/nsstring/1407194-standardizingpath
resolved = _path().default.resolve(resolved);
}
break;
default:
resolved ||= modifier.match(/default=(.*)/)?.[1];
break;
}
});
return resolveXcodeBuildSetting(resolved ?? '', lookup);
});
if (parsedValue !== value) {
return resolveXcodeBuildSetting(parsedValue, lookup);
}
return value;
}
//# sourceMappingURL=Xcodeproj.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
import { XcodeProject } from 'xcode';
/**
* Find the Info.plist path linked to a specific build configuration.
*
* @param projectRoot
* @param param1
* @returns
*/
export declare function getInfoPlistPathFromPbxproj(projectRootOrProject: string | XcodeProject, { targetName, buildConfiguration, }?: {
targetName?: string;
buildConfiguration?: string | 'Release' | 'Debug';
}): string | null;

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getInfoPlistPathFromPbxproj = getInfoPlistPathFromPbxproj;
function _Xcodeproj() {
const data = require("./Xcodeproj");
_Xcodeproj = function () {
return data;
};
return data;
}
function _Target() {
const data = require("../Target");
_Target = function () {
return data;
};
return data;
}
/**
* Find the Info.plist path linked to a specific build configuration.
*
* @param projectRoot
* @param param1
* @returns
*/
function getInfoPlistPathFromPbxproj(projectRootOrProject, {
targetName,
buildConfiguration = 'Release'
} = {}) {
const project = (0, _Xcodeproj().resolvePathOrProject)(projectRootOrProject);
if (!project) {
return null;
}
const xcBuildConfiguration = (0, _Target().getXCBuildConfigurationFromPbxproj)(project, {
targetName,
buildConfiguration
});
if (!xcBuildConfiguration) {
return null;
}
// The `INFOPLIST_FILE` is relative to the project folder, ex: app/Info.plist.
return sanitizeInfoPlistBuildProperty(xcBuildConfiguration.buildSettings.INFOPLIST_FILE);
}
function sanitizeInfoPlistBuildProperty(infoPlist) {
return infoPlist?.replace(/"/g, '').replace('$(SRCROOT)', '') ?? null;
}
//# sourceMappingURL=getInfoPlistPath.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getInfoPlistPath.js","names":["_Xcodeproj","data","require","_Target","getInfoPlistPathFromPbxproj","projectRootOrProject","targetName","buildConfiguration","project","resolvePathOrProject","xcBuildConfiguration","getXCBuildConfigurationFromPbxproj","sanitizeInfoPlistBuildProperty","buildSettings","INFOPLIST_FILE","infoPlist","replace"],"sources":["../../../src/ios/utils/getInfoPlistPath.ts"],"sourcesContent":["import { XcodeProject } from 'xcode';\n\nimport { resolvePathOrProject } from './Xcodeproj';\nimport { getXCBuildConfigurationFromPbxproj } from '../Target';\n\n/**\n * Find the Info.plist path linked to a specific build configuration.\n *\n * @param projectRoot\n * @param param1\n * @returns\n */\nexport function getInfoPlistPathFromPbxproj(\n projectRootOrProject: string | XcodeProject,\n {\n targetName,\n buildConfiguration = 'Release',\n }: { targetName?: string; buildConfiguration?: string | 'Release' | 'Debug' } = {}\n): string | null {\n const project = resolvePathOrProject(projectRootOrProject);\n if (!project) {\n return null;\n }\n\n const xcBuildConfiguration = getXCBuildConfigurationFromPbxproj(project, {\n targetName,\n buildConfiguration,\n });\n if (!xcBuildConfiguration) {\n return null;\n }\n // The `INFOPLIST_FILE` is relative to the project folder, ex: app/Info.plist.\n return sanitizeInfoPlistBuildProperty(xcBuildConfiguration.buildSettings.INFOPLIST_FILE);\n}\n\nfunction sanitizeInfoPlistBuildProperty(infoPlist?: string): string | null {\n return infoPlist?.replace(/\"/g, '').replace('$(SRCROOT)', '') ?? null;\n}\n"],"mappings":";;;;;;AAEA,SAAAA,WAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,UAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,QAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,OAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,2BAA2BA,CACzCC,oBAA2C,EAC3C;EACEC,UAAU;EACVC,kBAAkB,GAAG;AACqD,CAAC,GAAG,CAAC,CAAC,EACnE;EACf,MAAMC,OAAO,GAAG,IAAAC,iCAAoB,EAACJ,oBAAoB,CAAC;EAC1D,IAAI,CAACG,OAAO,EAAE;IACZ,OAAO,IAAI;EACb;EAEA,MAAME,oBAAoB,GAAG,IAAAC,4CAAkC,EAACH,OAAO,EAAE;IACvEF,UAAU;IACVC;EACF,CAAC,CAAC;EACF,IAAI,CAACG,oBAAoB,EAAE;IACzB,OAAO,IAAI;EACb;EACA;EACA,OAAOE,8BAA8B,CAACF,oBAAoB,CAACG,aAAa,CAACC,cAAc,CAAC;AAC1F;AAEA,SAASF,8BAA8BA,CAACG,SAAkB,EAAiB;EACzE,OAAOA,SAAS,EAAEC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAACA,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,IAAI;AACvE","ignoreList":[]}

View File

@@ -0,0 +1 @@
export declare function trimQuotes(s: string): string;

View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.trimQuotes = trimQuotes;
function trimQuotes(s) {
return s && s[0] === '"' && s[s.length - 1] === '"' ? s.slice(1, -1) : s;
}
//# sourceMappingURL=string.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"string.js","names":["trimQuotes","s","length","slice"],"sources":["../../../src/ios/utils/string.ts"],"sourcesContent":["export function trimQuotes(s: string): string {\n return s && s[0] === '\"' && s[s.length - 1] === '\"' ? s.slice(1, -1) : s;\n}\n"],"mappings":";;;;;;AAAO,SAASA,UAAUA,CAACC,CAAS,EAAU;EAC5C,OAAOA,CAAC,IAAIA,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAIA,CAAC,CAACA,CAAC,CAACC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,GAAGD,CAAC,CAACE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAGF,CAAC;AAC1E","ignoreList":[]}