@bravemobile/react-native-code-push 9.0.0-alpha.0 → 9.0.0-alpha.2
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/cli/commands/releaseCommand/index.js +1 -0
- package/package.json +1 -1
- package/babel-plugin-code-push/index.js +0 -197
- package/babel-plugin-code-push/package-lock.json +0 -10463
- package/babel-plugin-code-push/package.json +0 -26
- package/babel-plugin-code-push/test/.babelrc.js +0 -12
- package/babel-plugin-code-push/test/cases/test1-config +0 -15
- package/babel-plugin-code-push/test/cases/test1-input +0 -3
- package/babel-plugin-code-push/test/cases/test1-output +0 -11
- package/babel-plugin-code-push/test/cases/test2-config +0 -9
- package/babel-plugin-code-push/test/cases/test2-input +0 -3
- package/babel-plugin-code-push/test/cases/test2-output +0 -7
- package/babel-plugin-code-push/test/codepush.config.js +0 -15
- package/babel-plugin-code-push/test/plugin.test.js +0 -44
|
@@ -5,6 +5,7 @@ const { release } = require("./release");
|
|
|
5
5
|
|
|
6
6
|
program.command('release')
|
|
7
7
|
.description('Deploys a new CodePush update for a target binary app.\nAfter creating the CodePush bundle, it uploads the file and updates the ReleaseHistory information.\n`bundleUploader`, `getReleaseHistory`, and `setReleaseHistory` functions should be implemented in the config file.')
|
|
8
|
+
.requiredOption('-b, --binary-version <string>', '(Required) The target binary version')
|
|
8
9
|
.requiredOption('-v, --app-version <string>', '(Required) The app version to be released. It must be greater than the binary version.')
|
|
9
10
|
.addOption(new Option('-p, --platform <type>', 'platform').choices(['ios', 'android']).default('ios'))
|
|
10
11
|
.option('-i, --identifier <string>', 'reserved characters to distinguish the release.')
|
package/package.json
CHANGED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
const path = require("path");
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
const { parseExpression, parse } = require("@babel/parser");
|
|
4
|
-
|
|
5
|
-
const OPTIONS_TO_BUNDLE = [
|
|
6
|
-
"bundleHost",
|
|
7
|
-
"runtimeVersion",
|
|
8
|
-
"versioning",
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
module.exports = function (babel, options) {
|
|
12
|
-
const { types: t } = babel;
|
|
13
|
-
const configPath =
|
|
14
|
-
options.configPath != null
|
|
15
|
-
? path.resolve(options.configPath)
|
|
16
|
-
: path.resolve(process.cwd(), "code-push.config.js");
|
|
17
|
-
|
|
18
|
-
// Load config and imports from `code-push.config.js`
|
|
19
|
-
const { config, configImports, importedIdentifiers } = loadConfig(
|
|
20
|
-
babel,
|
|
21
|
-
configPath
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
visitor: {
|
|
26
|
-
Program(path) {
|
|
27
|
-
// Track imports in the input file to avoid duplicates
|
|
28
|
-
const existingImports = new Set();
|
|
29
|
-
path.traverse({
|
|
30
|
-
ImportDeclaration(importPath) {
|
|
31
|
-
existingImports.add(importPath.node.source.value);
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Add missing imports from code-push.config.js to the input file
|
|
36
|
-
configImports.forEach((importNode) => {
|
|
37
|
-
if (!existingImports.has(importNode.source.value)) {
|
|
38
|
-
// Clone the import node from code-push.config.js and add it to the input file
|
|
39
|
-
path.node.body.unshift(t.cloneNode(importNode));
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
},
|
|
43
|
-
ImportDeclaration(path, state) {
|
|
44
|
-
if (
|
|
45
|
-
path.node.source.value.includes("@bravemobile/react-native-code-push")
|
|
46
|
-
) {
|
|
47
|
-
const defaultImport = path.node.specifiers.find((specifier) =>
|
|
48
|
-
t.isImportDefaultSpecifier(specifier)
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// Save the imported name (e.g., "codePush") for later use
|
|
52
|
-
if (defaultImport) {
|
|
53
|
-
state.file.metadata.codePushImportName = defaultImport.local.name;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
CallExpression(path, state) {
|
|
58
|
-
const codePushImportName = state.file.metadata.codePushImportName;
|
|
59
|
-
if (!codePushImportName) return;
|
|
60
|
-
|
|
61
|
-
// Check if the current CallExpression is a call to the codePush function
|
|
62
|
-
if (t.isIdentifier(path.node.callee, { name: codePushImportName })) {
|
|
63
|
-
// Create an AST object representation of the configuration options to bundle
|
|
64
|
-
const configObjectExpression = t.objectExpression(
|
|
65
|
-
OPTIONS_TO_BUNDLE.map((key) =>
|
|
66
|
-
t.objectProperty(
|
|
67
|
-
t.identifier(key),
|
|
68
|
-
serializeConfigToNode(babel, importedIdentifiers, config[key])
|
|
69
|
-
)
|
|
70
|
-
)
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
// Replace the arguments of codePush with the generated config object
|
|
74
|
-
path.node.arguments = [configObjectExpression];
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/** loads config file from configPath */
|
|
82
|
-
function loadConfig(babel, configPath) {
|
|
83
|
-
if (!fs.existsSync(configPath)) {
|
|
84
|
-
throw new Error(
|
|
85
|
-
"code-push.config.js not found. Please ensure it exists in the root directory."
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const { types: t } = babel;
|
|
90
|
-
const configModule = require(configPath);
|
|
91
|
-
|
|
92
|
-
const configCode = fs.readFileSync(configPath, "utf8");
|
|
93
|
-
const ast = parse(configCode, {
|
|
94
|
-
sourceType: "module",
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Extract import declarations and track imported identifiers
|
|
98
|
-
const imports = [];
|
|
99
|
-
const importedIdentifiers = new Set();
|
|
100
|
-
|
|
101
|
-
const convertRequireIntoImportStatement = (declaration) => {
|
|
102
|
-
const moduleName = declaration.init.arguments[0].value;
|
|
103
|
-
if (t.isIdentifier(declaration.id)) {
|
|
104
|
-
// Case for `const fs = require("fs")`
|
|
105
|
-
return t.importDeclaration(
|
|
106
|
-
[t.importDefaultSpecifier(declaration.id)],
|
|
107
|
-
t.stringLiteral(moduleName)
|
|
108
|
-
);
|
|
109
|
-
} else if (t.isObjectPattern(declaration.id)) {
|
|
110
|
-
// Case for `const { parse } = require("module")`
|
|
111
|
-
const importSpecifiers = declaration.id.properties.map((property) =>
|
|
112
|
-
t.importSpecifier(property.value, property.key)
|
|
113
|
-
);
|
|
114
|
-
return t.importDeclaration(importSpecifiers, t.stringLiteral(moduleName));
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
ast.program.body.forEach((node) => {
|
|
119
|
-
if (t.isImportDeclaration(node)) {
|
|
120
|
-
// Handle import statements
|
|
121
|
-
imports.push(node);
|
|
122
|
-
node.specifiers.forEach((specifier) => {
|
|
123
|
-
importedIdentifiers.add(specifier.local.name);
|
|
124
|
-
});
|
|
125
|
-
} else if (t.isVariableDeclaration(node)) {
|
|
126
|
-
// Handle require function
|
|
127
|
-
node.declarations.forEach((declaration) => {
|
|
128
|
-
if (
|
|
129
|
-
t.isCallExpression(declaration.init) &&
|
|
130
|
-
t.isIdentifier(declaration.init.callee, { name: "require" }) &&
|
|
131
|
-
declaration.init.arguments.length === 1 &&
|
|
132
|
-
t.isStringLiteral(declaration.init.arguments[0])
|
|
133
|
-
) {
|
|
134
|
-
const importDeclaration =
|
|
135
|
-
convertRequireIntoImportStatement(declaration);
|
|
136
|
-
imports.push(importDeclaration);
|
|
137
|
-
declaration.id.properties.forEach((dec) => {
|
|
138
|
-
importedIdentifiers.add(dec.value.name); // Track the imported identifier
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
config: configModule.default || configModule,
|
|
147
|
-
configImports: imports,
|
|
148
|
-
importedIdentifiers,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/** Helper to serialize config values to AST nodes */
|
|
153
|
-
function serializeConfigToNode(babel, importedIdentifiers, value) {
|
|
154
|
-
const { types: t } = babel;
|
|
155
|
-
if (["string", "number", "boolean"].includes(typeof value) || value == null) {
|
|
156
|
-
return t.valueToNode(value); // Handle primitive values
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (Array.isArray(value)) {
|
|
160
|
-
return t.arrayExpression(
|
|
161
|
-
// Recursively handle arrays
|
|
162
|
-
value.map((v) => serializeConfigToNode(babel, importedIdentifiers, v))
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (typeof value === "object") {
|
|
167
|
-
return t.objectExpression(
|
|
168
|
-
Object.entries(value).map(([key, val]) =>
|
|
169
|
-
t.objectProperty(
|
|
170
|
-
t.identifier(key),
|
|
171
|
-
serializeConfigToNode(babel, importedIdentifiers, val)
|
|
172
|
-
)
|
|
173
|
-
)
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Use identifier for imported symbols instead of inlining
|
|
178
|
-
if (importedIdentifiers.has(value.name)) {
|
|
179
|
-
return t.identifier(value.name);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// For inline functions, parse and serialize them as expressions
|
|
183
|
-
if (typeof value === "function") {
|
|
184
|
-
const valueString = value.toString();
|
|
185
|
-
try {
|
|
186
|
-
return parseExpression(valueString, { sourceType: "module" });
|
|
187
|
-
} catch (error) {
|
|
188
|
-
throw new Error(
|
|
189
|
-
`Failed to parse function ${value.name || "anonymous"}: ${
|
|
190
|
-
error.message
|
|
191
|
-
}`
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
throw new Error(`Unsupported config value type: ${typeof value}`);
|
|
197
|
-
}
|