From 543e1057cd75d1032ef05e63f7e2d67f7fc92c1f Mon Sep 17 00:00:00 2001 From: "leo21.sismo.eth" Date: Sat, 8 Jul 2023 16:29:22 +0200 Subject: [PATCH] feat: simplify config, no need to import individual config files (#159) --- .github/workflows/create-app.yml | 35 +++ .gitignore | 3 + README.md | 1 - package.json | 14 +- space-configs/demo/aave-chan-initiative.ts | 11 +- space-configs/demo/cow-swap.ts | 19 +- space-configs/demo/privacy-is-normal.ts | 5 +- space-configs/demo/sismo.ts | 5 +- space-configs/demo/the-merge-contributors.ts | 9 +- space-configs/index.ts | 27 -- space-configs/main/aave-chan-initiative.ts | 7 +- space-configs/main/cow-swap.ts | 8 +- space-configs/main/privacy-is-normal.ts | 5 +- space-configs/main/sismo.ts | 5 +- space-configs/main/the-merge-contributors.ts | 7 +- space-configs/types.ts | 5 +- src/environments.ts | 6 +- src/libs/spaces/spaces.ts | 31 +- src/libs/spaces/types.ts | 9 +- .../configs-to-json/configs-to-json.script.ts | 17 ++ src/scripts/sync-apps-factory/index.ts | 2 + .../sync-apps-factory.script.ts | 6 + .../sync-apps-factory.test.ts | 35 +++ .../sync-apps-factory/sync-apps-factory.ts | 50 ++++ .../sync-apps-config-test-filled.ts | 276 ++++++++++++++++++ .../test-configs/sync-apps-config-test.ts | 276 ++++++++++++++++++ .../service-factory/service-factory.ts | 27 +- src/services/sismo-factory-service/index.ts | 2 + .../sismo-factory-api.ts | 53 ++++ .../sismo-factory-memory.ts | 33 +++ .../sismo-factory-service/sismo-factory.ts | 45 +++ .../Entities/user.entity.ts | 16 +- .../user-store/postgres-user-store/index.ts | 2 +- svgMock.js | 4 + yarn.lock | 263 ++++++++++++++++- 35 files changed, 1200 insertions(+), 119 deletions(-) create mode 100644 .github/workflows/create-app.yml delete mode 100644 space-configs/index.ts create mode 100644 src/scripts/configs-to-json/configs-to-json.script.ts create mode 100644 src/scripts/sync-apps-factory/index.ts create mode 100644 src/scripts/sync-apps-factory/sync-apps-factory.script.ts create mode 100644 src/scripts/sync-apps-factory/sync-apps-factory.test.ts create mode 100644 src/scripts/sync-apps-factory/sync-apps-factory.ts create mode 100644 src/scripts/sync-apps-factory/test-configs/sync-apps-config-test-filled.ts create mode 100644 src/scripts/sync-apps-factory/test-configs/sync-apps-config-test.ts create mode 100644 src/services/sismo-factory-service/index.ts create mode 100644 src/services/sismo-factory-service/sismo-factory-api.ts create mode 100644 src/services/sismo-factory-service/sismo-factory-memory.ts create mode 100644 src/services/sismo-factory-service/sismo-factory.ts create mode 100644 svgMock.js diff --git a/.github/workflows/create-app.yml b/.github/workflows/create-app.yml new file mode 100644 index 00000000..3b0b74e6 --- /dev/null +++ b/.github/workflows/create-app.yml @@ -0,0 +1,35 @@ +name: Create Sismo Connect App + +on: + issue_comment: + types: [created] + +jobs: + create-app: + runs-on: ubuntu-latest + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/create-app') && github.event.comment.author_association == 'COLLABORATOR' + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Create Sismo Connect App on the factory + run: yarn sync-all-apps-factory + env: + SISMO_FACTORY_URL: https://factory-api.sismo.io + SISMO_FACTORY_TOKEN: ${{ secrets.SISMO_FACTORY_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Commit and push filled appId + run: | + git config --global user.email "robot@sismo.io" + git config --global user.name "Sismo Bot" + git add -A + git commit -m "feat: create Sismo Connect App and auto-fill appId" || exit 0 + git push origin HEAD:${{ github.event.issue.pull_request.head.ref }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 182a8abc..4e49c45c 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ next-env.d.ts .yarn .yarn.lock + +.space-configs/ +.space-configs/* \ No newline at end of file diff --git a/README.md b/README.md index 6ceb5eb4..9738680c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ space-configs/ │   ├── aave_chan_initiative_apps_swag_1014x720.png │   ├── aave_chan_initiative_apps_swag_400x400.png │   └── ... -├── index.ts └── types.ts ``` diff --git a/package.json b/package.json index 524f5efb..01429296 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,15 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev", - "build": "next build", + "dev": "yarn build-config && (next dev & nodemon --watch ./space-configs --ext ts --exec 'yarn build-config')", + "build": "yarn build-config && next build", "start": "next start", "lint": "next lint", - "test": "yarn jest --coverage", + "test": "yarn build-config && yarn jest --coverage", + "prebuild": "yarn run build-config", + "build-config": "tsx ./src/scripts/configs-to-json/configs-to-json.script.ts", + "sync-all-apps-factory": "NEXT_PUBLIC_NODE_ENV=main yarn sync-apps-factory && NEXT_PUBLIC_NODE_ENV=demo yarn sync-apps-factory", + "sync-apps-factory": "yarn run build-config && tsx -r ./svgMock.js ./src/scripts/sync-apps-factory/sync-apps-factory.script.ts", "prettier": "prettier --write 'src/**/*.ts' '.github' 'README.md'" }, "dependencies": { @@ -52,8 +56,10 @@ "jest": "^29.5.0", "jest-date-mock": "^1.0.8", "jest-environment-jsdom": "29.5.0", + "nodemon": "^2.0.22", "sass": "^1.62.1", "ts-jest": "^29.1.0", - "ts-node": "^10.9.1" + "ts-node": "^10.9.1", + "tsx": "^3.12.7" } } diff --git a/space-configs/demo/aave-chan-initiative.ts b/space-configs/demo/aave-chan-initiative.ts index 493ebbda..b615ab1c 100644 --- a/space-configs/demo/aave-chan-initiative.ts +++ b/space-configs/demo/aave-chan-initiative.ts @@ -1,10 +1,9 @@ // add an images folder in your space folder if you would like Sismo to host your images -import { AuthType, ClaimType } from "@sismo-core/sismo-connect-server"; +import { AuthType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const aaveChanInitiativeConfigDemo: SpaceConfig = { +export default { metadata: { - slug: "aave-chan-initiative", name: "Aave-Chan Initiative", description: "This Space is dedicated to the Aave-Chan Initiative (ACI - Aavechan.eth), a delegate platform. Aave users that delegated their governance power to ACI will get access to gifts and premium features.", @@ -47,9 +46,7 @@ export const aaveChanInitiativeConfigDemo: SpaceConfig = { value: 1000, }, ], - impersonateAddresses: [ - "0x5af25164a0f1207db70727a2c447d6a7b44b89d0" - ], + impersonateAddresses: ["0x5af25164a0f1207db70727a2c447d6a7b44b89d0"], }, templateConfig: { step2CtaText: "Claim your Swag", @@ -118,4 +115,4 @@ export const aaveChanInitiativeConfigDemo: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/demo/cow-swap.ts b/space-configs/demo/cow-swap.ts index 6150e465..1e77c369 100644 --- a/space-configs/demo/cow-swap.ts +++ b/space-configs/demo/cow-swap.ts @@ -2,9 +2,8 @@ import { AuthType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const cowSwapConfigDemo: SpaceConfig = { +export default { metadata: { - slug: "cow-swap", name: "Cow Swap", description: "This Space is dedicated to Cow Swap, a DEX aggregator. Cow Traders and Holders will get access to gifts and premium features.", @@ -54,9 +53,7 @@ export const cowSwapConfigDemo: SpaceConfig = { value: 3, }, ], - impersonateAddresses: [ - "0xb18e3bf33365fd2466c2e99b181e527a165c210c" - ], + impersonateAddresses: ["0xb18e3bf33365fd2466c2e99b181e527a165c210c"], }, templateConfig: { step2CtaText: "Claim your Swag", @@ -74,7 +71,8 @@ export const cowSwapConfigDemo: SpaceConfig = { ], congratulationsMessage: { title: "Congratulations!", - description: "Swags are given on a first come first serve basis. Come to our booth and tell us your name/pseudonym to claim your Swag 🎒", + description: + "Swags are given on a first come first serve basis. Come to our booth and tell us your name/pseudonym to claim your Swag 🎒", }, output: { destination: { @@ -109,9 +107,7 @@ export const cowSwapConfigDemo: SpaceConfig = { value: 1, }, ], - impersonateAddresses: [ - "0xb18e3bf33365fd2466c2e99b181e527a165c210c" - ], + impersonateAddresses: ["0xb18e3bf33365fd2466c2e99b181e527a165c210c"], }, templateConfig: { step2CtaText: "Register to get your Ticket", @@ -129,7 +125,8 @@ export const cowSwapConfigDemo: SpaceConfig = { ], congratulationsMessage: { title: "Congratulations!", - description: "Tickets are processed on a first come first serve basis. You will receive an email update in a few days! See you there 💜", + description: + "Tickets are processed on a first come first serve basis. You will receive an email update in a few days! See you there 💜", }, output: { destination: { @@ -145,4 +142,4 @@ export const cowSwapConfigDemo: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/demo/privacy-is-normal.ts b/space-configs/demo/privacy-is-normal.ts index e916e519..520b036e 100644 --- a/space-configs/demo/privacy-is-normal.ts +++ b/space-configs/demo/privacy-is-normal.ts @@ -2,9 +2,8 @@ import { AuthType, ClaimType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const privacyIsNormalConfigDemo: SpaceConfig = { +export default { metadata: { - slug: "privacy-is-normal", name: "Privacy Is Normal 🌼", description: "This Space celebrates privacy as a fundamental human right. By proving you are a Tornado Cash user in a privacy-preserving manner and with a Gitcoin Passport, you were able to participate in our Sybil-resistant lottery. 10 winners have been selected to receive a printed ‘Privacy Is Normal’ artwork.", @@ -157,4 +156,4 @@ export const privacyIsNormalConfigDemo: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/demo/sismo.ts b/space-configs/demo/sismo.ts index 57818690..a584652c 100644 --- a/space-configs/demo/sismo.ts +++ b/space-configs/demo/sismo.ts @@ -2,9 +2,8 @@ import { AuthType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const sismoConfigDemo: SpaceConfig = { +export default { metadata: { - slug: "sismo", name: "Sismo", description: "This Space presents Sismo Apps, offering exclusive benefits for our contributors and community members. Prove your level and unlock access to the apps. Learn more about the Sismo Community and check your level: https://community.sismo.io.", @@ -470,4 +469,4 @@ export const sismoConfigDemo: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/demo/the-merge-contributors.ts b/space-configs/demo/the-merge-contributors.ts index d36b1f32..f7809b5e 100644 --- a/space-configs/demo/the-merge-contributors.ts +++ b/space-configs/demo/the-merge-contributors.ts @@ -3,10 +3,9 @@ import { AuthType } from "@sismo-core/sismo-connect-client"; import { SpaceConfig } from "../types"; -export const theMergeContributorsConfigDemo: SpaceConfig = { +export default { metadata: { name: "The Merge Contributors", - slug: "the-merge-contributors", description: "Tribute to contributors to the Ethereum Merge.", image: "pfp_Space_TheMergeContributors_400x400.png", }, @@ -19,7 +18,7 @@ export const theMergeContributorsConfigDemo: SpaceConfig = { description: "Register your email address to receive exclusive tickets for web3 events - open to contributors to The Merge.", tags: ["Event"], - image: "EthCCtickets_1014x720px.png", + image: "EthCCtickets_1014x720px.png", createdAt: new Date("2022-07-01T00:00:00.000Z"), }, sismoConnectRequest: { @@ -60,7 +59,7 @@ export const theMergeContributorsConfigDemo: SpaceConfig = { }, options: { isFeatured: true, - } + }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/index.ts b/space-configs/index.ts deleted file mode 100644 index f3f616f6..00000000 --- a/space-configs/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { SpaceConfig } from "./types"; -import { theMergeContributorsConfigMain } from "@/space-configs/main/the-merge-contributors"; -import { privacyIsNormalConfigMain } from "@/space-configs/main/privacy-is-normal"; -import { aaveChanInitiativeConfigMain } from "./main/aave-chan-initiative"; -import { sismoConfigMain } from "@/space-configs/main/sismo"; -import { cowSwapConfigMain } from "@/space-configs/main/cow-swap"; -import { theMergeContributorsConfigDemo } from "@/space-configs/demo/the-merge-contributors"; -import { sismoConfigDemo } from "@/space-configs/demo/sismo"; -import { privacyIsNormalConfigDemo } from "@/space-configs/demo/privacy-is-normal"; -import { aaveChanInitiativeConfigDemo } from "@/space-configs/demo/aave-chan-initiative"; -import { cowSwapConfigDemo } from "@/space-configs/demo/cow-swap"; - -export const configsMain: SpaceConfig[] = [ - theMergeContributorsConfigMain, - privacyIsNormalConfigMain, - aaveChanInitiativeConfigMain, - sismoConfigMain, - cowSwapConfigMain, -]; - -export const configsDemo: SpaceConfig[] = [ - theMergeContributorsConfigDemo, - sismoConfigDemo, - privacyIsNormalConfigDemo, - aaveChanInitiativeConfigDemo, - cowSwapConfigDemo, -]; diff --git a/space-configs/main/aave-chan-initiative.ts b/space-configs/main/aave-chan-initiative.ts index a4f393ea..1275c9af 100644 --- a/space-configs/main/aave-chan-initiative.ts +++ b/space-configs/main/aave-chan-initiative.ts @@ -2,9 +2,8 @@ import { AuthType, ClaimType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const aaveChanInitiativeConfigMain: SpaceConfig = { +export default { metadata: { - slug: "aave-chan-initiative", name: "Aave-Chan Initiative", description: "This Space is dedicated to the Aave-Chan Initiative (ACI - Aavechan.eth), a delegate platform. Aave users that delegated their governance power to ACI will get access to gifts and premium features.", @@ -112,7 +111,7 @@ export const aaveChanInitiativeConfigMain: SpaceConfig = { }, options: { isFeatured: true, - } + }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/main/cow-swap.ts b/space-configs/main/cow-swap.ts index 2c60769c..79a95a2d 100644 --- a/space-configs/main/cow-swap.ts +++ b/space-configs/main/cow-swap.ts @@ -2,9 +2,8 @@ import { AuthType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const cowSwapConfigMain: SpaceConfig = { +export default { metadata: { - slug: "cow-swap", name: "CoW Swap", description: "Welcome to the CoW Swap Sismo Space. CoW Swap is a decentralized exchange aggregator that protects users from MEV. CoW community, traders and holders can find here exclusive events, swags and premium features.", @@ -109,8 +108,7 @@ export const cowSwapConfigMain: SpaceConfig = { ], }, templateConfig: { - step2CtaText - : "Register to get your ticket", + step2CtaText: "Register to get your ticket", fields: [ { type: "short-text", @@ -142,4 +140,4 @@ export const cowSwapConfigMain: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/main/privacy-is-normal.ts b/space-configs/main/privacy-is-normal.ts index 72f6ba69..ae2a41b8 100644 --- a/space-configs/main/privacy-is-normal.ts +++ b/space-configs/main/privacy-is-normal.ts @@ -2,9 +2,8 @@ import { AuthType, ClaimType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const privacyIsNormalConfigMain: SpaceConfig = { +export default { metadata: { - slug: "privacy-is-normal", name: "Privacy Is Normal 🌼", description: "This Space celebrates privacy as a fundamental human right. By proving you are a Tornado Cash user in a privacy-preserving manner and with a Gitcoin Passport, you were able to participate in our Sybil-resistant lottery. 10 winners have been selected to receive a printed ‘Privacy Is Normal’ artwork.", @@ -155,4 +154,4 @@ export const privacyIsNormalConfigMain: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/main/sismo.ts b/space-configs/main/sismo.ts index de38eb91..69728ba6 100644 --- a/space-configs/main/sismo.ts +++ b/space-configs/main/sismo.ts @@ -2,9 +2,8 @@ import { AuthType } from "@sismo-core/sismo-connect-server"; import { SpaceConfig } from "../types"; -export const sismoConfigMain: SpaceConfig = { +export default { metadata: { - slug: "sismo", name: "Sismo", description: "This Space presents Sismo Apps, offering exclusive benefits for our contributors and community members. Prove your level and unlock access to the apps. Learn more about the Sismo Community and check your level: https://community.sismo.io.", @@ -188,4 +187,4 @@ export const sismoConfigMain: SpaceConfig = { }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/main/the-merge-contributors.ts b/space-configs/main/the-merge-contributors.ts index 48f231ba..0fbd3f2c 100644 --- a/space-configs/main/the-merge-contributors.ts +++ b/space-configs/main/the-merge-contributors.ts @@ -3,10 +3,9 @@ import { AuthType } from "@sismo-core/sismo-connect-client"; import { SpaceConfig } from "../types"; -export const theMergeContributorsConfigMain: SpaceConfig = { +export default { metadata: { name: "The Merge Contributors", - slug: "the-merge-contributors", description: "Tribute to contributors to the Ethereum Merge.", image: "pfp_Space_TheMergeContributors_400x400.png", }, @@ -82,7 +81,7 @@ export const theMergeContributorsConfigMain: SpaceConfig = { }, options: { isFeatured: true, - } + }, }, ], -}; +} as SpaceConfig; diff --git a/space-configs/types.ts b/space-configs/types.ts index 44b609d8..0c756e87 100644 --- a/space-configs/types.ts +++ b/space-configs/types.ts @@ -3,7 +3,6 @@ import { AuthRequest, ClaimRequest } from "@sismo-core/sismo-connect-react"; export type SpaceConfig = { metadata: { name: string; // 80 characters max - slug: string; // spaces.sismo.io/[slug] description: string; // 300 characters max image?: string; // 160x160px can be an url or local file socialLinks?: { @@ -11,6 +10,7 @@ export type SpaceConfig = { link: string; }[]; tags?: string[]; + slug?: string; // spaces.sismo.io/[slug] - auto-generated with the filename }; apps?: AppConfig[]; options?: { @@ -53,7 +53,6 @@ type AppCommonConfig = { }; }; - export type ExternalAppTemplateConfig = { link: string; }; @@ -167,4 +166,4 @@ type InputCommon = { helperText?: string; // 80 characters max maxCharacter?: number; isRequired?: boolean; -}; \ No newline at end of file +}; diff --git a/src/environments.ts b/src/environments.ts index f9694a5a..6c15c47f 100644 --- a/src/environments.ts +++ b/src/environments.ts @@ -11,7 +11,11 @@ type Environment = { type EnvNames = "demo" | "dev" | "main" | "test"; export const isEnv = (envName: EnvNames) => { - return process.env.NEXT_PUBLIC_NODE_ENV === envName; + return getEnvName() === envName; +}; + +export const getEnvName = () => { + return process.env.NEXT_PUBLIC_NODE_ENV; }; const env: Environment = { diff --git a/src/libs/spaces/spaces.ts b/src/libs/spaces/spaces.ts index a75c8140..58c7ecd3 100644 --- a/src/libs/spaces/spaces.ts +++ b/src/libs/spaces/spaces.ts @@ -17,33 +17,34 @@ export async function getSpaces(): Promise { const spaceProfileImage = await getImgSrcFromConfig({ configSlug: spaceConfig.metadata.slug, fileName: spaceConfig.metadata.image, - }) + }); for (let appConfig of spaceConfig.apps) { const appImage = await getImgSrcFromConfig({ configSlug: spaceConfig.metadata.slug, fileName: appConfig.metadata.image, - }) + }); const appCommon: AppCommonType = { name: appConfig.metadata.name, slug: appConfig.metadata.slug, description: appConfig.metadata.description, image: appImage, + imageFilename: appConfig.metadata.image, tags: appConfig.metadata.tags, claimRequests: appConfig.sismoConnectRequest.claimRequests, authRequests: appConfig.sismoConnectRequest.authRequests, impersonateAddresses: appConfig.sismoConnectRequest.impersonateAddresses, appId: appConfig.sismoConnectRequest.appId, - startDate: appConfig.options?.startDate, - endDate: appConfig.options?.endDate, + startDate: new Date(appConfig.options?.startDate), + endDate: new Date(appConfig.options?.endDate), disabled: appConfig.options?.disabled, - createdAt: appConfig.metadata.createdAt, - lastUpdateAt: appConfig.metadata?.lastUpdateAt, + createdAt: new Date(appConfig.metadata.createdAt), + lastUpdateAt: new Date(appConfig.metadata?.lastUpdateAt), isFeatured: appConfig.options?.isFeatured, space: { slug: spaceConfig.metadata.slug, name: spaceConfig.metadata.name, - profileImage: spaceProfileImage - } + profileImage: spaceProfileImage, + }, }; if (appConfig.type === "external") { apps.push({ @@ -97,13 +98,13 @@ export async function getSpaces(): Promise { return spaces; } -export type GetAppsOptions = { - sortedBy?: "createdAt", - where?: { +export type GetAppsOptions = { + sortedBy?: "createdAt"; + where?: { spaceSlug?: string; appSlug?: string; - } -} + }; +}; export async function getApps(options?: GetAppsOptions) { const spaces = await getSpaces(); @@ -122,11 +123,11 @@ export async function getApps(options?: GetAppsOptions) { } if (options?.where?.appSlug) { - apps = apps.filter(app => app.slug === options?.where?.appSlug); + apps = apps.filter((app) => app.slug === options?.where?.appSlug); } if (options?.where?.spaceSlug) { - apps = apps.filter(app => app.space.slug === options?.where?.spaceSlug); + apps = apps.filter((app) => app.space.slug === options?.where?.spaceSlug); } return apps; diff --git a/src/libs/spaces/types.ts b/src/libs/spaces/types.ts index f169ee42..00223046 100644 --- a/src/libs/spaces/types.ts +++ b/src/libs/spaces/types.ts @@ -35,6 +35,7 @@ export type AppCommonType = { description: string; // 200 characters max innerDescription?: string; image: string | ImportedNextImage; // 550x390px can be an url or local file + imageFilename: string; tags: string[]; createdAt?: Date; lastUpdateAt?: Date; @@ -54,10 +55,10 @@ export type AppCommonType = { appDescription?: string; space: { - slug: string, - name: string, - profileImage: string | ImportedNextImage - } + slug: string; + name: string; + profileImage: string | ImportedNextImage; + }; }; export type UserSelection = FirstComeFirstServed | Lottery; diff --git a/src/scripts/configs-to-json/configs-to-json.script.ts b/src/scripts/configs-to-json/configs-to-json.script.ts new file mode 100644 index 00000000..ca96cd64 --- /dev/null +++ b/src/scripts/configs-to-json/configs-to-json.script.ts @@ -0,0 +1,17 @@ +import { SpaceConfig } from "@/space-configs/types"; +import fs from "fs"; + +for (const env of ["main", "demo"]) { + let configs: SpaceConfig[] = []; + fs.readdirSync(`${__dirname}/../../../space-configs/${env}`).forEach((filename) => { + const config = require(`${__dirname}/../../../space-configs/${env}/${filename}`).default; + config.metadata.slug = filename.replace(".ts", ""); + configs.push(config); + }); + + fs.mkdirSync(`${__dirname}/../../../.space-configs`, { recursive: true }); + fs.writeFileSync( + `${__dirname}/../../../.space-configs/${env}.json`, + JSON.stringify(configs, null, 2) + ); +} diff --git a/src/scripts/sync-apps-factory/index.ts b/src/scripts/sync-apps-factory/index.ts new file mode 100644 index 00000000..ea3fee27 --- /dev/null +++ b/src/scripts/sync-apps-factory/index.ts @@ -0,0 +1,2 @@ +export * from "./sync-apps-factory"; +export * from "./sync-apps-factory.script"; diff --git a/src/scripts/sync-apps-factory/sync-apps-factory.script.ts b/src/scripts/sync-apps-factory/sync-apps-factory.script.ts new file mode 100644 index 00000000..006e7bb1 --- /dev/null +++ b/src/scripts/sync-apps-factory/sync-apps-factory.script.ts @@ -0,0 +1,6 @@ +import env, { getEnvName } from "@/src/environments"; +import { syncAppsFactory } from "./sync-apps-factory"; + +if (!env.isTest) { + syncAppsFactory(`${__dirname}/../../../space-configs/${getEnvName()}`, true); +} diff --git a/src/scripts/sync-apps-factory/sync-apps-factory.test.ts b/src/scripts/sync-apps-factory/sync-apps-factory.test.ts new file mode 100644 index 00000000..6428b6b3 --- /dev/null +++ b/src/scripts/sync-apps-factory/sync-apps-factory.test.ts @@ -0,0 +1,35 @@ +/** + * @jest-environment node + */ + +import fs from "fs"; +import ServiceFactory from "@/src/services/service-factory/service-factory"; +import { syncAppsConfigTest } from "@/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test"; +import { SismoFactoryService } from "@/src/services/sismo-factory-service"; +import { syncAppsFactory } from "@/src/scripts/sync-apps-factory"; + +describe("SCRIPT sync-apps-factory", () => { + let sismoFactoryMemory: SismoFactoryService; + + beforeEach(() => { + ServiceFactory.reset(); + ServiceFactory.getSpaceConfigs([syncAppsConfigTest]); + sismoFactoryMemory = ServiceFactory.getSismoFactoryService(); + // memoryTableStore = ServiceFactory.getZkFormTableStore() as MemoryTableStore; + }); + + it("should create apps when detecting {{ auto-fill }} in the appId field", async () => { + const res = await syncAppsFactory(`${__dirname}/test-configs`); + const createdApps = await sismoFactoryMemory.getApps(); + expect(createdApps.length).toEqual(3); + expect(createdApps[0].name).toEqual("app test number 1"); + expect(createdApps[1].name).toEqual("app test number 3"); + expect(createdApps[2].name).toEqual("app test number 4"); + expect(res[0].content).toContain(createdApps[0].id); + const expectedResult = fs.readFileSync( + `${__dirname}/test-configs/sync-apps-config-test-filled.ts`, + "utf8" + ); + expect(res[0].content).toEqual(expectedResult); + }); +}); diff --git a/src/scripts/sync-apps-factory/sync-apps-factory.ts b/src/scripts/sync-apps-factory/sync-apps-factory.ts new file mode 100644 index 00000000..30ab5792 --- /dev/null +++ b/src/scripts/sync-apps-factory/sync-apps-factory.ts @@ -0,0 +1,50 @@ +import { ZkAppType, getSpaces } from "@/src/libs/spaces"; +import ServiceFactory from "@/src/services/service-factory/service-factory"; +import fs from "fs"; + +const APP_REPLACE_PATTERN = /appId: "{{ auto-fill }}"/; + +export const syncAppsFactory = async (directoryLocation: string, save: boolean = false) => { + const sismoFactory = ServiceFactory.getSismoFactoryService(); + const loggerService = ServiceFactory.getLoggerService(); + const spaces = await getSpaces(); + let updatedFiles: { + filename: string; + content: string; + }[] = []; + for (const space of spaces) { + const apps: ZkAppType[] = space.apps; + const filename = `${directoryLocation}/${space.slug}.ts`; + let spaceFileContent = fs.readFileSync(filename, "utf8"); + let fileNeedsUpdate = false; + for (const app of apps) { + const appIdToFill = app?.appId?.includes("{{ auto-fill }}"); + if (appIdToFill) { + const imageContent = fs.readFileSync( + `${__dirname}/../../../space-configs/images/${app.imageFilename}` + ); + const imageBase64 = Buffer.from(imageContent).toString("base64"); + + loggerService.info(`Creating app ${app.name}...`); + const createdApp = await sismoFactory.createApp({ + name: app.name, + description: app.description, + logoBase64: imageBase64, + }); + loggerService.info(`App ${app.name} created in the factory with id ${createdApp.id}`); + + const createdAppIdString = `appId: "${createdApp.id}"`; + spaceFileContent = spaceFileContent.replace(APP_REPLACE_PATTERN, createdAppIdString); + fileNeedsUpdate = true; + } + } + if (save && fileNeedsUpdate) { + loggerService.info(`Saving file ${filename}`); + fs.writeFileSync(filename, spaceFileContent); + } + updatedFiles.push({ filename, content: spaceFileContent }); + } + return updatedFiles; +}; + +// syncAppsFactory(); diff --git a/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test-filled.ts b/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test-filled.ts new file mode 100644 index 00000000..2fe8eb45 --- /dev/null +++ b/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test-filled.ts @@ -0,0 +1,276 @@ +// add an images folder in your space folder if you would like Sismo to host your images + +import { AuthType } from "@sismo-core/sismo-connect-client"; +import { SpaceConfig } from "../../../../space-configs/types"; + +export const syncAppsConfigTest: SpaceConfig = { + metadata: { + name: "The leo Contributors", + slug: "sync-apps-config-test", + description: "Tribute to contributors to the Ethereum leo.", + image: "pfp_Space_TheMergeContributors_400x400.png", + }, + apps: [ + { + type: "zkForm", + metadata: { + name: "app test number 1", + slug: "ethcc-tickets", + description: + "Register your email address to receive exclusive tickets for web3 events - open to contributors to The leo.", + tags: ["Event"], + image: "EthCCtickets_1014x720px.png", + createdAt: new Date("2022-07-01T00:00:00.000Z"), + }, + sismoConnectRequest: { + appId: "0x0000000000000000000000000000000000000001", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [{ groupId: "0x42c768bb8ae79e4c5c05d3b51a4ec74a" }], + }, + templateConfig: { + step2CtaText: "Register to get tickets", + fields: [ + { + type: "short-text", + label: "First name", + isRequired: true, + }, + { + type: "short-text", + label: "Last name", + isRequired: true, + }, + { + type: "short-text", + label: "Email", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations", + description: + "You have successfully registered to receive exclusive tickets for web3 events.", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "1Wrh8gFPWuUfdip1wuOxBx_0bZQ_OJb2JsI5A-loRa-Y", + }, + }, + }, + options: { + isFeatured: true, + }, + }, + { + type: "zkForm", + metadata: { + slug: "event", + name: "app test number 2", + description: + "Prove you are a Cow Trader or Holder to register to an invitation-only event organized by Cow Swap, during EthCC week in Paris.", + tags: ["Event", "Ticket"], + image: "cowswap_app_store_cow_event_400x400.png", + createdAt: new Date("2023-07-04T18:00"), + }, + sismoConnectRequest: { + appId: "0x42bf819b60a7f4cbe57f2c5617b6a35c", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [ + { + groupId: "0x70c30e9a9abdb5fd41ba9e9cb7f50173", + value: 1, + }, + ], + impersonateAddresses: ["0xb18e3bf33365fd2466c2e99b181e527a165c210c"], + }, + templateConfig: { + step2CtaText: "Register to get your Ticket", + fields: [ + { + type: "short-text", + label: "Email", + isRequired: true, + }, + { + type: "short-text", + label: "Name or Pseudonym", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations!", + description: + "Tickets are processed on a first come first serve basis. You will receive an email update in a few days! See you there 💜", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "153c26qbdBFxgX1r9mKY7fx3krWPTFjKnYVMpYWEmRM0", + }, + saveAuths: true, + }, + }, + options: { + isFeatured: true, + endDate: new Date("2023-07-19T18:00Z"), + }, + }, + { + type: "zkForm", + metadata: { + name: "app test number 3", + slug: "ethcc-tickets", + description: + "Register your email address to receive exclusive tickets for web3 events - open to contributors to The leo.", + tags: ["Event"], + image: "EthCCtickets_1014x720px.png", + createdAt: new Date("2022-07-01T00:00:00.000Z"), + }, + sismoConnectRequest: { + appId: "0x0000000000000000000000000000000000000002", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [{ groupId: "0x42c768bb8ae79e4c5c05d3b51a4ec74a" }], + }, + templateConfig: { + step2CtaText: "Register to get tickets", + fields: [ + { + type: "short-text", + label: "First name", + isRequired: true, + }, + { + type: "short-text", + label: "Last name", + isRequired: true, + }, + { + type: "short-text", + label: "Email", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations", + description: + "You have successfully registered to receive exclusive tickets for web3 events.", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "1Wrh8gFPWuUfdip1wuOxBx_0bZQ_OJb2JsI5A-loRa-Y", + }, + }, + }, + options: { + isFeatured: true, + }, + }, + { + type: "zkForm", + metadata: { + name: "app test number 4", + slug: "ethcc-tickets", + description: + "Register your email address to receive exclusive tickets for web3 events - open to contributors to The leo.", + tags: ["Event"], + image: "EthCCtickets_1014x720px.png", + createdAt: new Date("2022-07-01T00:00:00.000Z"), + }, + sismoConnectRequest: { + appId: "0x0000000000000000000000000000000000000003", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [{ groupId: "0x42c768bb8ae79e4c5c05d3b51a4ec74a" }], + }, + templateConfig: { + step2CtaText: "Register to get tickets", + fields: [ + { + type: "short-text", + label: "First name", + isRequired: true, + }, + { + type: "short-text", + label: "Last name", + isRequired: true, + }, + { + type: "short-text", + label: "Email", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations", + description: + "You have successfully registered to receive exclusive tickets for web3 events.", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "1Wrh8gFPWuUfdip1wuOxBx_0bZQ_OJb2JsI5A-loRa-Y", + }, + }, + }, + options: { + isFeatured: true, + }, + }, + { + type: "zkForm", + metadata: { + slug: "event", + name: "Cow Event Invitation", + description: + "Prove you are a Cow Trader or Holder to register to an invitation-only event organized by Cow Swap, during EthCC week in Paris.", + tags: ["Event", "Ticket"], + image: "cowswap_app_store_cow_event_400x400.png", + createdAt: new Date("2023-07-04T18:00"), + }, + sismoConnectRequest: { + appId: "0x42bf819b60a7f4cbe57f2c5617b6a35c", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [ + { + groupId: "0x70c30e9a9abdb5fd41ba9e9cb7f50173", + value: 1, + }, + ], + impersonateAddresses: ["0xb18e3bf33365fd2466c2e99b181e527a165c210c"], + }, + templateConfig: { + step2CtaText: "Register to get your Ticket", + fields: [ + { + type: "short-text", + label: "Email", + isRequired: true, + }, + { + type: "short-text", + label: "Name or Pseudonym", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations!", + description: + "Tickets are processed on a first come first serve basis. You will receive an email update in a few days! See you there 💜", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "153c26qbdBFxgX1r9mKY7fx3krWPTFjKnYVMpYWEmRM0", + }, + saveAuths: true, + }, + }, + options: { + isFeatured: true, + endDate: new Date("2023-07-19T18:00Z"), + }, + }, + ], +}; diff --git a/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test.ts b/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test.ts new file mode 100644 index 00000000..67e25113 --- /dev/null +++ b/src/scripts/sync-apps-factory/test-configs/sync-apps-config-test.ts @@ -0,0 +1,276 @@ +// add an images folder in your space folder if you would like Sismo to host your images + +import { AuthType } from "@sismo-core/sismo-connect-client"; +import { SpaceConfig } from "../../../../space-configs/types"; + +export const syncAppsConfigTest: SpaceConfig = { + metadata: { + name: "The leo Contributors", + slug: "sync-apps-config-test", + description: "Tribute to contributors to the Ethereum leo.", + image: "pfp_Space_TheMergeContributors_400x400.png", + }, + apps: [ + { + type: "zkForm", + metadata: { + name: "app test number 1", + slug: "ethcc-tickets", + description: + "Register your email address to receive exclusive tickets for web3 events - open to contributors to The leo.", + tags: ["Event"], + image: "EthCCtickets_1014x720px.png", + createdAt: new Date("2022-07-01T00:00:00.000Z"), + }, + sismoConnectRequest: { + appId: "{{ auto-fill }}", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [{ groupId: "0x42c768bb8ae79e4c5c05d3b51a4ec74a" }], + }, + templateConfig: { + step2CtaText: "Register to get tickets", + fields: [ + { + type: "short-text", + label: "First name", + isRequired: true, + }, + { + type: "short-text", + label: "Last name", + isRequired: true, + }, + { + type: "short-text", + label: "Email", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations", + description: + "You have successfully registered to receive exclusive tickets for web3 events.", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "1Wrh8gFPWuUfdip1wuOxBx_0bZQ_OJb2JsI5A-loRa-Y", + }, + }, + }, + options: { + isFeatured: true, + }, + }, + { + type: "zkForm", + metadata: { + slug: "event", + name: "app test number 2", + description: + "Prove you are a Cow Trader or Holder to register to an invitation-only event organized by Cow Swap, during EthCC week in Paris.", + tags: ["Event", "Ticket"], + image: "cowswap_app_store_cow_event_400x400.png", + createdAt: new Date("2023-07-04T18:00"), + }, + sismoConnectRequest: { + appId: "0x42bf819b60a7f4cbe57f2c5617b6a35c", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [ + { + groupId: "0x70c30e9a9abdb5fd41ba9e9cb7f50173", + value: 1, + }, + ], + impersonateAddresses: ["0xb18e3bf33365fd2466c2e99b181e527a165c210c"], + }, + templateConfig: { + step2CtaText: "Register to get your Ticket", + fields: [ + { + type: "short-text", + label: "Email", + isRequired: true, + }, + { + type: "short-text", + label: "Name or Pseudonym", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations!", + description: + "Tickets are processed on a first come first serve basis. You will receive an email update in a few days! See you there 💜", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "153c26qbdBFxgX1r9mKY7fx3krWPTFjKnYVMpYWEmRM0", + }, + saveAuths: true, + }, + }, + options: { + isFeatured: true, + endDate: new Date("2023-07-19T18:00Z"), + }, + }, + { + type: "zkForm", + metadata: { + name: "app test number 3", + slug: "ethcc-tickets", + description: + "Register your email address to receive exclusive tickets for web3 events - open to contributors to The leo.", + tags: ["Event"], + image: "EthCCtickets_1014x720px.png", + createdAt: new Date("2022-07-01T00:00:00.000Z"), + }, + sismoConnectRequest: { + appId: "{{ auto-fill }}", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [{ groupId: "0x42c768bb8ae79e4c5c05d3b51a4ec74a" }], + }, + templateConfig: { + step2CtaText: "Register to get tickets", + fields: [ + { + type: "short-text", + label: "First name", + isRequired: true, + }, + { + type: "short-text", + label: "Last name", + isRequired: true, + }, + { + type: "short-text", + label: "Email", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations", + description: + "You have successfully registered to receive exclusive tickets for web3 events.", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "1Wrh8gFPWuUfdip1wuOxBx_0bZQ_OJb2JsI5A-loRa-Y", + }, + }, + }, + options: { + isFeatured: true, + }, + }, + { + type: "zkForm", + metadata: { + name: "app test number 4", + slug: "ethcc-tickets", + description: + "Register your email address to receive exclusive tickets for web3 events - open to contributors to The leo.", + tags: ["Event"], + image: "EthCCtickets_1014x720px.png", + createdAt: new Date("2022-07-01T00:00:00.000Z"), + }, + sismoConnectRequest: { + appId: "{{ auto-fill }}", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [{ groupId: "0x42c768bb8ae79e4c5c05d3b51a4ec74a" }], + }, + templateConfig: { + step2CtaText: "Register to get tickets", + fields: [ + { + type: "short-text", + label: "First name", + isRequired: true, + }, + { + type: "short-text", + label: "Last name", + isRequired: true, + }, + { + type: "short-text", + label: "Email", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations", + description: + "You have successfully registered to receive exclusive tickets for web3 events.", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "1Wrh8gFPWuUfdip1wuOxBx_0bZQ_OJb2JsI5A-loRa-Y", + }, + }, + }, + options: { + isFeatured: true, + }, + }, + { + type: "zkForm", + metadata: { + slug: "event", + name: "Cow Event Invitation", + description: + "Prove you are a Cow Trader or Holder to register to an invitation-only event organized by Cow Swap, during EthCC week in Paris.", + tags: ["Event", "Ticket"], + image: "cowswap_app_store_cow_event_400x400.png", + createdAt: new Date("2023-07-04T18:00"), + }, + sismoConnectRequest: { + appId: "0x42bf819b60a7f4cbe57f2c5617b6a35c", + authRequests: [{ authType: AuthType.VAULT }], + claimRequests: [ + { + groupId: "0x70c30e9a9abdb5fd41ba9e9cb7f50173", + value: 1, + }, + ], + impersonateAddresses: ["0xb18e3bf33365fd2466c2e99b181e527a165c210c"], + }, + templateConfig: { + step2CtaText: "Register to get your Ticket", + fields: [ + { + type: "short-text", + label: "Email", + isRequired: true, + }, + { + type: "short-text", + label: "Name or Pseudonym", + isRequired: true, + }, + ], + congratulationsMessage: { + title: "Congratulations!", + description: + "Tickets are processed on a first come first serve basis. You will receive an email update in a few days! See you there 💜", + }, + output: { + destination: { + type: "google_sheet", + spreadsheetId: "153c26qbdBFxgX1r9mKY7fx3krWPTFjKnYVMpYWEmRM0", + }, + saveAuths: true, + }, + }, + options: { + isFeatured: true, + endDate: new Date("2023-07-19T18:00Z"), + }, + }, + ], +}; diff --git a/src/services/service-factory/service-factory.ts b/src/services/service-factory/service-factory.ts index d14de675..223ce178 100644 --- a/src/services/service-factory/service-factory.ts +++ b/src/services/service-factory/service-factory.ts @@ -1,4 +1,5 @@ -import { configsDemo, configsMain } from "@/space-configs"; +import configsDemo from "@/.space-configs/demo.json"; +import configsMain from "@/.space-configs/main.json"; import { SpaceConfig } from "@/space-configs/types"; import { mockZkFormTestSpaceType } from "@/src/app/api/zk-form/mocks"; import { mockTelegramTestSpaceType } from "@/src/app/api/zk-telegram-bot/mocks"; @@ -6,6 +7,11 @@ import env from "@/src/environments"; import { LoggerService } from "@/src/services/logger-service/logger-service"; import { MemoryLogger } from "@/src/services/logger-service/memory-logger-service"; import { StdoutLogger } from "@/src/services/logger-service/stdout-logger-service"; +import { + SismoFactoryMemoryService, + SismoFactoryService, +} from "@/src/services/sismo-factory-service"; +import { SismoFactoryAPIService } from "@/src/services/sismo-factory-service/sismo-factory-api"; import { GoogleSpreadsheetStore, MemoryTableStore, TableStore } from "@/src/services/table-store"; import { MockedTelegramBotService } from "@/src/services/telegram-bot-service/mocked-telegram-bot-service"; import { TelegramAPIBotService } from "@/src/services/telegram-bot-service/telegram-api-bot-service"; @@ -20,6 +26,7 @@ let zkFormTableStore: TableStore; let telegramBotService: TelegramBotInterface; let configService: SpaceConfig[]; let loggerService: LoggerService; +let sismoFactoryService: SismoFactoryService; const ServiceFactory = { getZkTelegramBotUserStore: (customUserStore?: UserStore): UserStore => { @@ -78,21 +85,35 @@ const ServiceFactory = { } if (!configService) { if (env.isDemo) { - configService = configsDemo; + configService = configsDemo as any as SpaceConfig[]; } else if (env.isMain) { - configService = configsMain; + configService = configsMain as any as SpaceConfig[]; } else if (env.isTest) { configService = [mockTelegramTestSpaceType(), mockZkFormTestSpaceType()]; } } return configService; }, + getSismoFactoryService: (): SismoFactoryService => { + if (!sismoFactoryService) { + if (env.isTest) { + sismoFactoryService = new SismoFactoryMemoryService(); + } else { + sismoFactoryService = new SismoFactoryAPIService({ + url: process.env.SISMO_FACTORY_URL, + token: process.env.SISMO_FACTORY_TOKEN, + }); + } + } + return sismoFactoryService; + }, reset: (): void => { configService = null; zkTelegramBotUserStore = null; telegramBotService = null; loggerService = null; zkFormTableStore = null; + sismoFactoryService = null; }, }; diff --git a/src/services/sismo-factory-service/index.ts b/src/services/sismo-factory-service/index.ts new file mode 100644 index 00000000..687f857a --- /dev/null +++ b/src/services/sismo-factory-service/index.ts @@ -0,0 +1,2 @@ +export * from "./sismo-factory"; +export * from "./sismo-factory-memory"; diff --git a/src/services/sismo-factory-service/sismo-factory-api.ts b/src/services/sismo-factory-service/sismo-factory-api.ts new file mode 100644 index 00000000..f8c6fbed --- /dev/null +++ b/src/services/sismo-factory-service/sismo-factory-api.ts @@ -0,0 +1,53 @@ +import { + SismoConnectApp, + SismoConnectAppInput, + SismoFactoryService, +} from "@/src/services/sismo-factory-service/sismo-factory"; +import axios from "axios"; + +export class SismoFactoryAPIService extends SismoFactoryService { + private _url: string; + private _token: string; + + constructor({ url, token }: { url: string; token: string }) { + super(); + this._url = url; + this._token = token; + } + + protected async _create(app: SismoConnectAppInput): Promise { + const res = await axios.post( + `${this._url}/apps/create`, + { appInput: app }, + { + headers: this._getHeaders(), + } + ); + return res.data; + } + + protected async _update(appId: string, app: SismoConnectApp): Promise { + const res = await axios.put( + `${this._url}/apps/${appId}`, + { app }, + { + headers: this._getHeaders(), + } + ); + return res.data; + } + + async getApps(): Promise { + const res = await axios.get(`${this._url}/apps`, { + headers: this._getHeaders(), + }); + return res.data; + } + + private _getHeaders(): { [key: string]: string } { + return { + "Content-Type": "application/json", + Authorization: `Bearer ${this._token}`, + }; + } +} diff --git a/src/services/sismo-factory-service/sismo-factory-memory.ts b/src/services/sismo-factory-service/sismo-factory-memory.ts new file mode 100644 index 00000000..5cd335d3 --- /dev/null +++ b/src/services/sismo-factory-service/sismo-factory-memory.ts @@ -0,0 +1,33 @@ +import { + SismoConnectApp, + SismoConnectAppInput, + SismoFactoryService, +} from "@/src/services/sismo-factory-service/sismo-factory"; + +export class SismoFactoryMemoryService extends SismoFactoryService { + private _apps: { [appId: string]: SismoConnectApp } = {}; + + protected async _create(app: SismoConnectAppInput): Promise { + const appId = `0x${(Object.keys(this._apps).length + 1).toString().padStart(40, "0")}`; + const newApp: SismoConnectApp = { + ...app, + id: appId, + createdAt: Date.now(), + lastUpdatedAt: Date.now(), + logoUrl: "", + }; + this._apps[appId] = newApp; + return newApp; + } + + protected async _update(appId: string, app: SismoConnectApp): Promise { + const existingApp = this._apps[appId]; + if (!existingApp) throw new Error("App not found"); + this._apps[app.id] = app; + return this._apps[app.id]; + } + + async getApps(): Promise { + return Object.values(this._apps); + } +} diff --git a/src/services/sismo-factory-service/sismo-factory.ts b/src/services/sismo-factory-service/sismo-factory.ts new file mode 100644 index 00000000..562ac727 --- /dev/null +++ b/src/services/sismo-factory-service/sismo-factory.ts @@ -0,0 +1,45 @@ +export type SismoConnectBaseApp = { + name: string; + description: string; + logoBase64?: string; // png in BASE64 format +}; + +export type SismoConnectAppCommon = { + authorizedDomains: string[]; + creatorId: string; +}; + +export type SismoConnectAppInput = SismoConnectBaseApp & SismoConnectAppCommon; + +export type SismoConnectApp = SismoConnectAppInput & { + id: string; + createdAt: number; + lastUpdatedAt: number; + logoUrl: string; + authorizedDomains: string[]; + creatorId?: string; +}; + +export abstract class SismoFactoryService { + protected _commonParams: SismoConnectAppCommon = { + authorizedDomains: ["*.sismo.io", "*sismo.vercel.app"], // vercel is used to test preview deployment + creatorId: "0x5151110000000000000000000000000000000001", // service account used by the sismo app store + }; + + public createApp(app: SismoConnectBaseApp): Promise { + return this._create({ + ...this._commonParams, + ...app, + }); + } + public updateApp(appId: string, app: SismoConnectBaseApp): Promise { + return this._update(appId, { + ...this._commonParams, + ...app, + }); + } + + abstract getApps(): Promise; + protected abstract _create(app: SismoConnectAppInput): Promise; + protected abstract _update(appId: string, app: SismoConnectAppInput): Promise; +} diff --git a/src/services/user-store/postgres-user-store/Entities/user.entity.ts b/src/services/user-store/postgres-user-store/Entities/user.entity.ts index 1b85228b..c4c51154 100644 --- a/src/services/user-store/postgres-user-store/Entities/user.entity.ts +++ b/src/services/user-store/postgres-user-store/Entities/user.entity.ts @@ -1,14 +1,14 @@ -import { Entity, Column, PrimaryGeneratedColumn, Unique } from "typeorm" +import { Entity, Column, PrimaryGeneratedColumn, Unique } from "typeorm"; @Entity("zk-telegram-bot") @Unique(["userId", "appSlug"]) export class UserEntity { - @PrimaryGeneratedColumn() - id: number + @PrimaryGeneratedColumn() + id: number; - @Column() - userId: string + @Column("text") + userId: string; - @Column() - appSlug: string -} \ No newline at end of file + @Column("text") + appSlug: string; +} diff --git a/src/services/user-store/postgres-user-store/index.ts b/src/services/user-store/postgres-user-store/index.ts index 814615d8..846461e8 100644 --- a/src/services/user-store/postgres-user-store/index.ts +++ b/src/services/user-store/postgres-user-store/index.ts @@ -1,9 +1,9 @@ +import "reflect-metadata"; import { UserStore } from "../store"; import { User } from "../user"; import { UserEntity } from "./Entities/user.entity"; import { initAppDataSource } from "./initAppDataSource"; import { DataSource } from "typeorm"; -import "reflect-metadata"; export class PostgresUserStore extends UserStore { private appDataSource: DataSource; diff --git a/svgMock.js b/svgMock.js new file mode 100644 index 00000000..51b79eca --- /dev/null +++ b/svgMock.js @@ -0,0 +1,4 @@ +// do not delete this file, used to run script with tsx +require.extensions['.svg'] = function () { + return ''; +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 27564432..3af05a22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1051,6 +1051,140 @@ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== +"@esbuild-kit/cjs-loader@^2.4.2": + version "2.4.2" + resolved "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz#cb4dde00fbf744a68c4f20162ea15a8242d0fa54" + integrity sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg== + dependencies: + "@esbuild-kit/core-utils" "^3.0.0" + get-tsconfig "^4.4.0" + +"@esbuild-kit/core-utils@^3.0.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.1.0.tgz#49945d533dbd5e1b7620aa0fc522c15e6ec089c5" + integrity sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw== + dependencies: + esbuild "~0.17.6" + source-map-support "^0.5.21" + +"@esbuild-kit/esm-loader@^2.5.5": + version "2.5.5" + resolved "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.5.tgz#b82da14fcee3fc1d219869756c06f43f67d1ca71" + integrity sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw== + dependencies: + "@esbuild-kit/core-utils" "^3.0.0" + get-tsconfig "^4.4.0" + +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -2268,6 +2402,11 @@ abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== +abbrev@1: + version "1.1.1" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + abitype@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.8.2.tgz#cacd330d07488a4020d84f54fc361361234b9c83" @@ -2853,7 +2992,7 @@ check-types@^11.1.1: resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4" integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA== -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.0: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.0, chokidar@^3.5.2: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3444,6 +3583,34 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@~0.17.6: + version "0.17.19" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== + optionalDependencies: + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -4013,6 +4180,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.4.0: + version "4.6.2" + resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz#831879a5e6c2aa24fe79b60340e2233a1e0f472e" + integrity sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg== + dependencies: + resolve-pkg-maps "^1.0.0" + get-tsconfig@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" @@ -4313,6 +4487,11 @@ ieee754@^1.1.13, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + ignore@^5.2.0: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" @@ -5520,6 +5699,29 @@ node-releases@^2.0.8: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +nodemon@^2.0.22: + version "2.0.22" + resolved "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" + integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -5993,6 +6195,11 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -6111,7 +6318,7 @@ redent@^3.0.0: reflect-metadata@^0.1.13: version "0.1.13" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== regenerate-unicode-properties@^10.1.0: @@ -6193,6 +6400,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -6296,7 +6508,7 @@ semver@7.x, semver@^7.3.5, semver@^7.3.7: dependencies: lru-cache "^6.0.0" -semver@^5.6.0: +semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -6313,6 +6525,11 @@ semver@^7.5.0: dependencies: lru-cache "^6.0.0" +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + server-destroy@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" @@ -6397,6 +6614,13 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +simple-update-notifier@^1.0.7: + version "1.1.0" + resolved "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== + dependencies: + semver "~7.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -6454,6 +6678,14 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@^0.5.21: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -6630,7 +6862,7 @@ stylis@^4.2.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== -supports-color@^5.3.0: +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -6745,6 +6977,13 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + tough-cookie@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" @@ -6832,6 +7071,17 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsx@^3.12.7: + version "3.12.7" + resolved "https://registry.npmjs.org/tsx/-/tsx-3.12.7.tgz#b3b8b0fc79afc8260d1e14f9e995616c859a91e9" + integrity sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw== + dependencies: + "@esbuild-kit/cjs-loader" "^2.4.2" + "@esbuild-kit/core-utils" "^3.0.0" + "@esbuild-kit/esm-loader" "^2.5.5" + optionalDependencies: + fsevents "~2.3.2" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -6913,6 +7163,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"