Skip to content

Commit 8108ab5

Browse files
committed
first commit
0 parents  commit 8108ab5

12 files changed

Lines changed: 313 additions & 0 deletions

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# https://dart.dev/guides/libraries/private-files
2+
# Created by `dart pub`
3+
.dart_tool/
4+
5+
# Avoid committing pubspec.lock for library packages; see
6+
# https://dart.dev/guides/libraries/private-files#pubspeclock.
7+
pubspec.lock

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0
2+
3+
- Initial version.

LICENSE

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Copyright 2024 Yudha Virma Allasca
2+
3+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4+
5+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6+
7+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8+
9+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10+
11+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# GithubStorage
2+
3+
This package provides a convenient way to persist key-value pairs directly within your GitHub repository. Using implementation of (https://pub.dev/packages/github) Thanks to (https://github.com/SpinlockLabs)
4+
5+
## Features
6+
7+
- Secure Storage: Leverages GitHub's secrets management for secure storage of your data, use private repository.
8+
- Easy to Use: Simple API for storing and retrieving data.
9+
- Integrated with Dart: Works seamlessly within your Dart projects.
10+
11+
## Getting started
12+
13+
```yaml
14+
dependencies:
15+
github_storage: ^any
16+
```
17+
18+
## Usage
19+
20+
Register your github account
21+
```dart
22+
final git = GithubStorage(
23+
username: "this is yours",
24+
personalAccessToken: "yout token",
25+
repository: "your repo");
26+
```
27+
Create file and folder first if does not exist yet in your repo
28+
```dart
29+
await git.createBox(name: "user", folder: "data");
30+
```
31+
Create object of GithubBox
32+
```dart
33+
GithubBox userBox = git.box(name: "user", folder: "data");
34+
```
35+
Save, get, delete
36+
```dart
37+
await userBox.put("isDarkTheme", true);
38+
await userBox.remove("user");
39+
bool isDark = await userBox.get("isDark");
40+
```
41+
Or save an object
42+
```dart
43+
Map user = {
44+
"user": "jack",
45+
"no": 10,
46+
"color": [
47+
"red",
48+
"blue",
49+
],
50+
"planet": {"earth": "moon"}
51+
};
52+
53+
await userBox.put("jack", user);
54+
```
55+
56+
##
57+
58+
Note: This description emphasizes security and ease of use. Remember to replace "Secure Storage" with the specific mechanism your package uses (e.g., encrypted files) if it's different from GitHub secrets.

analysis_options.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file configures the static analysis results for your project (errors,
2+
# warnings, and lints).
3+
#
4+
# This enables the 'recommended' set of lints from `package:lints`.
5+
# This set helps identify many issues that may lead to problems when running
6+
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
7+
# style and format.
8+
#
9+
# If you want a smaller set of lints you can change this to specify
10+
# 'package:lints/core.yaml'. These are just the most critical lints
11+
# (the recommended set includes the core lints).
12+
# The core lints are also what is used by pub.dev for scoring packages.
13+
14+
include: package:lints/recommended.yaml
15+
16+
# Uncomment the following section to specify additional rules.
17+
18+
# linter:
19+
# rules:
20+
# - camel_case_types
21+
22+
# analyzer:
23+
# exclude:
24+
# - path/to/excluded/files/**
25+
26+
# For more information about the core and recommended set of lints, see
27+
# https://dart.dev/go/core-lints
28+
29+
# For additional information about configuring this file, see
30+
# https://dart.dev/guides/language/analysis-options
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:github_storage/github_storage.dart';
2+
import 'package:github_storage/src/github_box.dart';
3+
4+
void main() async {
5+
final git = GithubStorage(
6+
username: "this is yours",
7+
personalAccessToken: "yout token",
8+
repository: "your repo");
9+
10+
/// Create if not exist yet on repo
11+
await git.createBox(name: "user", folder: "data");
12+
13+
/// Create object of GithubBox
14+
GithubBox userBox = git.box(name: "user", folder: "data");
15+
GithubBox settingBox = git.box(name: "setting", folder: "setting");
16+
17+
await userBox.put("flutter", {"version": 1, "isDart": true});
18+
await settingBox.put("isDarkTheme", true);
19+
20+
bool isDark = await settingBox.get("isDark");
21+
print(isDark);
22+
23+
await userBox.remove("jack");
24+
Map setting = await settingBox.getRawData();
25+
print(setting.toString());
26+
27+
Map user = {
28+
"user": "jack",
29+
"no": 10,
30+
"color": [
31+
"red",
32+
"blue",
33+
],
34+
"planet": {"earth": "moon"}
35+
};
36+
37+
await settingBox.put("jack", user);
38+
}

lib/github_storage.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// Support for doing something awesome.
2+
///
3+
/// More dartdocs go here.
4+
library;
5+
6+
export 'src/github_storage_base.dart';
7+
8+
// TODO: Export any libraries intended for clients of this package.

lib/src/github_box.dart

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import 'dart:convert';
2+
import 'package:github/github.dart';
3+
import 'helper.dart';
4+
5+
class GithubBox {
6+
final String name;
7+
final String _username;
8+
final String _personalAccessToken;
9+
final String _repository;
10+
final String _folder;
11+
12+
GithubBox(
13+
this._username,
14+
this._personalAccessToken,
15+
this._repository,
16+
this._folder, {
17+
required this.name,
18+
});
19+
20+
/// Example put("user", "flutter")
21+
/// or
22+
/// put("user": {"user: "flutter", "isDart": true})
23+
Future<void> put(String key, dynamic value) async {
24+
final box = await GitHub(
25+
auth: Authentication.withToken(_personalAccessToken))
26+
.repositories
27+
.getContents(RepositorySlug(_username, _repository), "$_folder/$name");
28+
Map<String, dynamic> content = json.decode(box.file!.text);
29+
content.addAll({key: value});
30+
await GitHub(auth: Authentication.withToken(_personalAccessToken))
31+
.repositories
32+
.updateFile(RepositorySlug(_username, _repository), "$_folder/$name",
33+
"Modified key: $key", prettyByte(content), box.file!.sha!,
34+
branch: "main");
35+
}
36+
37+
/// Return single value of key
38+
Future<dynamic> get(String key) async {
39+
final box = await GitHub(
40+
auth: Authentication.withToken(_personalAccessToken))
41+
.repositories
42+
.getContents(RepositorySlug(_username, _repository), "$_folder/$name");
43+
Map<String, dynamic> content = json.decode(box.file!.text);
44+
return content[key];
45+
}
46+
47+
/// Return Map of all box/file
48+
Future<Map<String, dynamic>> getRawData() async {
49+
final box = await GitHub(
50+
auth: Authentication.withToken(_personalAccessToken))
51+
.repositories
52+
.getContents(RepositorySlug(_username, _repository), "$_folder/$name");
53+
return json.decode(box.file!.text);
54+
}
55+
56+
/// Delete key
57+
Future<void> remove(String key) async {
58+
final box = await GitHub(
59+
auth: Authentication.withToken(_personalAccessToken))
60+
.repositories
61+
.getContents(RepositorySlug(_username, _repository), "$_folder/$name");
62+
Map<String, dynamic> content = json.decode(box.file!.text);
63+
content.remove(key);
64+
await GitHub(auth: Authentication.withToken(_personalAccessToken))
65+
.repositories
66+
.updateFile(RepositorySlug(_username, _repository), "$_folder/$name",
67+
"Modified key: $key", prettyByte(content), box.file!.sha!,
68+
branch: "main");
69+
}
70+
}

lib/src/github_storage_base.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import 'package:github/github.dart';
2+
import 'github_box.dart';
3+
import '../src/helper.dart';
4+
5+
class GithubStorage {
6+
/// Github username
7+
final String username;
8+
9+
/// https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
10+
final String personalAccessToken;
11+
12+
/// Public or private repository name
13+
/// https://docs.github.com/en/repositories
14+
final String repository;
15+
16+
GithubStorage(
17+
{required this.username,
18+
required this.personalAccessToken,
19+
required this.repository});
20+
21+
/// Create box/file object
22+
GithubBox box({required String name, required String folder}) {
23+
return GithubBox(
24+
name: name, username, personalAccessToken, repository, folder);
25+
}
26+
27+
/// Remove box from github
28+
Future<void> deleteBox(String boxName) async {
29+
final box =
30+
await GitHub(auth: Authentication.withToken(personalAccessToken))
31+
.repositories
32+
.getContents(RepositorySlug(username, repository), boxName);
33+
await GitHub(auth: Authentication.withToken(personalAccessToken))
34+
.repositories
35+
.deleteFile(RepositorySlug(username, repository), boxName,
36+
"Delete box: $boxName", box.file!.sha!, "main");
37+
}
38+
39+
/// Create new empty box/file if not exist yet
40+
Future<void> createBox({required String name, required String folder}) async {
41+
await GitHub(auth: Authentication.withToken(personalAccessToken))
42+
.repositories
43+
.createFile(
44+
RepositorySlug(username, repository),
45+
CreateFile(
46+
branch: "main",
47+
path: "$folder/$name",
48+
content: prettyByte({}),
49+
message: "Create new box: /$folder/$name"),
50+
);
51+
}
52+
}

lib/src/helper.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import 'dart:convert';
2+
3+
/// just helper function
4+
/// for beauty look on web github
5+
String prettyByte(Map<String, dynamic> object) {
6+
JsonEncoder encoder = JsonEncoder.withIndent(' ');
7+
String pretty = encoder.convert(object);
8+
List<int> byte = pretty.codeUnits;
9+
return base64Encode(byte);
10+
}

0 commit comments

Comments
 (0)