craft-native 0.0.497 → 0.0.500
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/android/templates/CraftAppLinks.kt.template +28 -0
- package/dist/android/templates/CraftBridge.kt.template +3 -29
- package/dist/android/templates/CraftNativeBackground.kt.template +21 -2
- package/dist/android/templates/CraftNativeCapabilities.kt.template +145 -28
- package/dist/android/templates/CraftNativeFlatList.kt.template +51 -3
- package/dist/android/templates/CraftNativeShell.kt.template +102 -2
- package/dist/android/templates/CraftNativeSounds.kt.template +22 -3
- package/dist/android/templates/MainActivityNative.kt.template +44 -14
- package/dist/api/process.d.ts +23 -28
- package/dist/bridge/core.d.ts +30 -6
- package/dist/browser.js +27 -5
- package/dist/cli.js +39 -19
- package/dist/components/index.d.ts +1 -1
- package/dist/index.cjs +90 -99
- package/dist/index.js +90 -99
- package/dist/ios/templates/CraftApp.swift +25 -1
- package/dist/ios/templates/CraftHybrid.swift +63 -22
- package/dist/ios/templates/CraftNativeActions.swift +47 -3
- package/dist/ios/templates/CraftNativeFiles.swift +160 -8
- package/dist/ios/templates/CraftNativeFlatList.swift +43 -6
- package/dist/ios/templates/CraftNativeScreen.swift +222 -69
- package/dist/ios/templates/CraftPersistentStorage.swift +28 -5
- package/dist/ios/templates/CraftScheduledWorkouts.swift +11 -4
- package/dist/ios/templates/CraftWebAudio.swift +20 -1
- package/dist/package.d.ts +22 -0
- package/package.json +1 -1
|
@@ -3067,6 +3067,19 @@ internal class CraftNativeScrollView(context: Context) : SwipeRefreshLayout(cont
|
|
|
3067
3067
|
}
|
|
3068
3068
|
}
|
|
3069
3069
|
|
|
3070
|
+
/**
|
|
3071
|
+
* How far the grouped tab actions reach over the end of this scroll view,
|
|
3072
|
+
* in pixels (#523). Its content gets that much room at the end, so the
|
|
3073
|
+
* last of it can be brought clear of them; the rest still scrolls behind
|
|
3074
|
+
* them, in the viewport it had.
|
|
3075
|
+
*/
|
|
3076
|
+
fun setFloatingCover(cover: Int) {
|
|
3077
|
+
val next = if (horizontalMode == true) 0 else max(0, cover)
|
|
3078
|
+
if (vertical.paddingBottom == next) return
|
|
3079
|
+
vertical.clipToPadding = false
|
|
3080
|
+
vertical.setPadding(vertical.paddingLeft, vertical.paddingTop, vertical.paddingRight, next)
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3070
3083
|
private var bounces = true
|
|
3071
3084
|
private var alwaysBounceVertical = true
|
|
3072
3085
|
private var alwaysBounceHorizontal = true
|
|
@@ -3585,6 +3598,17 @@ private class CraftNativeTextField(context: Context) : EditText(context) {
|
|
|
3585
3598
|
CraftNativePointers.dispatch(this, event) { super.dispatchTouchEvent(it) }
|
|
3586
3599
|
|
|
3587
3600
|
companion object { val CLEAR_ACTION_ID = View.generateViewId() }
|
|
3601
|
+
/**
|
|
3602
|
+
* `autoFocus` as this field was last drawn. Focus is taken when it turns
|
|
3603
|
+
* on, which mounting with it on is, and not on each render while it stays
|
|
3604
|
+
* on: that took the keyboard back whenever anything else changed (#511).
|
|
3605
|
+
*/
|
|
3606
|
+
private var autoFocus = false
|
|
3607
|
+
fun autoFocusTurnedOn(wanted: Boolean): Boolean {
|
|
3608
|
+
val turnedOn = wanted && !autoFocus
|
|
3609
|
+
autoFocus = wanted
|
|
3610
|
+
return turnedOn
|
|
3611
|
+
}
|
|
3588
3612
|
var clearButtonMode = "never"
|
|
3589
3613
|
var onClearRequest: (() -> Unit)? = null
|
|
3590
3614
|
private var clearPressed = false
|
|
@@ -5635,7 +5659,8 @@ class MainActivity : AppCompatActivity() {
|
|
|
5635
5659
|
if (activeScreen.active) send(activeScreen, "SOUND_EVENT", payload)
|
|
5636
5660
|
}
|
|
5637
5661
|
screen = activeScreen
|
|
5638
|
-
|
|
5662
|
+
// Not able to hear yet: its prelude is built and run below.
|
|
5663
|
+
CraftNativeHub.registerWaiting(activeScreen.capabilityScope) { type, payload ->
|
|
5639
5664
|
if (activeScreen.active) send(activeScreen, type, payload)
|
|
5640
5665
|
}
|
|
5641
5666
|
if (!headless) {
|
|
@@ -5845,6 +5870,9 @@ class MainActivity : AppCompatActivity() {
|
|
|
5845
5870
|
if (!activeScreen.active) return@addListener
|
|
5846
5871
|
try {
|
|
5847
5872
|
setup.get()
|
|
5873
|
+
// The prelude has run, so the isolate can hear: what changed
|
|
5874
|
+
// while it was being built, before the bundle reads any of it.
|
|
5875
|
+
CraftNativeHub.ready(activeScreen.capabilityScope)
|
|
5848
5876
|
val source = CraftNativeBundle.source(this, route)
|
|
5849
5877
|
if (source == null) {
|
|
5850
5878
|
if (activeScreen.active) showError("Missing native-screen.js. Build with --native-bundle after compiling STX.")
|
|
@@ -5891,6 +5919,8 @@ class MainActivity : AppCompatActivity() {
|
|
|
5891
5919
|
}
|
|
5892
5920
|
}, executor)
|
|
5893
5921
|
} catch (error: Exception) {
|
|
5922
|
+
// Nothing will run in this isolate, so nothing is kept for it.
|
|
5923
|
+
CraftNativeHub.ready(activeScreen.capabilityScope)
|
|
5894
5924
|
Log.e(TAG, "Native STX bridge failed", error)
|
|
5895
5925
|
showError("Native STX bridge failed: ${error.message}")
|
|
5896
5926
|
}
|
|
@@ -6796,7 +6826,7 @@ class MainActivity : AppCompatActivity() {
|
|
|
6796
6826
|
send(screen, "EVENT", JSONObject().put("handlerName", current).put("nativeEvent", JSONObject().put("text", text.toString())))
|
|
6797
6827
|
true
|
|
6798
6828
|
}
|
|
6799
|
-
if (craftNativeBoolean(props.opt("autoFocus")) && !isFocused) post {
|
|
6829
|
+
if (autoFocusTurnedOn(craftNativeBoolean(props.opt("autoFocus"))) && !isFocused) post {
|
|
6800
6830
|
if (!isFocused) {
|
|
6801
6831
|
requestFocus()
|
|
6802
6832
|
(getSystemService(INPUT_METHOD_SERVICE) as? android.view.inputmethod.InputMethodManager)
|
|
@@ -8723,9 +8753,13 @@ class MainActivity : AppCompatActivity() {
|
|
|
8723
8753
|
}
|
|
8724
8754
|
"pause" -> completion(CraftNativeCapabilityResult(data = screen.sounds.pause(id)))
|
|
8725
8755
|
"resume" -> completion(CraftNativeCapabilityResult(data = screen.sounds.resume(id)))
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
"
|
|
8756
|
+
// A number is a JSON number: `optDouble` also read "0.5" as one,
|
|
8757
|
+
// where UIKit answers false for a volume given as text.
|
|
8758
|
+
"setVolume" -> completion(CraftNativeCapabilityResult(data = screen.sounds.setVolume(id,
|
|
8759
|
+
(args.opt(1) as? Number)?.toDouble() ?: Double.NaN,
|
|
8760
|
+
(args.optJSONObject(2)?.opt("fade") as? Number)?.toDouble() ?: 0.0)))
|
|
8761
|
+
"stop" -> completion(CraftNativeCapabilityResult(data = screen.sounds.stop(id, screen.sounds.fadeOut(args.optJSONObject(1)))))
|
|
8762
|
+
"stopAll" -> completion(CraftNativeCapabilityResult(data = screen.sounds.stopAll(screen.sounds.fadeOut(args.optJSONObject(0)))))
|
|
8729
8763
|
else -> completion(CraftNativeCapabilityResult(code = "UNKNOWN_ACTION", message = "Unsupported Audio method"))
|
|
8730
8764
|
}
|
|
8731
8765
|
}
|
|
@@ -8865,15 +8899,8 @@ class MainActivity : AppCompatActivity() {
|
|
|
8865
8899
|
else -> CraftNativeCapabilityResult(code = "UNKNOWN_ACTION", message = "Unsupported native API")
|
|
8866
8900
|
}
|
|
8867
8901
|
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
.put("scheme", uri.scheme ?: "")
|
|
8871
|
-
.put("host", uri.host ?: "")
|
|
8872
|
-
.put("path", uri.path ?: "")
|
|
8873
|
-
.put("query", uri.query ?: "")
|
|
8874
|
-
.put("queryParams", JSONObject().apply {
|
|
8875
|
-
uri.queryParameterNames.forEach { name -> put(name, uri.getQueryParameter(name) ?: "") }
|
|
8876
|
-
})
|
|
8902
|
+
/** A link as the screens hear it: `CraftAppLinks.describe`, which the page bridge uses too. */
|
|
8903
|
+
internal fun deepLinkData(uri: android.net.Uri): JSONObject = CraftAppLinks.describe(uri)
|
|
8877
8904
|
|
|
8878
8905
|
/** App-wide news (the app's state, a link): every screen and the app script hear it. */
|
|
8879
8906
|
private fun publish(type: String, payload: JSONObject) {
|
|
@@ -9423,6 +9450,7 @@ class MainActivity : AppCompatActivity() {
|
|
|
9423
9450
|
screen.capabilityTimeouts.clear()
|
|
9424
9451
|
screen.pendingCapabilities.forEach(capabilities::cancel)
|
|
9425
9452
|
screen.pendingCapabilities.clear()
|
|
9453
|
+
capabilities.endScope(screen.capabilityScope)
|
|
9426
9454
|
releaseViewState(screen, retainedViews(screen).toList())
|
|
9427
9455
|
screen.inputWatchers.forEach { (input, watcher) -> input.removeTextChangedListener(watcher) }
|
|
9428
9456
|
screen.inputWatchers.clear()
|
|
@@ -9463,6 +9491,8 @@ class MainActivity : AppCompatActivity() {
|
|
|
9463
9491
|
screen.capabilityTimeouts.clear()
|
|
9464
9492
|
screen.pendingCapabilities.forEach(capabilities::cancel)
|
|
9465
9493
|
screen.pendingCapabilities.clear()
|
|
9494
|
+
// Again: a transaction can be begun while the isolate is closing.
|
|
9495
|
+
capabilities.endScope(screen.capabilityScope)
|
|
9466
9496
|
done()
|
|
9467
9497
|
}
|
|
9468
9498
|
}
|
package/dist/api/process.d.ts
CHANGED
|
@@ -60,7 +60,6 @@ export declare function exec(command: string, options?: ExecOptions): Promise<Ex
|
|
|
60
60
|
*/
|
|
61
61
|
export interface SpawnOptions {
|
|
62
62
|
cwd?: string;
|
|
63
|
-
env?: Record<string, string>;
|
|
64
63
|
/**
|
|
65
64
|
* Run `command` as a command line through a shell (cmd.exe on Windows,
|
|
66
65
|
* /bin/sh elsewhere) instead of executing it directly.
|
|
@@ -74,45 +73,41 @@ export interface SpawnOptions {
|
|
|
74
73
|
*/
|
|
75
74
|
shell?: boolean;
|
|
76
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* A process started through the native bridge.
|
|
78
|
+
*
|
|
79
|
+
* What native `shell.spawn` does, and so all this class offers: start a
|
|
80
|
+
* program, and kill it. The child inherits Craft's own standard output and
|
|
81
|
+
* error. Nothing it writes is delivered to the page, and its exit is not
|
|
82
|
+
* reported.
|
|
83
|
+
*
|
|
84
|
+
* `onStdout`, `onStderr`, `onExit` and `write` used to be declared here. No
|
|
85
|
+
* native bridge ever emitted the events behind them or accepted input, so a
|
|
86
|
+
* handler registered with them was never called. They are removed rather than
|
|
87
|
+
* left as methods that accept a callback and stay silent. To read a child's
|
|
88
|
+
* output, run it in your app's backend process and send the result to the
|
|
89
|
+
* page; `exec()` covers a command that finishes and returns its output whole.
|
|
90
|
+
*
|
|
91
|
+
* Windows and Linux desktop builds do not serve the `shell` namespace at all:
|
|
92
|
+
* there `start()` rejects.
|
|
93
|
+
*/
|
|
77
94
|
export declare class ChildProcess {
|
|
78
95
|
private command;
|
|
79
96
|
private args;
|
|
80
97
|
private options;
|
|
81
98
|
private processId;
|
|
82
|
-
private onStdoutHandlers;
|
|
83
|
-
private onStderrHandlers;
|
|
84
|
-
private onExitHandlers;
|
|
85
|
-
private domListeners;
|
|
86
|
-
private exited;
|
|
87
99
|
constructor(command: string, args?: string[], options?: SpawnOptions);
|
|
88
|
-
|
|
89
|
-
private removeDomListeners;
|
|
90
|
-
/** Pid assigned by the native bridge, or null before start(). */
|
|
100
|
+
/** Identifier this process is registered under, or null before start(). */
|
|
91
101
|
get pid(): string | null;
|
|
92
102
|
/**
|
|
93
|
-
* Start the process
|
|
103
|
+
* Start the process. Resolves once native has started it.
|
|
94
104
|
*/
|
|
95
105
|
start(): Promise<void>;
|
|
96
106
|
/**
|
|
97
|
-
*
|
|
98
|
-
|
|
99
|
-
write(data: string): Promise<void>;
|
|
100
|
-
/**
|
|
101
|
-
* Kill the process
|
|
102
|
-
*/
|
|
103
|
-
kill(signal?: string): Promise<void>;
|
|
104
|
-
/**
|
|
105
|
-
* Listen for stdout data
|
|
106
|
-
*/
|
|
107
|
-
onStdout(handler: (data: string) => void): () => void;
|
|
108
|
-
/**
|
|
109
|
-
* Listen for stderr data
|
|
110
|
-
*/
|
|
111
|
-
onStderr(handler: (data: string) => void): () => void;
|
|
112
|
-
/**
|
|
113
|
-
* Listen for exit
|
|
107
|
+
* Kill the process. Native sends the platform's default termination; there
|
|
108
|
+
* is no signal to choose.
|
|
114
109
|
*/
|
|
115
|
-
|
|
110
|
+
kill(): Promise<void>;
|
|
116
111
|
}
|
|
117
112
|
/**
|
|
118
113
|
* Spawn a child process
|
package/dist/bridge/core.d.ts
CHANGED
|
@@ -46,6 +46,12 @@ export declare const BridgeErrorCodes: {
|
|
|
46
46
|
readonly PROTOCOL_MISMATCH: -8;
|
|
47
47
|
/** Bridge transitioned from connected to disconnected with requests in flight */
|
|
48
48
|
readonly DISCONNECTED: -9;
|
|
49
|
+
/**
|
|
50
|
+
* The native side received the request and refused or failed it. Not
|
|
51
|
+
* retried: asking again gets the same answer. `data.nativeCode` carries
|
|
52
|
+
* the bridge's own string code when it sent one.
|
|
53
|
+
*/
|
|
54
|
+
readonly NATIVE_ERROR: -10;
|
|
49
55
|
};
|
|
50
56
|
export type BridgeErrorCode = typeof BridgeErrorCodes[keyof typeof BridgeErrorCodes];
|
|
51
57
|
/**
|
|
@@ -136,12 +142,12 @@ export declare class NativeBridge extends EventEmitter {
|
|
|
136
142
|
* BridgeError(PROTOCOL_MISMATCH) if the native side reports a version we
|
|
137
143
|
* don't speak.
|
|
138
144
|
*
|
|
139
|
-
* This is **opt-in** — you must call it explicitly
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
+
* This is **opt-in** — you must call it explicitly, and only against a
|
|
146
|
+
* host of your own that answers a `_handshake` request. Craft's own
|
|
147
|
+
* webview hosts do not: inside one, requests go through
|
|
148
|
+
* `window.craft.invoke`, which takes `namespace.action` names, and this
|
|
149
|
+
* call is rejected immediately instead of negotiating anything. Use
|
|
150
|
+
* `window.craft.capabilities` to ask a Craft host what it serves.
|
|
145
151
|
*/
|
|
146
152
|
handshake(): Promise<{
|
|
147
153
|
nativeVersion: number;
|
|
@@ -203,6 +209,24 @@ export declare class NativeBridge extends EventEmitter {
|
|
|
203
209
|
* use that to fail fast instead of waiting for the request timeout.
|
|
204
210
|
*/
|
|
205
211
|
private send;
|
|
212
|
+
/**
|
|
213
|
+
* Hand a request to `window.craft.invoke`, the dispatcher that
|
|
214
|
+
* `craft-bridge.js` injects into every Craft webview, and settle the
|
|
215
|
+
* pending entry with what native answers.
|
|
216
|
+
*
|
|
217
|
+
* This is the only path by which `request()` reaches native code. The
|
|
218
|
+
* `{id, type: 'request', method, params}` envelope this class builds is not
|
|
219
|
+
* something any Craft host parses: posted raw to the `craft` message
|
|
220
|
+
* handler it was dropped, and every `request()` waited out its timeout and
|
|
221
|
+
* its retries. The method name is used as written, `namespace.action`, so
|
|
222
|
+
* it has to be one the native bridge serves (`fs.readFile`,
|
|
223
|
+
* `shell.openUrl`, `dialog.openFile`); one it does not serve is rejected
|
|
224
|
+
* with `NATIVE_ERROR` straight away.
|
|
225
|
+
*
|
|
226
|
+
* Returns false when the injected bridge is not present, so the older
|
|
227
|
+
* transports below still get their turn in a host that provides one.
|
|
228
|
+
*/
|
|
229
|
+
private sendThroughInjectedBridge;
|
|
206
230
|
/**
|
|
207
231
|
* Reject the pending entry corresponding to `message.id` with `error`,
|
|
208
232
|
* if any. Used by `send()` when serialization or transport throws so
|
package/dist/browser.js
CHANGED
|
@@ -909,8 +909,24 @@ async function createBrowserPlatform(options = {}) {
|
|
|
909
909
|
}
|
|
910
910
|
if (method === "write") {
|
|
911
911
|
const settings = object(args[2]);
|
|
912
|
-
const
|
|
913
|
-
|
|
912
|
+
const [name, data] = args;
|
|
913
|
+
const refuse = (message) => Object.assign(new Error(message), { code: "INVALID_ARGUMENT" });
|
|
914
|
+
if (typeof name !== "string" || !name.trim())
|
|
915
|
+
throw refuse("files.write needs a file name");
|
|
916
|
+
if (typeof data !== "string")
|
|
917
|
+
throw refuse("files.write needs its contents as a string");
|
|
918
|
+
const encoding = settings.encoding ?? "utf8";
|
|
919
|
+
if (encoding !== "utf8" && encoding !== "base64")
|
|
920
|
+
throw refuse("files.write encoding is 'utf8' or 'base64'");
|
|
921
|
+
let contents = data;
|
|
922
|
+
if (encoding === "base64") {
|
|
923
|
+
try {
|
|
924
|
+
contents = Uint8Array.from(atob(data), (letter) => letter.charCodeAt(0));
|
|
925
|
+
} catch {
|
|
926
|
+
throw refuse("files.write base64 is invalid");
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
return file([contents], name, String(settings.type ?? "application/octet-stream"));
|
|
914
930
|
}
|
|
915
931
|
if (method === "remove") {
|
|
916
932
|
const path = String(args[0]);
|
|
@@ -1071,14 +1087,15 @@ async function createBrowserPlatform(options = {}) {
|
|
|
1071
1087
|
throw error;
|
|
1072
1088
|
}
|
|
1073
1089
|
}
|
|
1090
|
+
const fadeOut = (options) => typeof options.fadeOut === "number" ? options.fadeOut : 0;
|
|
1074
1091
|
if (method === "stopAll") {
|
|
1075
1092
|
soundRequests.clear();
|
|
1076
|
-
await Promise.all([...sounds.keys()].map((key) => stopSound(key,
|
|
1093
|
+
await Promise.all([...sounds.keys()].map((key) => stopSound(key, fadeOut(first))));
|
|
1077
1094
|
return true;
|
|
1078
1095
|
}
|
|
1079
1096
|
if (method === "stop") {
|
|
1080
1097
|
soundRequests.delete(id);
|
|
1081
|
-
await stopSound(id,
|
|
1098
|
+
await stopSound(id, fadeOut(object(args[1])));
|
|
1082
1099
|
return Boolean(sound);
|
|
1083
1100
|
}
|
|
1084
1101
|
if (!sound)
|
|
@@ -1092,7 +1109,12 @@ async function createBrowserPlatform(options = {}) {
|
|
|
1092
1109
|
return true;
|
|
1093
1110
|
}
|
|
1094
1111
|
if (method === "setVolume") {
|
|
1095
|
-
|
|
1112
|
+
const volume = args[1];
|
|
1113
|
+
const asked = object(args[2]).fade;
|
|
1114
|
+
const milliseconds = typeof asked === "number" ? asked : 0;
|
|
1115
|
+
if (typeof volume !== "number" || !Number.isFinite(volume) || !Number.isFinite(milliseconds) || milliseconds < 0)
|
|
1116
|
+
return false;
|
|
1117
|
+
await fade(sound, volume, milliseconds);
|
|
1096
1118
|
return true;
|
|
1097
1119
|
}
|
|
1098
1120
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1395,6 +1395,33 @@ Description: ${description || opts.name}
|
|
|
1395
1395
|
}
|
|
1396
1396
|
});
|
|
1397
1397
|
}
|
|
1398
|
+
function rpmSpec(options) {
|
|
1399
|
+
return [
|
|
1400
|
+
"%global debug_package %{nil}",
|
|
1401
|
+
"%global _build_id_links none",
|
|
1402
|
+
"%global __strip /bin/true",
|
|
1403
|
+
"%global __os_install_post %{nil}",
|
|
1404
|
+
`Name: ${options.name}`,
|
|
1405
|
+
`Version: ${options.version}`,
|
|
1406
|
+
"Release: 1",
|
|
1407
|
+
`Summary: ${options.summary}`,
|
|
1408
|
+
"License: MIT",
|
|
1409
|
+
`Source0: ${options.name}`,
|
|
1410
|
+
...options.requires ? [`Requires: ${options.requires}`] : [],
|
|
1411
|
+
"",
|
|
1412
|
+
"%description",
|
|
1413
|
+
options.description,
|
|
1414
|
+
"",
|
|
1415
|
+
"%install",
|
|
1416
|
+
"mkdir -p %{buildroot}/usr/bin",
|
|
1417
|
+
`install -m 755 %{SOURCE0} %{buildroot}/usr/bin/${options.name}`,
|
|
1418
|
+
"",
|
|
1419
|
+
"%files",
|
|
1420
|
+
`/usr/bin/${options.name}`,
|
|
1421
|
+
""
|
|
1422
|
+
].join(`
|
|
1423
|
+
`);
|
|
1424
|
+
}
|
|
1398
1425
|
async function createRPM(opts) {
|
|
1399
1426
|
return new Promise((resolve) => {
|
|
1400
1427
|
try {
|
|
@@ -1427,26 +1454,17 @@ async function createRPM(opts) {
|
|
|
1427
1454
|
return r;
|
|
1428
1455
|
}).join(", ");
|
|
1429
1456
|
copyFileSync(opts.binaryPath, join3(sourcesDir, sanitizedName));
|
|
1430
|
-
const specContent =
|
|
1431
|
-
Version: ${opts.version}
|
|
1432
|
-
Release: 1%{?dist}
|
|
1433
|
-
Summary: ${summary}
|
|
1434
|
-
License: MIT
|
|
1435
|
-
Requires: ${requires}
|
|
1436
|
-
|
|
1437
|
-
%description
|
|
1438
|
-
${description}
|
|
1439
|
-
|
|
1440
|
-
%install
|
|
1441
|
-
mkdir -p %{buildroot}/usr/bin
|
|
1442
|
-
install -m 755 %{SOURCE0} %{buildroot}/usr/bin/${sanitizedName}
|
|
1443
|
-
|
|
1444
|
-
%files
|
|
1445
|
-
/usr/bin/${sanitizedName}
|
|
1446
|
-
`;
|
|
1457
|
+
const specContent = rpmSpec({ name: sanitizedName, version: opts.version, summary, description, requires });
|
|
1447
1458
|
const specPath = join3(specDir, `${opts.name.toLowerCase()}.spec`);
|
|
1448
1459
|
writeFileSync4(specPath, specContent);
|
|
1449
1460
|
const proc = spawn("rpmbuild", ["-bb", specPath]);
|
|
1461
|
+
let said = "";
|
|
1462
|
+
proc.stdout?.on("data", (chunk) => {
|
|
1463
|
+
said += chunk.toString();
|
|
1464
|
+
});
|
|
1465
|
+
proc.stderr?.on("data", (chunk) => {
|
|
1466
|
+
said += chunk.toString();
|
|
1467
|
+
});
|
|
1450
1468
|
proc.on("close", (code) => {
|
|
1451
1469
|
if (code === 0) {
|
|
1452
1470
|
const rpmName = `${opts.name.toLowerCase()}-${opts.version}-1.x86_64.rpm`;
|
|
@@ -1458,7 +1476,9 @@ install -m 755 %{SOURCE0} %{buildroot}/usr/bin/${sanitizedName}
|
|
|
1458
1476
|
resolve({ success: false, error: "Failed to copy built RPM" });
|
|
1459
1477
|
}
|
|
1460
1478
|
} else {
|
|
1461
|
-
resolve({ success: false, error: `rpmbuild exited with code ${code}
|
|
1479
|
+
resolve({ success: false, error: `rpmbuild exited with code ${code}: ${said.trim().split(`
|
|
1480
|
+
`).slice(-12).join(`
|
|
1481
|
+
`)}` });
|
|
1462
1482
|
}
|
|
1463
1483
|
});
|
|
1464
1484
|
proc.on("error", (err) => {
|
|
@@ -3246,7 +3266,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
|
|
|
3246
3266
|
`);
|
|
3247
3267
|
}
|
|
3248
3268
|
// package.json
|
|
3249
|
-
var version = "0.0.
|
|
3269
|
+
var version = "0.0.500";
|
|
3250
3270
|
|
|
3251
3271
|
// bin/cli.ts
|
|
3252
3272
|
var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
|
|
@@ -801,7 +801,7 @@ export interface TextInputProps extends BaseProps {
|
|
|
801
801
|
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters';
|
|
802
802
|
/** Auto correct */
|
|
803
803
|
autoCorrect?: boolean;
|
|
804
|
-
/**
|
|
804
|
+
/** Focus the input when it mounts, or when this turns on; not on each render. */
|
|
805
805
|
autoFocus?: boolean;
|
|
806
806
|
/** Secure text entry (password) */
|
|
807
807
|
secureTextEntry?: boolean;
|