Compare commits

...

22 Commits

Author SHA1 Message Date
d67e47ae4b nix(module): module boilerplate 2025-02-20 10:27:18 +01:00
b43b8da9ab nix (test): fix build 2025-02-20 10:17:14 +01:00
8534e16469 docs: +sidebar. 2025-02-19 20:20:21 -05:00
f6cc6f2eae docs: Minor prep for 0.0.28. 2025-02-19 19:54:45 -05:00
0904425221 update: CodeMirror. 2025-02-19 19:04:59 -05:00
a729886522 update: sqlite 3.49.1. 2025-02-19 18:59:45 -05:00
e5dfedc7d1 ios: Drop min ios version to 14. Generate more of the Info.plist. We don't use non-exempt encryption. 2025-02-19 18:49:53 -05:00
f02423d084 ios: Now with more sed. 2025-02-18 21:46:04 -05:00
8f4b6e83eb ios: This fixes the build on macos and runs in the simulator. 2025-02-18 21:28:03 -05:00
3029919553 ios: Might as well generate the CFBundleShortVersionString from that other version. 2025-02-18 20:58:16 -05:00
ac67db0591 Merge pull request 'nix: fix build instructions fuckup' (#107) from tasiaiso/tildefriends:tasiaiso-fix-fuckup-holy-shit into main
Reviewed-on: cory/tildefriends#107
2025-02-18 19:26:56 -05:00
1e08838f5b ios: I was able to get an iOS build to app store connect with this. Sanity lost. 2025-02-18 19:03:25 -05:00
d814f7ee77 nix: update flake lockfile, fix update procedure 2025-02-18 22:41:00 +01:00
7edfb9d386 docs: I forgot to do this last release. 2025-02-17 21:16:38 -05:00
6928d6caba cleanup: prettier. 2025-02-16 15:52:27 -05:00
1a626875cf build: Link warning on macos. 2025-02-16 15:13:45 -05:00
6eb3b64334 build: Fix android aab build. 2025-02-16 14:41:14 -05:00
09f3595e93 ssb: Use the right shape for your own profile image. 2025-02-16 14:37:45 -05:00
11e89622d4 security: Respect the autologin setting better. 2025-02-16 14:07:14 -05:00
0fa8acc264 ios: Untested, but attempt auto-login. 2025-02-16 13:42:07 -05:00
afc7c64ed8 android: Fix launch args. 2025-02-16 13:41:26 -05:00
c794c1b885 admin: Global settings can be specified on the command-line. Removed some previous, less thorough ways of configuring things. #102 2025-02-16 13:37:25 -05:00
79 changed files with 565 additions and 405 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@ deps/openssl/
dist/ dist/
.flatpak-builder .flatpak-builder
.keys .keys
**/.DS_Store
logs/ logs/
**/node_modules **/node_modules
out out

View File

@@ -1680,7 +1680,7 @@ DISABLE_INDEX = NO
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO GENERATE_TREEVIEW = YES
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the # When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview # FULL_SIDEBAR option determines if the side bar is limited to only the treeview

View File

@@ -17,10 +17,13 @@ MAKEFLAGS += --no-builtin-rules
## ANDROID_SDK := Path to the Android SDK. ## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 33 VERSION_CODE := 33
VERSION_CODE_IOS := 8
VERSION_NUMBER := 0.0.28-wip VERSION_NUMBER := 0.0.28-wip
VERSION_NAME := This program kills fascists. VERSION_NAME := This program kills fascists.
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3490000.zip IPHONEOS_VERSION_MIN=14.0
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3490100.zip
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool
@@ -302,8 +305,8 @@ $(ANDROID_X86_64_TARGETS): LDFLAGS += -Lout/openssl/android/x86_64/usr/local/lib
$(NONMACOS_TARGETS): CFLAGS += -Wno-cast-function-type $(NONMACOS_TARGETS): CFLAGS += -Wno-cast-function-type
$(MACOS_TARGETS): LDFLAGS += -Wl,-dead_strip $(MACOS_TARGETS): LDFLAGS += -Wl,-dead_strip
$(NONMACOS_TARGETS): LDFLAGS += -Wl,--gc-sections -Wl,--as-needed $(NONMACOS_TARGETS): LDFLAGS += -Wl,--gc-sections -Wl,--as-needed
$(IOS_TARGETS): CFLAGS += -miphoneos-version-min=9.0 $(IOS_TARGETS): CFLAGS += -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0 $(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
$(IOS_TARGETS): CFLAGS += -Iout/openssl/ios/ios64-xcrun/usr/local/include $(IOS_TARGETS): CFLAGS += -Iout/openssl/ios/ios64-xcrun/usr/local/include
$(IOS_TARGETS): LDFLAGS += -Lout/openssl/ios/ios64-xcrun/usr/local/lib $(IOS_TARGETS): LDFLAGS += -Lout/openssl/ios/ios64-xcrun/usr/local/lib
@@ -808,7 +811,7 @@ $(MINIUNZIP_OBJS): CFLAGS += \
LDFLAGS += \ LDFLAGS += \
-pthread \ -pthread \
-lm -lm
$(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS) $(MACOS_TARGETS): LDFLAGS += \ $(HOST_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS) $(filter-out $(HOST_TARGETS),$(MACOS_TARGETS)): LDFLAGS += \
-lssl \ -lssl \
-lcrypto -lcrypto
ifneq ($(UNAME_S),Haiku) ifneq ($(UNAME_S),Haiku)
@@ -910,6 +913,17 @@ src/android/AndroidManifest.xml : $(firstword $(MAKEFILE_LIST))
-e 's/android:targetSdkVersion="[[:digit:]]*"/android:targetSdkVersion="$(ANDROID_TARGET_SDK_VERSION)"/' \ -e 's/android:targetSdkVersion="[[:digit:]]*"/android:targetSdkVersion="$(ANDROID_TARGET_SDK_VERSION)"/' \
$@ $@
src/ios/Info.plist : $(firstword $(MAKEFILE_LIST))
@echo "[ios_version] $@"
@cat $@ | \
tr '\n' '^' | \
sed -r \
-e 's@(<key>CFBundleShortVersionString</key>\^[[:space:]]*<string>)[0-9.]*(</string>)@\1$(VERSION_NUMBER:%-wip=%)\2@' \
-e 's@(<key>CFBundleVersion</key>\^[[:space:]]*<string>)[[:digit:]]+(</string>)@\1$(VERSION_CODE_IOS)\2@' \
-e 's@(<key>MinimumOSVersion</key>\^[[:space:]]*<string>)[0-9.]*(</string>)@\1$(IPHONEOS_VERSION_MIN)\2@' | \
tr '^' '\n' > \
$@.tmp && mv $@.tmp $@ || rm -f $@.tmp
## ##
## Android targets: ## Android targets:
## ##
@@ -967,11 +981,11 @@ out/apk/classes.dex: $(CLASS_FILES)
@$(ANDROID_BUILD_TOOLS)/d8 --lib $(ANDROID_PLATFORM)/android.jar --output $(dir $@) out/classes/com/unprompted/tildefriends/*.class @$(ANDROID_BUILD_TOOLS)/d8 --lib $(ANDROID_PLATFORM)/android.jar --output $(dir $@) out/classes/com/unprompted/tildefriends/*.class
PACKAGE_DIRS := \ PACKAGE_DIRS := \
apps/ \ apps \
core/ \ core \
deps/codemirror/ \ deps/codemirror \
deps/prettier/ \ deps/prettier \
deps/lit/ deps/lit
RAW_FILES := $(sort $(filter-out apps/blog% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f -not -name '.*'))) RAW_FILES := $(sort $(filter-out apps/blog% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f -not -name '.*')))
@@ -1001,6 +1015,7 @@ out/TildeFriends.aab: out/apk/classes.dex $(filter-out %debug%, $(ANDROID_TARGET
--manifest src/android/AndroidManifest.xml \ --manifest src/android/AndroidManifest.xml \
-R out/res/layout_activity_main.xml.flat \ -R out/res/layout_activity_main.xml.flat \
-R out/res/drawable_icon.xml.flat \ -R out/res/drawable_icon.xml.flat \
-R out/res/drawable_logo.xml.flat \
--auto-add-overlay --auto-add-overlay
@unzip out/aab/temporary.apk -d out/aab/staging/ @unzip out/aab/temporary.apk -d out/aab/staging/
@mkdir -p out/aab/staging/root/deps @mkdir -p out/aab/staging/root/deps
@@ -1218,7 +1233,7 @@ $(LOCAL_DEPS):
CROSS_TOP=../../deps/ios_toolchain/target \ CROSS_TOP=../../deps/ios_toolchain/target \
CROSS_SDK=iPhoneOS18.2.sdk \ CROSS_SDK=iPhoneOS18.2.sdk \
CC=clang \ CC=clang \
OPTIONS=-miphoneos-version-min=9.0 \ OPTIONS=-miphoneos-version-min=$(IPHONEOS_VERSION_MIN) \
tools/ssl-local tools/ssl-local
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(LOCAL_DEPS) $(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(LOCAL_DEPS)
endif endif
@@ -1265,7 +1280,7 @@ endif
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
IOS_DEPS := out/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a IOS_DEPS := out/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
$(IOS_DEPS): $(IOS_DEPS):
+@BUILD_PLATFORM=ios BUILD_TARGET=ios64-xcrun SSL_TARGET=ios64-xcrun OPTIONS="-fPIC -Wno-macro-redefined -miphoneos-version-min=9.0" tools/ssl-local +@BUILD_PLATFORM=ios BUILD_TARGET=ios64-xcrun SSL_TARGET=ios64-xcrun OPTIONS="-fPIC -Wno-macro-redefined -miphoneos-version-min=$(IPHONEOS_VERSION_MIN)" tools/ssl-local
+@BUILD_PLATFORM=ios BUILD_TARGET=iossimulator-xcrun SSL_TARGET=iossimulator-xcrun OPTIONS="-fPIC -Wno-macro-redefined" tools/ssl-local +@BUILD_PLATFORM=ios BUILD_TARGET=iossimulator-xcrun SSL_TARGET=iossimulator-xcrun OPTIONS="-fPIC -Wno-macro-redefined" tools/ssl-local
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS) $(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS)
endif endif
@@ -1399,6 +1414,17 @@ dist-test: dist ## Exercise some built distributable files, making sure they wor
@rm -rf tildefriends-$(VERSION_NUMBER) @rm -rf tildefriends-$(VERSION_NUMBER)
.PHONY: dist-test .PHONY: dist-test
dist-ios: iosrelease-app
rm -rfv out/Payload out/tildefriends.ipa
mkdir -p out/Payload/tildefriends.app
cp -avR out/tildefriends-iosrelease.app/* out/Payload/tildefriends.app/
cp src/ios/tildefriends.png out/Payload/tildefriends.app/
cp src/ios/icons/Assets.car out/Payload/tildefriends.app/
cp src/ios/distribution.mobileprovision out/Payload/tildefriends.app/embedded.mobileprovision
xcrun -sdk iphoneos codesign -f -s 'Apple Distribution' --entitlements src/ios/Entitlements.plist --generate-entitlement-der out/Payload/tildefriends.app
cd out; zip -r tildefriends.ipa Payload; cd ..
xcrun -sdk iphoneos altool --upload-app -f out/tildefriends.ipa -t ios -u $$(cat .keys/altool-user) -p $$(cat .keys/altool-password)
## ##
## Targets for tidying up: ## Targets for tidying up:
## ##

View File

@@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🎛", "emoji": "🎛",
"previous": "&R49FywYF8CXPhoSEydLbSCgvCddeyTiBwGuDU/gqY+M=.sha256" "previous": "&kmKNyb/uaXNb24gCinJtfS8iWx4cLUWdtl0y2DwEUas=.sha256"
} }

View File

@@ -72,7 +72,7 @@ ${description.value}</textarea
</button> </button>
</li> </li>
`; `;
} else { } else if (description.type != 'hidden') {
return html` return html`
<li class="w3-row"> <li class="w3-row">
<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label> <label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${title_case(key)}</label>

View File

@@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&weo9lucKMSz3xzM6l3knRepNnyRIzKlaJnP9NDJAk+g=.sha256" "previous": "&jAAzd36Nmpw0sRA1Dx9wLiIwGX+q//+S/Han+RLlEOw=.sha256"
} }

View File

@@ -21,7 +21,9 @@ class TfUserElement extends LitElement {
render() { render() {
let user = this.users[this.id]; let user = this.users[this.id];
let shape = let shape =
!user?.follow_depth || user.follow_depth >= 2 ? 'w3-circle' : 'w3-round'; user?.follow_depth === undefined || user.follow_depth >= 2
? 'w3-circle'
: 'w3-round';
let image = html`<span let image = html`<span
class=${'w3-theme-l4 ' + shape} class=${'w3-theme-l4 ' + shape}
style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em" style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em"

View File

@@ -470,7 +470,6 @@ async function getProcessBlob(blobId, key, options) {
imports.ssb = Object.fromEntries( imports.ssb = Object.fromEntries(
Object.keys(ssb).map((key) => [key, ssb[key].bind(ssb)]) Object.keys(ssb).map((key) => [key, ssb[key].bind(ssb)])
); );
imports.ssb.port = tildefriends.ssb_port;
imports.ssb.createIdentity = () => process.createIdentity(); imports.ssb.createIdentity = () => process.createIdentity();
imports.ssb.addIdentity = function (id) { imports.ssb.addIdentity = function (id) {
if ( if (

View File

@@ -1,4 +1,8 @@
# How to upgrade to a newer version # How to upgrade to a newer version
# - On the june and december release, you'll have to update nixpkgs to the current branch
# Change `nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";`
# to the latest release (see https://nixos.org/)
# - Run `$ nix flake update`
# - Comment `src.hash` # - Comment `src.hash`
# - Change `version` # - Change `version`
# - Run `$ nix build` # - Run `$ nix build`
@@ -21,14 +25,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.27.1"; version = "0.0.28";
src = pkgs.fetchFromGitea { src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net"; domain = "dev.tildefriends.net";
owner = "cory"; owner = "cory";
repo = "tildefriends"; repo = "tildefriends";
rev = "v${version}"; rev = "f02423d0846fefd5ab21fa4542fb77ce5714547c";
hash = "sha256-3t1m9ZomQF3DteWyALJWrnCq0EAROEK8shKXh6Ao38c="; hash = "sha256-QyM7wmViXJc4r8uTu4oE/HO3Z9tzNbFIX2+AOTQz9ZY=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

File diff suppressed because one or more lines are too long

170
deps/codemirror_src/package-lock.json generated vendored
View File

@@ -144,9 +144,9 @@
} }
}, },
"node_modules/@codemirror/view": { "node_modules/@codemirror/view": {
"version": "6.36.2", "version": "6.36.3",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.2.tgz", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.3.tgz",
"integrity": "sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA==", "integrity": "sha512-N2bilM47QWC8Hnx0rMdDxO2x2ImJ1FvZWXubwKgjeoOrWwEiFrtpA7SFHcuZ+o2Ze2VzbkgbzWVj4+V18LVkeg==",
"dependencies": { "dependencies": {
"@codemirror/state": "^6.5.0", "@codemirror/state": "^6.5.0",
"style-mod": "^4.1.0", "style-mod": "^4.1.0",
@@ -344,9 +344,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
"integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==", "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -356,9 +356,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
"integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==", "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -368,9 +368,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
"integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==", "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -380,9 +380,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
"integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==", "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -392,9 +392,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
"integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==", "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -404,9 +404,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
"integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==", "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -416,9 +416,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
"integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==", "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -428,9 +428,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
"integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==", "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -440,9 +440,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
"integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==", "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -452,9 +452,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
"integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==", "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -464,9 +464,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
"integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==", "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -476,9 +476,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
"integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==", "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -488,9 +488,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
"integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==", "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -500,9 +500,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
"integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==", "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -512,9 +512,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
"integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==", "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -524,9 +524,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
"integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==", "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -536,9 +536,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
"integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==", "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -548,9 +548,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
"integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==", "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -560,9 +560,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
"integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==", "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -733,9 +733,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.34.6", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz",
"integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==", "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
"dependencies": { "dependencies": {
"@types/estree": "1.0.6" "@types/estree": "1.0.6"
}, },
@@ -747,25 +747,25 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.34.6", "@rollup/rollup-android-arm-eabi": "4.34.8",
"@rollup/rollup-android-arm64": "4.34.6", "@rollup/rollup-android-arm64": "4.34.8",
"@rollup/rollup-darwin-arm64": "4.34.6", "@rollup/rollup-darwin-arm64": "4.34.8",
"@rollup/rollup-darwin-x64": "4.34.6", "@rollup/rollup-darwin-x64": "4.34.8",
"@rollup/rollup-freebsd-arm64": "4.34.6", "@rollup/rollup-freebsd-arm64": "4.34.8",
"@rollup/rollup-freebsd-x64": "4.34.6", "@rollup/rollup-freebsd-x64": "4.34.8",
"@rollup/rollup-linux-arm-gnueabihf": "4.34.6", "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
"@rollup/rollup-linux-arm-musleabihf": "4.34.6", "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
"@rollup/rollup-linux-arm64-gnu": "4.34.6", "@rollup/rollup-linux-arm64-gnu": "4.34.8",
"@rollup/rollup-linux-arm64-musl": "4.34.6", "@rollup/rollup-linux-arm64-musl": "4.34.8",
"@rollup/rollup-linux-loongarch64-gnu": "4.34.6", "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.6", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
"@rollup/rollup-linux-riscv64-gnu": "4.34.6", "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
"@rollup/rollup-linux-s390x-gnu": "4.34.6", "@rollup/rollup-linux-s390x-gnu": "4.34.8",
"@rollup/rollup-linux-x64-gnu": "4.34.6", "@rollup/rollup-linux-x64-gnu": "4.34.8",
"@rollup/rollup-linux-x64-musl": "4.34.6", "@rollup/rollup-linux-x64-musl": "4.34.8",
"@rollup/rollup-win32-arm64-msvc": "4.34.6", "@rollup/rollup-win32-arm64-msvc": "4.34.8",
"@rollup/rollup-win32-ia32-msvc": "4.34.6", "@rollup/rollup-win32-ia32-msvc": "4.34.8",
"@rollup/rollup-win32-x64-msvc": "4.34.6", "@rollup/rollup-win32-x64-msvc": "4.34.8",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@@ -840,9 +840,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.38.2", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.38.2.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
"integrity": "sha512-w8CXxxbFA5zfNsR/i8HZq5bvn18AK0O9jj7hyo1YqkovLxEFa0uP0LCVGZRqiRaKRFxXhELBp8SteeAjEnfeJg==", "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",

22
deps/sqlite/sqlite3.c vendored
View File

@@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite ** This file is an amalgamation of many separate C source files from SQLite
** version 3.49.0. By combining all the individual C code files into this ** version 3.49.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation ** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be ** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements ** possible if the files were compiled separately. Performance improvements
@@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library. ** separate file. This file contains only code for the core SQLite library.
** **
** The content in this amalgamation comes from Fossil check-in ** The content in this amalgamation comes from Fossil check-in
** 4a7dd425dc2a0e5082a9049c9b4a9d4f199a with changes in files: ** 873d4e274b4988d260ba8354a9718324a1c2 with changes in files:
** **
** **
*/ */
@@ -465,9 +465,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.49.0" #define SQLITE_VERSION "3.49.1"
#define SQLITE_VERSION_NUMBER 3049000 #define SQLITE_VERSION_NUMBER 3049001
#define SQLITE_SOURCE_ID "2025-02-06 11:55:18 4a7dd425dc2a0e5082a9049c9b4a9d4f199a71583d014c24b4cfe276c5a77cde" #define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@@ -131067,7 +131067,7 @@ static void concatFuncCore(
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
n += sqlite3_value_bytes(argv[i]); n += sqlite3_value_bytes(argv[i]);
} }
n += (argc-1)*nSep; n += (argc-1)*(i64)nSep;
z = sqlite3_malloc64(n+1); z = sqlite3_malloc64(n+1);
if( z==0 ){ if( z==0 ){
sqlite3_result_error_nomem(context); sqlite3_result_error_nomem(context);
@@ -182305,7 +182305,7 @@ SQLITE_API int sqlite3_config(int op, ...){
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#ifndef SQLITE_OMIT_LOOKASIDE #ifndef SQLITE_OMIT_LOOKASIDE
void *pStart; void *pStart;
sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt; sqlite3_int64 szAlloc;
int nBig; /* Number of full-size slots */ int nBig; /* Number of full-size slots */
int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */
@@ -182324,7 +182324,9 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
*/ */
sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
if( sz>65528 ) sz = 65528;
if( cnt<0 ) cnt = 0; if( cnt<0 ) cnt = 0;
szAlloc = (i64)sz*(i64)cnt;
if( sz==0 || cnt==0 ){ if( sz==0 || cnt==0 ){
sz = 0; sz = 0;
pStart = 0; pStart = 0;
@@ -182339,10 +182341,10 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
if( sz>=LOOKASIDE_SMALL*3 ){ if( sz>=LOOKASIDE_SMALL*3 ){
nBig = szAlloc/(3*LOOKASIDE_SMALL+sz); nBig = szAlloc/(3*LOOKASIDE_SMALL+sz);
nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL; nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL;
}else if( sz>=LOOKASIDE_SMALL*2 ){ }else if( sz>=LOOKASIDE_SMALL*2 ){
nBig = szAlloc/(LOOKASIDE_SMALL+sz); nBig = szAlloc/(LOOKASIDE_SMALL+sz);
nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL; nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL;
}else }else
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
if( sz>0 ){ if( sz>0 ){
@@ -255872,7 +255874,7 @@ static void fts5SourceIdFunc(
){ ){
assert( nArg==0 ); assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused); UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2025-02-06 11:55:18 4a7dd425dc2a0e5082a9049c9b4a9d4f199a71583d014c24b4cfe276c5a77cde", -1, SQLITE_TRANSIENT); sqlite3_result_text(pCtx, "fts5: 2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70", -1, SQLITE_TRANSIENT);
} }
/* /*

View File

@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.49.0" #define SQLITE_VERSION "3.49.1"
#define SQLITE_VERSION_NUMBER 3049000 #define SQLITE_VERSION_NUMBER 3049001
#define SQLITE_SOURCE_ID "2025-02-06 11:55:18 4a7dd425dc2a0e5082a9049c9b4a9d4f199a71583d014c24b4cfe276c5a77cde" #define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers

View File

@@ -6,10 +6,14 @@
- update metadata/en-US/changelogs - update metadata/en-US/changelogs
- git tag - git tag
- push - push
- make dist
- make a release on gitea - make a release on gitea
- upload the artifacts - upload the artifacts
- upload the AppImage and zsyncmake
- upload to Google
- upload to Apple with dist-ios on macos
- nix - nix
- june and december: update release version
- run `nix flake update`
- comment out the hash in default.nix - comment out the hash in default.nix
- update the version - update the version
- run `nix-build` - run `nix-build`

14
flake.lock generated
View File

@@ -5,11 +5,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1731533236,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -20,16 +20,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1717281328, "lastModified": 1739758141,
"narHash": "sha256-evZPzpf59oNcDUXxh2GHcxHkTEG4fjae2ytWP85jXRo=", "narHash": "sha256-uq6A2L7o1/tR6VfmYhZWoVAwb3gTy7j4Jx30MIrH0rE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b3b2b28c1daa04fe2ae47c21bb76fd226eac4ca1", "rev": "c618e28f70257593de75a7044438efc1c1fc0791",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.05", "ref": "nixos-24.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

View File

@@ -2,7 +2,7 @@
description = "Tilde Friends is a platform for making, running, and sharing web applications."; description = "Tilde Friends is a platform for making, running, and sharing web applications.";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
@@ -35,5 +35,27 @@
graphviz graphviz
]; ];
}; };
nixosModules.default = {
config,
lib,
...
}: let
# Shorter name to access final settings a
# user of hello.nix module HAS ACTUALLY SET.
# cfg is a typical convention.
cfg = config.services.tildefriends;
in {
options.services.tildefriends = {
enable = lib.mkEnableOption "Enable Tilde Friends";
};
config = lib.mkIf cfg.enable {
systemd.services.tildefriends = {
wantedBy = ["multi-user.target"];
serviceConfig.ExecStart = "${pkgs.tildefriends}/bin/tildefriends";
};
};
};
}); });
} }

View File

@@ -0,0 +1,14 @@
* An iOS build is on TestFlight.
* macOS targets are debug and release like everywhere else.
* Running from a subdirectory is fine.
* Patchwork compatibility improvements.
* Invite fixes.
* Follow/block UI fixes.
* Mobile automatically logs in.
* Allow specifying all global settings from the command-line.
* UpdateS:
* CodeMirror
* OpenSSL 3.4.1
* libbacktrace
* sqlite 3.49.1
* speedscope 1.22.2

6
package-lock.json generated
View File

@@ -11,9 +11,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.5.0", "version": "3.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.0.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz",
"integrity": "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA==", "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==",
"bin": { "bin": {
"prettier": "bin/prettier.cjs" "prettier": "bin/prettier.cjs"
}, },

View File

@@ -2166,31 +2166,22 @@ static void _httpd_endpoint_logout(tf_http_request_t* request)
tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0); tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
} }
static bool _task_arg_is_mobile(tf_task_t* task)
{
bool result = false;
JSContext* context = tf_task_get_context(task);
JSValue global = JS_GetGlobalObject(context);
JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends");
JSValue args = JS_GetPropertyStr(context, tildefriends, "args");
JSValue mobile = JS_GetPropertyStr(context, args, "mobile");
result = JS_ToBool(context, mobile) != 0;
JS_FreeValue(context, mobile);
JS_FreeValue(context, args);
JS_FreeValue(context, tildefriends);
JS_FreeValue(context, global);
return result;
}
typedef struct _auto_login_t typedef struct _auto_login_t
{ {
tf_http_request_t* request; tf_http_request_t* request;
bool autologin;
const char* users; const char* users;
} auto_login_t; } auto_login_t;
static void _httpd_auto_login_work(tf_ssb_t* ssb, void* user_data) static void _httpd_auto_login_work(tf_ssb_t* ssb, void* user_data)
{ {
auto_login_t* request = user_data; auto_login_t* request = user_data;
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
tf_ssb_db_get_global_setting_bool(db, "autologin", &request->autologin);
tf_ssb_release_db_reader(ssb, db);
if (request->autologin)
{
request->users = tf_ssb_db_get_property(ssb, "auth", "users"); request->users = tf_ssb_db_get_property(ssb, "auth", "users");
if (request->users && strcmp(request->users, "[]") == 0) if (request->users && strcmp(request->users, "[]") == 0)
{ {
@@ -2217,6 +2208,7 @@ static void _httpd_auto_login_work(tf_ssb_t* ssb, void* user_data)
request->users = tf_ssb_db_get_property(ssb, "auth", "users"); request->users = tf_ssb_db_get_property(ssb, "auth", "users");
} }
}
} }
static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_data) static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_data)
@@ -2224,6 +2216,13 @@ static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_d
auto_login_t* work = user_data; auto_login_t* work = user_data;
JSContext* context = tf_ssb_get_context(ssb); JSContext* context = tf_ssb_get_context(ssb);
const char* session_token = NULL; const char* session_token = NULL;
if (!work->autologin)
{
const char* k_payload = tf_http_status_text(404);
tf_http_respond(work->request, 404, NULL, 0, k_payload, strlen(k_payload));
}
else
{
if (work->users) if (work->users)
{ {
JSValue json = JS_ParseJSON(context, work->users, strlen(work->users), NULL); JSValue json = JS_ParseJSON(context, work->users, strlen(work->users), NULL);
@@ -2255,6 +2254,7 @@ static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_d
}; };
tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0);
} }
}
tf_http_request_unref(work->request); tf_http_request_unref(work->request);
tf_free((void*)work->users); tf_free((void*)work->users);
tf_free(work); tf_free(work);
@@ -2263,20 +2263,12 @@ static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_d
static void _httpd_endpoint_login_auto(tf_http_request_t* request) static void _httpd_endpoint_login_auto(tf_http_request_t* request)
{ {
tf_task_t* task = request->user_data; tf_task_t* task = request->user_data;
if (tf_util_is_mobile() || _task_arg_is_mobile(task))
{
tf_http_request_ref(request); tf_http_request_ref(request);
tf_ssb_t* ssb = tf_task_get_ssb(task); tf_ssb_t* ssb = tf_task_get_ssb(task);
auto_login_t* work = tf_malloc(sizeof(auto_login_t)); auto_login_t* work = tf_malloc(sizeof(auto_login_t));
*work = (auto_login_t) { .request = request }; *work = (auto_login_t) { .request = request };
tf_ssb_run_work(ssb, _httpd_auto_login_work, _httpd_auto_login_after_work, work); tf_ssb_run_work(ssb, _httpd_auto_login_work, _httpd_auto_login_after_work, work);
}
else
{
const char* k_payload = tf_http_status_text(404);
tf_http_respond(request, 404, NULL, 0, k_payload, strlen(k_payload));
}
} }
static void _httpd_endpoint_app_socket(tf_http_request_t* request) static void _httpd_endpoint_app_socket(tf_http_request_t* request)
@@ -2319,35 +2311,6 @@ static void _httpd_endpoint_app_socket(tf_http_request_t* request)
JS_FreeValue(context, global); JS_FreeValue(context, global);
} }
static int _tf_httpd_get_tildefriends_int(JSContext* context, const char* arg)
{
JSValue global = JS_GetGlobalObject(context);
JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends");
JSValue arg_value = JS_GetPropertyStr(context, tildefriends, arg);
int value = 0;
JS_ToInt32(context, &value, arg_value);
JS_FreeValue(context, arg_value);
JS_FreeValue(context, tildefriends);
JS_FreeValue(context, global);
return value;
}
static const char* _tf_httpd_get_tildefriends_arg_string(JSContext* context, const char* arg)
{
JSValue global = JS_GetGlobalObject(context);
JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends");
JSValue args = JS_GetPropertyStr(context, tildefriends, "args");
JSValue arg_value = JS_GetPropertyStr(context, args, arg);
const char* value = !JS_IsUndefined(arg_value) ? JS_ToCString(context, arg_value) : NULL;
const char* result = value ? tf_strdup(value) : NULL;
JS_FreeCString(context, value);
JS_FreeValue(context, arg_value);
JS_FreeValue(context, args);
JS_FreeValue(context, tildefriends);
JS_FreeValue(context, global);
return result;
}
static void _httpd_free_user_data(void* user_data) static void _httpd_free_user_data(void* user_data)
{ {
tf_free(user_data); tf_free(user_data);
@@ -2394,10 +2357,6 @@ void tf_httpd_register(JSContext* context)
fprintf(stderr, "Failed to register Request.\n"); fprintf(stderr, "Failed to register Request.\n");
} }
int http_port = _tf_httpd_get_tildefriends_int(context, "http_port");
int https_port = _tf_httpd_get_tildefriends_int(context, "https_port");
const char* out_http_port_file = _tf_httpd_get_tildefriends_arg_string(context, "out_http_port_file");
JSValue global = JS_GetGlobalObject(context); JSValue global = JS_GetGlobalObject(context);
JSValue httpd = JS_NewObjectClass(context, _httpd_class_id); JSValue httpd = JS_NewObjectClass(context, _httpd_class_id);
@@ -2408,6 +2367,15 @@ void tf_httpd_register(JSContext* context)
tf_http_set_trace(http, tf_task_get_trace(task)); tf_http_set_trace(http, tf_task_get_trace(task));
JS_SetOpaque(httpd, http); JS_SetOpaque(httpd, http);
int64_t http_port = 0;
int64_t https_port = 0;
char out_http_port_file[512] = "";
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
tf_ssb_db_get_global_setting_int64(db, "http_port", &http_port);
tf_ssb_db_get_global_setting_int64(db, "https_port", &https_port);
tf_ssb_db_get_global_setting_string(db, "out_http_port_file", out_http_port_file, sizeof(out_http_port_file));
tf_ssb_release_db_reader(ssb, db);
if (https_port) if (https_port)
{ {
http_user_data_t* user_data = tf_http_get_user_data(http); http_user_data_t* user_data = tf_http_get_user_data(http);
@@ -2463,14 +2431,14 @@ void tf_httpd_register(JSContext* context)
JS_SetPropertyStr(context, global, "httpd", httpd); JS_SetPropertyStr(context, global, "httpd", httpd);
JS_FreeValue(context, global); JS_FreeValue(context, global);
if (http_port > 0 || out_http_port_file) if (http_port > 0 || *out_http_port_file)
{ {
httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t)); httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t));
*listener = (httpd_listener_t) { 0 }; *listener = (httpd_listener_t) { 0 };
int assigned_port = tf_http_listen(http, http_port, NULL, _httpd_listener_cleanup, listener); int assigned_port = tf_http_listen(http, http_port, NULL, _httpd_listener_cleanup, listener);
tf_printf(CYAN "~😎 Tilde Friends" RESET " " YELLOW VERSION_NUMBER RESET " is now up at " MAGENTA "http://127.0.0.1:%d/" RESET ".\n", assigned_port); tf_printf(CYAN "~😎 Tilde Friends" RESET " " YELLOW VERSION_NUMBER RESET " is now up at " MAGENTA "http://127.0.0.1:%d/" RESET ".\n", assigned_port);
if (out_http_port_file) if (*out_http_port_file)
{ {
const char* actual_http_port_file = tf_task_get_path_with_root(task, out_http_port_file); const char* actual_http_port_file = tf_task_get_path_with_root(task, out_http_port_file);
FILE* file = fopen(actual_http_port_file, "wb"); FILE* file = fopen(actual_http_port_file, "wb");
@@ -2507,6 +2475,4 @@ void tf_httpd_register(JSContext* context)
tf_free((char*)private_key); tf_free((char*)private_key);
} }
} }
tf_free((void*)out_http_port_file);
} }

View File

@@ -16,7 +16,7 @@ void tf_run_thread_start(const char* zip_path);
static void _start_initial_load(WKWebView* web_view) static void _start_initial_load(WKWebView* web_view)
{ {
[web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:12345/"]]]; [web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:12345/login/auto"]]];
} }
@implementation ViewController : UIViewController @implementation ViewController : UIViewController

View File

@@ -7,6 +7,6 @@
<key>com.apple.developer.team-identifier</key> <key>com.apple.developer.team-identifier</key>
<string>EDVXQ27EB5</string> <string>EDVXQ27EB5</string>
<key>get-task-allow</key> <key>get-task-allow</key>
<true/> <false/>
</dict> </dict>
</plist> </plist>

View File

@@ -2,34 +2,86 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleName</key> <key>CFBundleDisplayName</key>
<string>tildefriends</string> <string>Tilde Friends</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>tildefriends</string> <string>tildefriends</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>com.unprompted.tildefriends</string> <string>com.unprompted.tildefriends</string>
<key>CFBundleResourceSpecification</key> <key>CFBundleName</key>
<string>ResourceRules.plist</string> <string>tildefriends</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.28</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>8</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>CFBundleDisplayName</key> <key>MinimumOSVersion</key>
<string>Tilde Friends</string> <string>14.0</string>
<key>CFBundleVersion</key> <key>UIDeviceFamily</key>
<string>1.0</string> <array>
<key>CFBundleShortVersionString</key> <integer>1</integer>
<string>1.0</string> <integer>2</integer>
<key>CFBundleIconName</key> </array>
<string>AppIcon</string>
<key>CFBundleIconFile</key>
<string>tildefriends.png</string>
<key>UILaunchScreen</key> <key>UILaunchScreen</key>
<dict> <dict>
<key>UIImageName</key> <key>UIImageName</key>
<string>tildefriends.png</string> <string>tildefriends.png</string>
</dict> </dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>BuildMachineOSBuild</key>
<string>24D70</string>
<key>DTPlatformBuild</key>
<string>22C146</string>
<key>DTPlatformVersion</key>
<string>18.2</string>
<key>DTSDKBuild</key>
<string>22C146</string>
<key>DTSDKName</key>
<string>iphoneos18.2</string>
<key>DTXcode</key>
<string>1620</string>
<key>DTXcodeBuild</key>
<string>16C5032a</string>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~iphone</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon60x60</string>
</array>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict> </dict>
</plist> </plist>

Binary file not shown.

BIN
src/ios/icons/Assets.car Normal file

Binary file not shown.

View File

@@ -0,0 +1 @@
{"images":[{"idiom":"ios-marketing","scale":"1x","size":"1024x1024","filename":"icon-ios-marketing-1-1024-1024.png"}],"info":{"author":"xcode","version":1}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@@ -0,0 +1 @@
{"info": {"version": 1, "author": "xcode"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/ios/icons/ios/100.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
src/ios/icons/ios/114.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
src/ios/icons/ios/128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
src/ios/icons/ios/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

BIN
src/ios/icons/ios/172.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/ios/icons/ios/180.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/ios/icons/ios/196.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/ios/icons/ios/216.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/ios/icons/ios/256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/ios/icons/ios/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/ios/icons/ios/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
src/ios/icons/ios/50.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src/ios/icons/ios/512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
src/ios/icons/ios/55.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/ios/icons/ios/64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
src/ios/icons/ios/88.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
src/ios/icons/ios/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
src/ios/icons/uploaded.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@@ -1217,9 +1217,6 @@ typedef struct tf_run_args_t
{ {
const char* script; const char* script;
const char* network_key; const char* network_key;
int ssb_port;
int http_port;
int https_port;
const char* db_path; const char* db_path;
int count; int count;
const char* args; const char* args;
@@ -1244,9 +1241,6 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
tf_printf("setting zip path to %s\n", args->zip); tf_printf("setting zip path to %s\n", args->zip);
tf_task_set_zip_path(task, args->zip); tf_task_set_zip_path(task, args->zip);
tf_task_set_ssb_network_key(task, args->network_key); tf_task_set_ssb_network_key(task, args->network_key);
tf_task_set_ssb_port(task, args->ssb_port ? args->ssb_port + index : 0);
tf_task_set_http_port(task, args->http_port ? args->http_port + index : 0);
tf_task_set_https_port(task, args->https_port ? args->https_port + index : 0);
tf_task_set_args(task, args->args); tf_task_set_args(task, args->args);
tf_task_set_one_proc(task, args->one_proc); tf_task_set_one_proc(task, args->one_proc);
const char* db_path = args->db_path; const char* db_path = args->db_path;
@@ -1301,7 +1295,14 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
tf_task_activate(task); tf_task_activate(task);
tf_ssb_set_verbose(tf_task_get_ssb(task), args->verbose); tf_ssb_set_verbose(tf_task_get_ssb(task), args->verbose);
tf_ssb_start_periodic(tf_task_get_ssb(task)); tf_ssb_start_periodic(tf_task_get_ssb(task));
if (args->http_port || args->https_port) tf_ssb_t* ssb = tf_task_get_ssb(task);
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
int64_t http_port = 0;
int64_t https_port = 0;
tf_ssb_db_get_global_setting_int64(db, "http_port", &http_port);
tf_ssb_db_get_global_setting_int64(db, "https_port", &https_port);
tf_ssb_release_db_reader(ssb, db);
if (http_port || https_port)
{ {
if (args->zip) if (args->zip)
{ {
@@ -1417,9 +1418,6 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
const char* default_db_path = _get_db_path(); const char* default_db_path = _get_db_path();
tf_run_args_t args = { tf_run_args_t args = {
.count = 1, .count = 1,
.http_port = 12345,
.https_port = 12346,
.ssb_port = 8008,
.db_path = default_db_path, .db_path = default_db_path,
}; };
bool show_usage = false; bool show_usage = false;
@@ -1436,10 +1434,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
{ {
static const struct option k_options[] = { static const struct option k_options[] = {
{ "script", required_argument, NULL, 's' }, { "script", required_argument, NULL, 's' },
{ "ssb-port", required_argument, NULL, 'b' },
{ "ssb-network-key", required_argument, NULL, 'k' }, { "ssb-network-key", required_argument, NULL, 'k' },
{ "http-port", required_argument, NULL, 'p' },
{ "https-port", required_argument, NULL, 'q' },
{ "db-path", required_argument, NULL, 'd' }, { "db-path", required_argument, NULL, 'd' },
{ "count", required_argument, NULL, 'n' }, { "count", required_argument, NULL, 'n' },
{ "args", required_argument, NULL, 'a' }, { "args", required_argument, NULL, 'a' },
@@ -1448,7 +1443,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
{ "verbose", no_argument, NULL, 'v' }, { "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
}; };
int c = getopt_long(argc, argv, "s:b:k:p:q:d:n:a:oz:vh", k_options, NULL); int c = getopt_long(argc, argv, "s:k:d:n:a:oz:vh", k_options, NULL);
if (c == -1) if (c == -1)
{ {
break; break;
@@ -1467,15 +1462,6 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
case 'k': case 'k':
args.network_key = optarg; args.network_key = optarg;
break; break;
case 'b':
args.ssb_port = atoi(optarg);
break;
case 'p':
args.http_port = atoi(optarg);
break;
case 'q':
args.https_port = atoi(optarg);
break;
case 'd': case 'd':
args.db_path = optarg; args.db_path = optarg;
break; break;
@@ -1502,13 +1488,11 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_printf("\n%s run [options]\n\n", file); tf_printf("\n%s run [options]\n\n", file);
tf_printf("options\n"); tf_printf("options\n");
tf_printf(" -s, --script script Script to run (default: core/core.js).\n"); tf_printf(" -s, --script script Script to run (default: core/core.js).\n");
tf_printf(" -b, --ssb-port port Port on which to run SSB (default: 8008, 0 disables).\n");
tf_printf(" -p, --http-port port Port on which to run Tilde Friends web server (default: 12345).\n");
tf_printf(" -q, --https-port port Port on which to run secure Tilde Friends web server (default: 12346).\n");
tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", default_db_path); tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -k, --ssb-network-key key SSB network key to use.\n"); tf_printf(" -k, --ssb-network-key key SSB network key to use.\n");
tf_printf(" -n, --count count Number of instances to run.\n"); tf_printf(" -n, --count count Number of instances to run.\n");
tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true.\n"); tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true (note: these are persisted to the database).\n");
tf_util_document_settings(" ");
tf_printf(" -o, --one-proc Run everything in one process (unsafely!).\n"); tf_printf(" -o, --one-proc Run everything in one process (unsafely!).\n");
tf_printf(" -z, --zip path Zip archive from which to load files.\n"); tf_printf(" -z, --zip path Zip archive from which to load files.\n");
tf_printf(" -v, --verbose Log raw messages.\n"); tf_printf(" -v, --verbose Log raw messages.\n");
@@ -1744,18 +1728,15 @@ static jint _tf_server_main(JNIEnv* env, jobject this_object, jstring files_dir,
tf_printf("uv_chdir: %s\n", uv_strerror(result)); tf_printf("uv_chdir: %s\n", uv_strerror(result));
} }
size_t port_file_arg_length = strlen(out_port_file) + strlen("out_http_port_file=") + 1; size_t args_length = strlen(out_port_file) + strlen("--args=http_port=0,out_http_port_file=") + 1;
char* port_file_arg = alloca(port_file_arg_length); char* args_buffer = alloca(args_length);
snprintf(port_file_arg, port_file_arg_length, "out_http_port_file=%s", out_port_file); snprintf(args_buffer, args_length, "--args=http_port=0,out_http_port_file=%s", out_port_file);
const char* args[] = { const char* args[] = {
"run", "run",
"-z", "-z",
apk, apk,
"-a", args_buffer,
port_file_arg,
"-p",
"0",
}; };
tf_task_set_android_service_callbacks(_tf_service_start, _tf_service_stop); tf_task_set_android_service_callbacks(_tf_service_start, _tf_service_stop);
@@ -1847,9 +1828,6 @@ void tf_run_thread_start(const char* zip_path)
tf_run_thread_data_t* data = tf_malloc(sizeof(tf_run_thread_data_t)); tf_run_thread_data_t* data = tf_malloc(sizeof(tf_run_thread_data_t));
tf_run_args_t args = { tf_run_args_t args = {
.count = 1, .count = 1,
.http_port = 12345,
.https_port = 12346,
.ssb_port = 8008,
.db_path = "db.sqlite", .db_path = "db.sqlite",
.one_proc = true, .one_proc = true,
.zip = zip_path, .zip = zip_path,

View File

@@ -2126,6 +2126,51 @@ bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* ou
return result; return result;
} }
bool tf_ssb_db_set_global_setting_from_string(sqlite3* db, const char* name, char* value)
{
tf_setting_kind_t kind = tf_util_get_global_setting_kind(name);
if (kind == k_kind_unknown)
{
return false;
}
bool result = false;
sqlite3_stmt* statement;
if (sqlite3_prepare(db,
"INSERT INTO properties (id, key, value) VALUES ('core', 'settings', json_object(?1, ?2)) ON CONFLICT DO UPDATE SET value = json_set(value, '$.' || ?1, ?2)", -1,
&statement, NULL) == SQLITE_OK)
{
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
{
bool bound = false;
switch (kind)
{
case k_kind_bool:
bound = sqlite3_bind_int(statement, 2, value && (strcmp(value, "true") == 0 || atoi(value))) == SQLITE_OK;
break;
case k_kind_int:
bound = sqlite3_bind_int(statement, 2, atoi(value)) == SQLITE_OK;
break;
case k_kind_string:
bound = sqlite3_bind_text(statement, 2, value, -1, NULL) == SQLITE_OK;
break;
case k_kind_unknown:
break;
}
if (bound && sqlite3_step(statement) == SQLITE_DONE)
{
result = sqlite3_changes(db) != 0;
}
}
sqlite3_finalize(statement);
}
else
{
tf_printf("prepare failed: %s\n", sqlite3_errmsg(db));
}
return result;
}
const char* tf_ssb_db_get_profile(sqlite3* db, const char* id) const char* tf_ssb_db_get_profile(sqlite3* db, const char* id)
{ {
const char* result = NULL; const char* result = NULL;

View File

@@ -486,6 +486,15 @@ bool tf_ssb_db_get_global_setting_int64(sqlite3* db, const char* name, int64_t*
*/ */
bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size); bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size);
/**
** Set a global setting from a string representation of its value.
** @param db The database.
** @param name The setting name.
** @param value The settinv value.
** @return true if the setting was set.
*/
bool tf_ssb_db_set_global_setting_from_string(sqlite3* db, const char* name, char* value);
/** /**
** Get the latest profile information for the given identity. ** Get the latest profile information for the given identity.
** @param db The database. ** @param db The database.

View File

@@ -2357,6 +2357,12 @@ static JSValue _tf_ssb_set_user_permission(JSContext* context, JSValueConst this
return result; return result;
} }
static JSValue _tf_ssb_port(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
return JS_NewInt32(context, tf_ssb_server_get_port(ssb));
}
void tf_ssb_register(JSContext* context, tf_ssb_t* ssb) void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
{ {
JS_NewClassID(&_tf_ssb_classId); JS_NewClassID(&_tf_ssb_classId);
@@ -2403,6 +2409,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
JS_SetPropertyStr(context, object, "createTunnel", JS_NewCFunction(context, _tf_ssb_createTunnel, "createTunnel", 3)); JS_SetPropertyStr(context, object, "createTunnel", JS_NewCFunction(context, _tf_ssb_createTunnel, "createTunnel", 3));
JS_SetPropertyStr(context, object, "following", JS_NewCFunction(context, _tf_ssb_following, "following", 2)); JS_SetPropertyStr(context, object, "following", JS_NewCFunction(context, _tf_ssb_following, "following", 2));
JS_SetPropertyStr(context, object, "sync", JS_NewCFunction(context, _tf_ssb_sync, "sync", 0)); JS_SetPropertyStr(context, object, "sync", JS_NewCFunction(context, _tf_ssb_sync, "sync", 0));
JS_SetPropertyStr(context, object, "port", JS_NewCFunction(context, _tf_ssb_port, "port", 0));
/* Write. */ /* Write. */
JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1)); JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1));
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 1)); JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 1));

