From efe3ef6b5980371c6a1a1d3d93f27649789fb8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Djk=C3=A1=C5=A5o?= Date: Wed, 17 Apr 2024 17:30:51 +0200 Subject: [PATCH] init --- .gitignore | 1 + .gitmodules | 15 ++ Cargo.lock | 230 ++++++++++++++++++++++ Cargo.toml | 12 ++ all_apps/apps | 1 + all_apps/saleor-app-abandoned-checkouts | 1 + all_apps/saleor-app-payment-authorize.net | 1 + all_apps/saleor-app-payment-klarna | 1 + all_apps/saleor-app-payment-stripe | 1 + changes.sh | 59 ++++++ changes/actions.json | 92 +++++++++ changes/changes.json | 186 +++++++++++++++++ changes/snippets/case_redisapl.ts | 8 + changes/snippets/import_redisapl.ts | 1 + changes/snippets/redis_apl.ts | 93 +++++++++ changes/snippets/turbo_env.ts | 1 + src/main.rs | 134 +++++++++++++ 17 files changed, 837 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 160000 all_apps/apps create mode 160000 all_apps/saleor-app-abandoned-checkouts create mode 160000 all_apps/saleor-app-payment-authorize.net create mode 160000 all_apps/saleor-app-payment-klarna create mode 160000 all_apps/saleor-app-payment-stripe create mode 100755 changes.sh create mode 100644 changes/actions.json create mode 100644 changes/changes.json create mode 100644 changes/snippets/case_redisapl.ts create mode 100644 changes/snippets/import_redisapl.ts create mode 100644 changes/snippets/redis_apl.ts create mode 100644 changes/snippets/turbo_env.ts create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..62a3eee --- /dev/null +++ b/.gitmodules @@ -0,0 +1,15 @@ +[submodule "all_apps/apps"] + path = all_apps/apps + url = https://github.com/saleor/apps +[submodule "all_apps/saleor-app-payment-authorize.net"] + path = all_apps/saleor-app-payment-authorize.net + url = https://github.com/saleor/saleor-app-payment-authorize.net +[submodule "all_apps/saleor-app-payment-stripe"] + path = all_apps/saleor-app-payment-stripe + url = https://github.com/saleor/saleor-app-payment-stripe +[submodule "all_apps/saleor-app-payment-klarna"] + path = all_apps/saleor-app-payment-klarna + url = https://github.com/saleor/saleor-app-payment-klarna +[submodule "all_apps/saleor-app-abandoned-checkouts"] + path = all_apps/saleor-app-abandoned-checkouts + url = https://github.com/saleor/saleor-app-abandoned-checkouts diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9837ec7 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,230 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "proc-macro2" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "saleor-dockerize-all-apps" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "spinners", + "thiserror", + "walkdir", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "spinners" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ef947f358b9c238923f764c72a4a9d42f2d637c46e059dbd319d6e7cfb4f82" +dependencies = [ + "lazy_static", + "maplit", + "strum", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d87790d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "saleor-dockerize-all-apps" +version = "0.1.0" +edition = "2021" + +[dependencies] +# owo-colors = "4.0.0" +serde = { version = "1.0.198", features = ["derive"] } +serde_json = "1.0.116" +spinners = "4.1.1" +thiserror = "1.0.58" +walkdir = "2.5.0" diff --git a/all_apps/apps b/all_apps/apps new file mode 160000 index 0000000..b1f272a --- /dev/null +++ b/all_apps/apps @@ -0,0 +1 @@ +Subproject commit b1f272a9df378b35a456e71f883d6c3223332664 diff --git a/all_apps/saleor-app-abandoned-checkouts b/all_apps/saleor-app-abandoned-checkouts new file mode 160000 index 0000000..3fddb86 --- /dev/null +++ b/all_apps/saleor-app-abandoned-checkouts @@ -0,0 +1 @@ +Subproject commit 3fddb86fe003f7552d413d12a37fd1998c02f84c diff --git a/all_apps/saleor-app-payment-authorize.net b/all_apps/saleor-app-payment-authorize.net new file mode 160000 index 0000000..c3c3d5b --- /dev/null +++ b/all_apps/saleor-app-payment-authorize.net @@ -0,0 +1 @@ +Subproject commit c3c3d5ba8dc871ff3435f7b1852b8bee2af2da88 diff --git a/all_apps/saleor-app-payment-klarna b/all_apps/saleor-app-payment-klarna new file mode 160000 index 0000000..8740c3b --- /dev/null +++ b/all_apps/saleor-app-payment-klarna @@ -0,0 +1 @@ +Subproject commit 8740c3b0090a22cad3f80108ec3f91f12acde57c diff --git a/all_apps/saleor-app-payment-stripe b/all_apps/saleor-app-payment-stripe new file mode 160000 index 0000000..70151ab --- /dev/null +++ b/all_apps/saleor-app-payment-stripe @@ -0,0 +1 @@ +Subproject commit 70151abb52786687293b173471f574444b5331a6 diff --git a/changes.sh b/changes.sh new file mode 100755 index 0000000..66275c5 --- /dev/null +++ b/changes.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +REDIS_APL_PATH="./changes/snippets/redis_apl.ts" +CURR_PWD="$(pwd)" + +app_paths=( + "apps/apps/cms-v2" + "apps/apps/avatax" + "apps/apps/crm" + "apps/apps/data-importer" + "apps/apps/emails-and-messages" + "apps/apps/invoices" + "apps/apps/klaviyo" + "apps/apps/products-feed" + "apps/apps/search" + "apps/apps/segment" + "apps/apps/slack" + "apps/apps/taxjar" + "saleor-app-abandoned-checkouts" + "saleor-app-payment-authorize.net" + "saleor-app-payment-klarna" + "saleor-app-payment-stripe" +) + +redis_apl_target_paths=( + "apps/apps/cms-v2/src" + "apps/apps/avatax" + "apps/apps/crm/src" + "apps/apps/data-importer" + "apps/apps/emails-and-messages/src" + "apps/apps/invoices/src" + "apps/apps/klaviyo" + "apps/apps/products-feed/src" + "apps/apps/search" + "apps/apps/segment/src" + "apps/apps/slack/src/lib" + "apps/apps/taxjar" + "saleor-app-abandoned-checkouts" + "saleor-app-payment-authorize.net/src" + "saleor-app-payment-klarna/src" + "saleor-app-payment-stripe/src" +) + +echo "copying redis_apls..." + +for i in ${redis_apl_target_paths[*]}; do + echo "copying redis_apl.ts to ./all_apps/$i" + cp -f "$REDIS_APL_PATH" "./all_apps/$i" + # always copies next to saleor-app.ts, so let's add some files to that file too + rg -l "switch \(process.env.APL\)" -t ts +done + +for i in ${app_paths[*]}; do + cd "./all_apps/$i" + echo $(pwd) + pnpm i + pnpm i ioredis + cd "$CURR_PWD" +done diff --git a/changes/actions.json b/changes/actions.json new file mode 100644 index 0000000..540ca8e --- /dev/null +++ b/changes/actions.json @@ -0,0 +1,92 @@ +[ + { + "name": "default_patch", + "actions": [ + { + "target": "redis_apl.ts", + "action_type": "Create", + "snippets": [ + { + "snippet": "redis_apl.ts" + } + ] + }, + { + "target": "saleor-app.ts", + "action_type": "Insert", + "snippets": [ + { + "after": "switch (aplType)", + "snippet": "case_redisapl.ts" + }, + { + "after": "import", + "snippet": "import_redisapl.ts" + } + ] + } + ] + }, + { + "name": "turbo_patch", + "actions": [ + { + "target": "turbo.json", + "action_type": "Insert", + "snippets": [ + { + "after": "APP_API_BASE_URL", + "snippet": "turbo_env.ts" + } + ] + } + ] + }, + { + "name": "default_but_process_switch", + "actions": [ + { + "target": "redis_apl.ts", + "action_type": "Create", + "snippets": [ + { + "snippet": "redis_apl.ts" + } + ] + }, + { + "target": "saleor-app.ts", + "action_type": "Insert", + "snippets": [ + { + "after": "switch (process.env.APL)", + "snippet": "case_redisapl.ts" + }, + { + "after": "import", + "snippet": "import_redisapl.ts" + } + ] + } + ] + }, + { + "name": "default_but_env_switch", + "actions": [ + { + "target": "saleor-app.ts", + "action_type": "Insert", + "snippets": [ + { + "after": "import", + "snippet": "import_redisapl.ts" + }, + { + "after": "switch (env.APL)", + "snippet": "case_redisapl.ts" + } + ] + } + ] + } +] diff --git a/changes/changes.json b/changes/changes.json new file mode 100644 index 0000000..5f0b6c7 --- /dev/null +++ b/changes/changes.json @@ -0,0 +1,186 @@ +[ + { + "folder": "apps", + "sub": [ + { + "folder": "apps", + "sub": [ + { + "folder": "avatax", + "actions_by_ref": [ + "default_but_process_switch", + "turbo_patch" + ] + }, + { + "folder": "cms-v2", + "actions_by_ref": [ + "turbo_patch" + ], + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_patch" + ] + } + ] + }, + { + "folder": "crm", + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_patch" + ] + } + ] + }, + { + "folder": "data-importer", + "actions_by_ref": [ + "default_but_process_switch", + "turbo_patch" + ] + }, + { + "folder": "emails-and-messages", + "actions_by_ref": [ + "turbo_patch" + ], + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_patch" + ] + } + ] + }, + { + "folder": "invoices", + "actions_by_ref": [ + "turbo_patch" + ], + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_patch" + ] + } + ] + }, + { + "folder": "klaviyo", + "actions_by_ref": [ + "default_patch", + "turbo_patch" + ] + }, + { + "folder": "products-feed", + "actions_by_ref": [ + "turbo_patch" + ], + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_patch" + ] + } + ] + }, + { + "folder": "search", + "actions_by_ref": [ + "turbo_patch", + "default_patch" + ] + }, + { + "folder": "segment", + "actions_by_ref": [ + "turbo_patch" + ], + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_patch" + ] + } + ] + }, + { + "folder": "slack", + "actions_by_ref": [ + "turbo_patch" + ], + "sub": [ + { + "folder": "src", + "sub": [ + { + "folder": "lib", + "actions_by_ref": [ + "default_but_process_switch" + ] + } + ] + } + ] + }, + { + "folder": "taxjar", + "actions_by_ref": [ + "turbo_patch", + "default_but_process_switch" + ] + } + ] + }, + { + "folder": "saleor-app-abandoned-checkouts", + "actions_by_ref": [ + "default_but_process_switch" + ] + }, + { + "folder": "saleor-app-payment-authorize.net", + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_but_env_switch" + ] + } + ] + }, + { + "folder": "saleor-app-payment-klarna", + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_but_env_switch" + ] + } + ] + }, + { + "folder": "saleor-app-payment-stripe", + "sub": [ + { + "folder": "src", + "actions_by_ref": [ + "default_but_env_switch" + ] + } + ] + } + ] + } +] diff --git a/changes/snippets/case_redisapl.ts b/changes/snippets/case_redisapl.ts new file mode 100644 index 0000000..003313c --- /dev/null +++ b/changes/snippets/case_redisapl.ts @@ -0,0 +1,8 @@ + case "redis": { + if (!process.env.REDIS_URL) throw new Error("Missing redis url"); + if (!process.env.APP_API_BASE_URL) + throw new Error("Redis relies on APP_API_BASE_URL to store keys, please set env variable"); + apl = new RedisAPL({ redisUrl: process.env.REDIS_URL, appApiBaseUrl: process.env.APP_API_BASE_URL }); + console.log(apl) + break; + } diff --git a/changes/snippets/import_redisapl.ts b/changes/snippets/import_redisapl.ts new file mode 100644 index 0000000..d444dbc --- /dev/null +++ b/changes/snippets/import_redisapl.ts @@ -0,0 +1 @@ +import { RedisAPL } from "./redis_apl" diff --git a/changes/snippets/redis_apl.ts b/changes/snippets/redis_apl.ts new file mode 100644 index 0000000..5895dfc --- /dev/null +++ b/changes/snippets/redis_apl.ts @@ -0,0 +1,93 @@ +import Redis from "ioredis"; + +import { + APL, + AplConfiguredResult, + AplReadyResult, + AuthData, +} from "@saleor/app-sdk/APL"; + +export type RedisAPLClientArgs = { + client: Redis; + appApiBaseUrl: string; +}; +export type RedisAPLUrlArgs = { + redisUrl: string; + appApiBaseUrl: string; +}; +/** + * Redis APL + * @param redisUrl - in format redis[s]://[[username][:password]@][host][:port][/db-number], + * so for example redis://alice:foobared@awesome.redis.server:6380 + * For saleor-platform, thats: `redis://redis:6379/2` + */ +export class RedisAPL implements APL { + private client; + + private appApiBaseUrl; + + constructor(args: RedisAPLClientArgs | RedisAPLUrlArgs) { + if (!args.appApiBaseUrl) + throw new Error( + "The RedisAPL requires to know the app api url beforehand", + ); + this.appApiBaseUrl = args.appApiBaseUrl; + + if ("client" in args && args.client) { + this.client = args.client; + } else if ("redisUrl" in args && args.redisUrl) { + this.client = new Redis(args.redisUrl, { lazyConnect: true }); + } else { + throw new Error("RedisAPL: No redis url or client defined"); + } + this.isConfigured().then((v) => console.log("REDIS: CONFIGURED TEST: ", v)); + } + + private prepareKey(saleorApiUrl: string) { + return `${this.appApiBaseUrl}:${saleorApiUrl}`; + } + + async get(saleorApiUrl: string): Promise { + const res = await this.client.get(this.prepareKey(saleorApiUrl)); + console.log( + `REDIS: GET FOR ${this.prepareKey(saleorApiUrl)} (is ${res ? "truthy" : "falsy"}):`, + ); + if (res) { + const data = JSON.parse(res) as AuthData; + console.dir(data, { depth: null }); + return data; + } + } + + async set(authData: AuthData): Promise { + const res = await this.client.set( + this.prepareKey(authData.saleorApiUrl), + JSON.stringify(authData), + ); + console.log( + `REDIS: SET FOR ${this.prepareKey(authData.saleorApiUrl)}: `, + res, + ); + } + + async delete(saleorApiUrl: string): Promise { + const val = await this.client.getdel(this.prepareKey(saleorApiUrl)); + console.log("REDIS: DEL: ", val); + } + + async getAll(): Promise { + throw new Error("redisAPL does not support getAll method"); + } + + async isReady(): Promise { + const ready = !!(await this.client.info()); + console.log("REDIS: ISREADY: ", ready); + return { ready: ready } as AplReadyResult; + } + + async isConfigured(): Promise { + const ready = !!(await this.client.info()); + console.log("REDIS: ISCONF: ", ready); + return { configured: ready } as AplConfiguredResult; + } +} diff --git a/changes/snippets/turbo_env.ts b/changes/snippets/turbo_env.ts new file mode 100644 index 0000000..c8297a5 --- /dev/null +++ b/changes/snippets/turbo_env.ts @@ -0,0 +1 @@ + "REDIS_URL" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6208197 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,134 @@ +use std::{ + io, + path::{Path, PathBuf}, + process::Command, + str::FromStr, +}; + +use serde::{Deserialize, Serialize}; +use walkdir::WalkDir; + +fn main() -> Result<(), io::Error> { + let snippets = get_snippets().unwrap(); + let actions = get_actions().unwrap(); + let changes = get_changes() + .unwrap() + .into_iter() + .map(|c| Box::new(c)) + .collect::>(); + + for change in changes { + let mut current_cumulative_path = std::env::current_dir()?; + current_cumulative_path.push("all_apps"); + current_cumulative_path.push(&change.folder); + + process_change(&change, ¤t_cumulative_path); + if let Some(sub) = change.sub { + iter_sub(sub) + } + } + + Ok(()) +} +pub fn process_change( + change: &Box, + current_cumulative_path: &PathBuf, +) -> Result<(), io::Error> { + if let Some(actions) = &change.actions { + for action in actions { + let mut current_file = current_cumulative_path.clone(); + current_file.push(&action.target); + let command; + match action.action_type { + ActionType::Create => Command::new("ln").args(["-s", current_file]), + ActionType::Insert => {} + } + } + } + Ok(()) +} + +pub fn iter_sub(sub: Vec>) { + for change in sub { + process_change(&change); + if let Some(further_sub) = change.sub { + iter_sub(further_sub) + } + } +} + +pub fn get_changes() -> Result, std::io::Error> { + Ok(serde_json::from_str(&std::fs::read_to_string( + "./changes/changes.json", + )?)?) +} + +pub fn get_snippets() -> Result, std::io::Error> { + let mut snippets = vec![]; + for entry in WalkDir::new("./changes/snippets").into_iter().flatten() { + if entry.path().is_file() { + if let Some(name) = entry.path().file_stem() { + if let Some(name) = name.to_str() { + snippets.push(Snippet { + id: SnippetId(name.to_owned()), + value: std::fs::read_to_string(entry.path())?, + }) + } + }; + } + } + Ok(snippets) +} + +pub fn get_actions() -> Result, std::io::Error> { + Ok(serde_json::from_str(&std::fs::read_to_string( + "./changes/actions.json", + )?)?) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Change { + pub folder: String, + pub sub: Option>>, + pub actions_by_ref: Option>, + pub actions: Option>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct NamedActions { + pub name: ActionsId, + pub actions: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Action { + pub target: String, + pub action_type: ActionType, + pub snippets: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ActionStep { + pub after: Option, + pub snippet: SnippetId, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Snippet { + id: SnippetId, + value: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum ActionType { + Insert, + Create, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[serde(transparent)] +pub struct SnippetId(pub String); + +#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[serde(transparent)] +pub struct ActionsId(pub String);