View File

@@ -913,7 +913,7 @@ static void _write_file(const char* path, const char* contents)
fclose(file); fclose(file);
} }
#define TEST_ARGS " --ssb-port=0 --http-port=0 --https-port=0" #define TEST_ARGS " --args=ssb_port=0,http_port=0,https_port=0"
void tf_ssb_test_encrypt(const tf_test_options_t* options) void tf_ssb_test_encrypt(const tf_test_options_t* options)
{ {

View File

@@ -9,6 +9,7 @@
#include "packetstream.h" #include "packetstream.h"
#include "serialize.h" #include "serialize.h"
#include "socket.js.h" #include "socket.js.h"
#include "ssb.db.h"
#include "ssb.h" #include "ssb.h"
#include "ssb.js.h" #include "ssb.js.h"
#include "taskstub.js.h" #include "taskstub.js.h"
@@ -154,9 +155,6 @@ typedef struct _tf_task_t
JSValue _loadedFiles; JSValue _loadedFiles;
const char* _network_key; const char* _network_key;
int _ssb_port;
int _http_port;
int _https_port;
char _db_path[256]; char _db_path[256];
char _zip_path[256]; char _zip_path[256];
char _root_path[256]; char _root_path[256];
@@ -398,6 +396,7 @@ static JSValue _tf_task_exit(JSContext* context, JSValueConst this_val, int argc
int exitCode = 0; int exitCode = 0;
JS_ToInt32(task->_context, &exitCode, argv[0]); JS_ToInt32(task->_context, &exitCode, argv[0]);
tf_trace_end(task->_trace); tf_trace_end(task->_trace);
tf_printf("EXIT %d\n", exitCode);
exit(exitCode); exit(exitCode);
return JS_UNDEFINED; return JS_UNDEFINED;
} }
@@ -1680,38 +1679,6 @@ void tf_task_activate(tf_task_t* task)
JS_DefinePropertyGetSet(context, global, atom, JS_NewCFunction(context, _tf_task_get_parent, "parent", 0), JS_UNDEFINED, 0); JS_DefinePropertyGetSet(context, global, atom, JS_NewCFunction(context, _tf_task_get_parent, "parent", 0), JS_UNDEFINED, 0);
JS_FreeAtom(context, atom); JS_FreeAtom(context, atom);
JSValue tildefriends = JS_NewObject(context);
JSValue args = JS_NewObject(context);
JS_SetPropertyStr(context, tildefriends, "args", args);
if (task->_args)
{
char* saveptr = NULL;
char* copy = tf_strdup(task->_args);
char* start = copy;
while (true)
{
char* assignment = strtok_r(start, ",", &saveptr);
start = NULL;
if (!assignment)
{
break;
}
char* equals = strchr(assignment, '=');
if (equals)
{
*equals = '\0';
JS_SetPropertyStr(context, args, assignment, JS_NewString(context, equals + 1));
}
else
{
tf_printf("Assignment missing '=': %s.\n", assignment);
exit(1);
}
}
tf_free(copy);
}
JS_SetPropertyStr(context, global, "tildefriends", tildefriends);
task->_trace = tf_trace_create(); task->_trace = tf_trace_create();
if (task->_trusted) if (task->_trusted)
{ {
@@ -1732,23 +1699,45 @@ void tf_task_activate(tf_task_t* task)
tf_ssb_register(context, task->_ssb); tf_ssb_register(context, task->_ssb);
tf_ssb_set_hitch_callback(task->_ssb, _tf_task_record_hitch, task); tf_ssb_set_hitch_callback(task->_ssb, _tf_task_record_hitch, task);
int actual_ssb_port = task->_ssb_port; if (task->_args)
{
sqlite3* db = tf_ssb_acquire_db_writer(task->_ssb);
char* saveptr = NULL;
char* copy = tf_strdup(task->_args);
char* start = copy;
while (true)
{
char* assignment = strtok_r(start, ",", &saveptr);
start = NULL;
if (!assignment)
{
break;
}
char* equals = strchr(assignment, '=');
if (equals)
{
*equals = '\0';
tf_ssb_db_set_global_setting_from_string(db, assignment, equals + 1);
}
else
{
tf_printf("Assignment missing '=': %s.\n", assignment);
exit(1);
}
}
tf_free(copy);
tf_ssb_release_db_writer(task->_ssb, db);
}
if (task->_ssb_port) int64_t ssb_port = 0;
sqlite3* db = tf_ssb_acquire_db_reader(task->_ssb);
tf_ssb_db_get_global_setting_int64(db, "ssb_port", &ssb_port);
tf_ssb_release_db_reader(task->_ssb, db);
if (ssb_port)
{ {
tf_ssb_broadcast_listener_start(task->_ssb, false); tf_ssb_broadcast_listener_start(task->_ssb, false);
tf_ssb_broadcast_sender_start(task->_ssb); tf_ssb_broadcast_sender_start(task->_ssb);
actual_ssb_port = tf_ssb_server_open(task->_ssb, task->_ssb_port); tf_ssb_server_open(task->_ssb, ssb_port);
}
JS_SetPropertyStr(context, tildefriends, "ssb_port", JS_NewInt32(context, actual_ssb_port));
if (task->_http_port)
{
JS_SetPropertyStr(context, tildefriends, "http_port", JS_NewInt32(context, task->_http_port));
}
if (task->_https_port)
{
JS_SetPropertyStr(context, tildefriends, "https_port", JS_NewInt32(context, task->_https_port));
} }
JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0)); JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0));
@@ -1999,21 +1988,6 @@ void tf_task_set_ssb_network_key(tf_task_t* task, const char* network_key)
task->_network_key = network_key; task->_network_key = network_key;
} }
void tf_task_set_ssb_port(tf_task_t* task, int port)
{
task->_ssb_port = port;
}
void tf_task_set_http_port(tf_task_t* task, int port)
{
task->_http_port = port;
}
void tf_task_set_https_port(tf_task_t* task, int port)
{
task->_https_port = port;
}
void tf_task_set_db_path(tf_task_t* task, const char* db_path) void tf_task_set_db_path(tf_task_t* task, const char* db_path)
{ {
snprintf(task->_db_path, sizeof(task->_db_path), "%s", db_path); snprintf(task->_db_path, sizeof(task->_db_path), "%s", db_path);

View File

@@ -76,27 +76,6 @@ void tf_task_configure_from_fd(tf_task_t* task, int fd);
*/ */
void tf_task_set_ssb_network_key(tf_task_t* task, const char* network_key); void tf_task_set_ssb_network_key(tf_task_t* task, const char* network_key);
/**
** Set the port number on which to run an SSB secure handshake server.
** @param task The task.
** @param port The port number or 0 to disable.
*/
void tf_task_set_ssb_port(tf_task_t* task, int port);
/**
** Set the port number on which to run an HTTP server.
** @param task The task.
** @param port The port number of 0 to disable.
*/
void tf_task_set_http_port(tf_task_t* task, int port);
/**
** Set the port number on which to run an HTTPS server.
** @param task The task.
** @param port The port number of 0 to disable.
*/
void tf_task_set_https_port(tf_task_t* task, int port);
/** /**
** Set the path to the SQLite database. ** Set the path to the SQLite database.
** @param task The task. ** @param task The task.

View File

@@ -32,7 +32,7 @@
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#define TEST_ARGS " --ssb-port=0 --http-port=0 --https-port=0" #define TEST_ARGS " --args=ssb_port=0,http_port=0,https_port=0"
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
static void _write_file(const char* path, const char* contents) static void _write_file(const char* path, const char* contents)
@@ -311,7 +311,7 @@ static void _test_database(const tf_test_options_t* options)
" print('Expected but did not find: ' + JSON.stringify(expected));\n" " print('Expected but did not find: ' + JSON.stringify(expected));\n"
" exit(4);\n" " exit(4);\n"
" }\n" " }\n"
" if (JSON.stringify(await databases.list('%')) != '[\"testdb\"]') {\n" " if (JSON.stringify(await databases.list('%')) != '[\"core\",\"testdb\"]') {\n"
" exit(7);\n" " exit(7);\n"
" }\n" " }\n"
"}\n" "}\n"
@@ -864,9 +864,6 @@ static void _test_httpd(const tf_test_options_t* options)
uv_loop_init(&loop); uv_loop_init(&loop);
unlink("out/test_db0.sqlite"); unlink("out/test_db0.sqlite");
char command[256];
snprintf(command, sizeof(command), "%s run -b 0 --db-path=out/test_db0.sqlite" TEST_ARGS, options->exe_path);
uv_stdio_container_t stdio[] = { uv_stdio_container_t stdio[] = {
[STDIN_FILENO] = { .flags = UV_IGNORE }, [STDIN_FILENO] = { .flags = UV_IGNORE },
[STDOUT_FILENO] = { .flags = UV_INHERIT_FD }, [STDOUT_FILENO] = { .flags = UV_INHERIT_FD },
@@ -876,7 +873,7 @@ static void _test_httpd(const tf_test_options_t* options)
uv_spawn(&loop, &process, uv_spawn(&loop, &process,
&(uv_process_options_t) { &(uv_process_options_t) {
.file = options->exe_path, .file = options->exe_path,
.args = (char*[]) { (char*)options->exe_path, "run", "-b0", "--db-path=out/test_db0.sqlite", "--http-port=8080", "--https-port=0", NULL }, .args = (char*[]) { (char*)options->exe_path, "run", "--db-path=out/test_db0.sqlite", "--args=ssb_port=0,http_port=8080,https_port=0", NULL },
.stdio_count = sizeof(stdio) / sizeof(*stdio), .stdio_count = sizeof(stdio) / sizeof(*stdio),
.stdio = stdio, .stdio = stdio,
}); });
@@ -960,7 +957,7 @@ static void _test_auto(const tf_test_options_t* options)
unlink("out/selenium.sqlite-shm"); unlink("out/selenium.sqlite-shm");
unlink("out/selenium.sqlite-wal"); unlink("out/selenium.sqlite-wal");
char* args[] = { executable, "run", "-d", "out/selenium.sqlite", "-b", "0", "-p", "8888", NULL }; char* args[] = { executable, "run", "-d", "out/selenium.sqlite", "-a", "ssb_port=0,http_port=8888", NULL };
uv_stdio_container_t io[3] = { uv_stdio_container_t io[3] = {
{ .flags = UV_INHERIT_FD }, { .flags = UV_INHERIT_FD },

View File

@@ -314,13 +314,6 @@ static JSValue _util_parseHttpResponse(JSContext* context, JSValueConst this_val
return result; return result;
} }
typedef enum _value_kind_t
{
k_kind_bool,
k_kind_int,
k_kind_string,
} value_kind_t;
static const char* k_kind_name[] = { static const char* k_kind_name[] = {
[k_kind_bool] = "bool", [k_kind_bool] = "bool",
[k_kind_int] = "int", [k_kind_int] = "int",
@@ -329,7 +322,7 @@ static const char* k_kind_name[] = {
typedef struct _setting_value_t typedef struct _setting_value_t
{ {
value_kind_t kind; tf_setting_kind_t kind;
union union
{ {
bool bool_value; bool bool_value;
@@ -348,6 +341,13 @@ typedef struct _setting_t
static const setting_t k_settings[] = { static const setting_t k_settings[] = {
{ .name = "code_of_conduct", .type = "textarea", .description = "Code of conduct presented at sign-in.", .default_value = { .kind = k_kind_string, .string_value = NULL } }, { .name = "code_of_conduct", .type = "textarea", .description = "Code of conduct presented at sign-in.", .default_value = { .kind = k_kind_string, .string_value = NULL } },
{ .name = "ssb_port",
.type = "integer",
.description = "Port on which to listen for SSB secure handshake connections.",
.default_value = { .kind = k_kind_int, .int_value = 8008 } },
{ .name = "http_port", .type = "integer", .description = "Port on which to listen for HTTP connections.", .default_value = { .kind = k_kind_int, .int_value = 12345 } },
{ .name = "https_port", .type = "integer", .description = "Port on which to listen for secure HTTP connections.", .default_value = { .kind = k_kind_int, .int_value = 0 } },
{ .name = "out_http_port_file", .type = "hidden", .description = "File to which to write bound HTTP port.", .default_value = { .kind = k_kind_string, .string_value = NULL } },
{ .name = "blob_fetch_age_seconds", { .name = "blob_fetch_age_seconds",
.type = "integer", .type = "integer",
.description = "Only blobs mentioned more recently than this age will be automatically fetched.", .description = "Only blobs mentioned more recently than this age will be automatically fetched.",
@@ -393,21 +393,31 @@ static const setting_t k_settings[] = {
.type = "boolean", .type = "boolean",
.description = "Whether connections are accepted from accounts that aren't in the replication range or otherwise already known.", .description = "Whether connections are accepted from accounts that aren't in the replication range or otherwise already known.",
.default_value = { .kind = k_kind_bool, .bool_value = true } }, .default_value = { .kind = k_kind_bool, .bool_value = true } },
{ .name = "autologin", .type = "boolean", .description = "Whether mobile autologin is supported.", .default_value = { .kind = k_kind_bool, .bool_value = TF_IS_MOBILE != 0 } },
}; };
static const setting_t* _util_get_setting(const char* name, value_kind_t kind) static const setting_t* _util_get_setting(const char* name, tf_setting_kind_t kind)
{ {
for (int i = 0; i < tf_countof(k_settings); i++) for (int i = 0; i < tf_countof(k_settings); i++)
{ {
if (strcmp(k_settings[i].name, name) == 0 && k_settings[i].default_value.kind == kind) if (strcmp(k_settings[i].name, name) == 0 && (kind == k_kind_unknown || k_settings[i].default_value.kind == kind))
{ {
return &k_settings[i]; return &k_settings[i];
} }
} }
if (kind != k_kind_unknown)
{
tf_printf("Did not find global setting of type %s: %s.\n", k_kind_name[kind], name); tf_printf("Did not find global setting of type %s: %s.\n", k_kind_name[kind], name);
}
return NULL; return NULL;
} }
tf_setting_kind_t tf_util_get_global_setting_kind(const char* name)
{
const setting_t* setting = _util_get_setting(name, k_kind_unknown);
return setting ? setting->default_value.kind : k_kind_unknown;
}
bool tf_util_get_default_global_setting_bool(const char* name) bool tf_util_get_default_global_setting_bool(const char* name)
{ {
const setting_t* setting = _util_get_setting(name, k_kind_bool); const setting_t* setting = _util_get_setting(name, k_kind_bool);
@@ -446,12 +456,41 @@ static JSValue _util_defaultGlobalSettings(JSContext* context, JSValueConst this
JS_SetPropertyStr( JS_SetPropertyStr(
context, entry, "default_value", k_settings[i].default_value.string_value ? JS_NewString(context, k_settings[i].default_value.string_value) : JS_UNDEFINED); context, entry, "default_value", k_settings[i].default_value.string_value ? JS_NewString(context, k_settings[i].default_value.string_value) : JS_UNDEFINED);
break; break;
case k_kind_unknown:
break;
} }
JS_SetPropertyStr(context, settings, k_settings[i].name, entry); JS_SetPropertyStr(context, settings, k_settings[i].name, entry);
} }
return settings; return settings;
} }
void tf_util_document_settings(const char* line_prefix)
{
char buffer[32];
for (int i = 0; i < tf_countof(k_settings); i++)
{
const char* default_value = NULL;
const char* quote = "";
switch (k_settings[i].default_value.kind)
{
case k_kind_bool:
default_value = k_settings[i].default_value.bool_value ? "true" : "false";
break;
case k_kind_string:
quote = "\"";
default_value = k_settings[i].default_value.string_value ? k_settings[i].default_value.string_value : "";
break;
case k_kind_int:
snprintf(buffer, sizeof(buffer), "%d", k_settings[i].default_value.int_value);
default_value = buffer;
break;
case k_kind_unknown:
break;
}
tf_printf("%s%s (default: %s%s%s): %s\n", line_prefix, k_settings[i].name, quote, default_value, quote, k_settings[i].description);
}
}
JSValue tf_util_new_uint8_array(JSContext* context, const uint8_t* data, size_t size) JSValue tf_util_new_uint8_array(JSContext* context, const uint8_t* data, size_t size)
{ {
JSValue array_buffer = JS_NewArrayBufferCopy(context, data, size); JSValue array_buffer = JS_NewArrayBufferCopy(context, data, size);

View File

@@ -10,6 +10,17 @@
#include <stdbool.h> #include <stdbool.h>
/**
** Type of a setting.
*/
typedef enum _tf_setting_kind_t
{
k_kind_unknown,
k_kind_bool,
k_kind_int,
k_kind_string,
} tf_setting_kind_t;
/** An event loop. */ /** An event loop. */
typedef struct uv_loop_s uv_loop_t; typedef struct uv_loop_s uv_loop_t;
@@ -194,6 +205,19 @@ int tf_util_get_default_global_setting_int(const char* name);
*/ */
const char* tf_util_get_default_global_setting_string(const char* name); const char* tf_util_get_default_global_setting_string(const char* name);
/**
** Get the expected kind of a global setting.
** @param name The setting name.
** @return The setting kind or unknown if nonexistent.
*/
tf_setting_kind_t tf_util_get_global_setting_kind(const char* name);
/**
** Log documentation for the available settings.
** @param line_prefix Text to prefix each line with."
*/
void tf_util_document_settings(const char* line_prefix);
/** /**
** Check if the app is running on a mobile device. ** Check if the app is running on a mobile device.
** @return true for iPhone/Android, false otherwise. ** @return true for iPhone/Android, false otherwise.

14
tools/ios-distribute Normal file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash -e
rm -rfv out/tildefriends-iosrelease.app out/Payload out/tildefriends.ipa
make iosrelease-app
cp src/ios/tildefriends.png out/tildefriends-iosrelease.app/tildefriends.png
cp src/ios/icons/Assets.car out/tildefriends-iosrelease.app/
cp src/ios/icons/ios/icon-72.png out/tildefriends-iosrelease.app/
cp src/ios/icons/ios/icon-120.png out/tildefriends-iosrelease.app/
cp src/ios/icons/ios/icon-152.png out/tildefriends-iosrelease.app/
cp src/ios/distribution.mobileprovision out/tildefriends-iosrelease.app/embedded.mobileprovision
xcrun -sdk iphoneos codesign -f -s 'Apple Distribution: Cory McWilliams' --entitlements src/ios/Entitlements.plist --generate-entitlement-der out/tildefriends-iosrelease.app
mkdir -p out/Payload/tildefriends.app
cp -avR out/tildefriends-iosrelease.app/* out/Payload/tildefriends.app/
cd out; zip -r tildefriends.ipa Payload; cd ..
xcrun -sdk iphoneos altool --upload-app -f out/tildefriends.ipa -t ios -u $(cat .keys/altool-user) -p $(cat .keys/altool-password)