mirror of
https://github.com/LukeHagar/idn-admin-console.git
synced 2025-12-06 04:20:02 +00:00
Initial commit
This commit is contained in:
32
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve.
|
||||
title: "[BUG] Your Bug Report Here"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Operating System (please complete the following information):**
|
||||
- OS: [e.g. Windows 10 19044.1889, Ubuntu 18.04, Mac OS Monterey 12.4]
|
||||
- CLI Environment [e.g. Command Prompt, Powershell, Terminal]
|
||||
- Version [e.g. 1.04]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project.
|
||||
title: "[FEATURE] Your Feature Request Here "
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like.**
|
||||
A clear and concise description of what you want to happen. Ex. It would be nice if [...]
|
||||
|
||||
**Describe alternatives you've considered.**
|
||||
A clear and concise description of any alternative solutions or features you've considered. Ex. I have seen similar features on [...]
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
16
.github/workflows/greetings.yml
vendored
Normal file
16
.github/workflows/greetings.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Greetings
|
||||
|
||||
on: [pull_request_target, issues]
|
||||
|
||||
jobs:
|
||||
greeting:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: "🎉 Thanks for opening your first issue here! Welcome to the community!"
|
||||
pr-message: "🎉 Thanks for opening this pull request! We really appreciate contributors like you! 🙌"
|
||||
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
node_modules
|
||||
.svelte-kit
|
||||
|
||||
dist
|
||||
build
|
||||
package
|
||||
|
||||
.env
|
||||
.env.*
|
||||
*.local
|
||||
!.env.example
|
||||
|
||||
yarn-error.log
|
||||
pnpm-lock.yaml
|
||||
|
||||
.DS_Store
|
||||
12
.prettierrc
Normal file
12
.prettierrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"svelteSortOrder": "scripts-markup-styles",
|
||||
"htmlWhitespaceSensitivity": "ignore",
|
||||
"trailingComma": "all",
|
||||
"requirePragma": false,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"useTabs": true,
|
||||
"tabWidth": 4,
|
||||
"semi": true
|
||||
}
|
||||
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["svelte.svelte-vscode"]
|
||||
}
|
||||
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"[svelte]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "svelte.svelte-vscode"
|
||||
}
|
||||
}
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Braden Wiggins and contributors: https://github.com/fractalhq/sveltekit-electron/graphs/contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 SailPoint
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
153
README.md
Normal file
153
README.md
Normal file
@@ -0,0 +1,153 @@
|
||||
<a id="readme-top"></a>
|
||||
|
||||
## How to use this template
|
||||
|
||||
Update sheild urls
|
||||
|
||||
* Update url for discourse, downloads, issues, current release, and contributors
|
||||
|
||||
Project title and logo
|
||||
|
||||
* Update project title and description
|
||||
* Update project logo
|
||||
* Update link to point to documentation about this project
|
||||
|
||||
About the project
|
||||
|
||||
* Update project screenshot
|
||||
* Update the paragraph with what your project is meant to accomplish
|
||||
|
||||
Getting started
|
||||
|
||||
* Describe how to get started with your project
|
||||
* Describe any prerequisites needed to run your project
|
||||
* Describe how to install and run your project
|
||||
|
||||
Discuss
|
||||
|
||||
* Create a tag in our discourse forum for your project
|
||||
* Update link in this section to point to the newly created tag
|
||||
|
||||
After these steps are complete remove this checklist!
|
||||
|
||||
[![Discourse Topics][discourse-shield]][discourse-url]
|
||||
![Times Downloaded][downloads-shield]
|
||||
![Issues][issues-shield]
|
||||
![Latest Releases][release-shield]
|
||||
![Contributor Shield][contributor-shield]
|
||||
|
||||
[discourse-shield]: https://img.shields.io/discourse/topics?label=Discuss%20This%20Tool&server=https%3A%2F%2Fdeveloper.sailpoint.com%2Fdiscuss
|
||||
[discourse-url]: https://developer.sailpoint.com/discuss/tag/workflows
|
||||
[downloads-shield]: https://img.shields.io/github/downloads/sailpoint-oss/api-linter/total?label=Downloads
|
||||
[issues-shield]:https://img.shields.io/github/issues/sailpoint-oss/api-linter?label=Issues
|
||||
[release-shield]: https://img.shields.io/github/v/release/sailpoint-oss/api-linter?label=Current%20Release
|
||||
[contributor-shield]:https://img.shields.io/github/contributors/sailpoint-oss/api-linter?label=Contributors
|
||||
|
||||
[product-screenshot]: ./assets/images/api-linter-output.png
|
||||
|
||||
<!-- PROJECT LOGO -->
|
||||
<br />
|
||||
<div align="center">
|
||||
<a href="https://github.com/othneildrew/Best-README-Template">
|
||||
<img src="https://avatars.githubusercontent.com/u/63106368?s=200&v=4" alt="Logo" width="80" height="80">
|
||||
</a>
|
||||
|
||||
<h3 align="center">SailPoint OSS - README - Template</h3>
|
||||
|
||||
<p align="center">
|
||||
An awesome README template to jumpstart your projects!
|
||||
<br />
|
||||
<a href="https://github.com/othneildrew/Best-README-Template"><strong>Explore the docs »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<!-- <a href="https://github.com/sailpoint/repo-template">View Demo</a>
|
||||
·
|
||||
<a href="https://github.com/sailpoint-oss/repo-template/issues">Report Bug</a>
|
||||
·
|
||||
<a href="https://github.com/sailpoint-oss/repo-template/issueschoose">Request Feature</a> -->
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- ABOUT THE PROJECT -->
|
||||
## About The Project
|
||||
|
||||
<div align="center">
|
||||
<img src="./assets/images/api-linter-output.png" width="500" height="" style="text-align:center">
|
||||
</div>
|
||||
|
||||
There are many great README templates available on GitHub; however, I didn't find one that really suited my needs so I created this enhanced one. I want to create a README template so amazing that it'll be the last one you ever need -- I think this is it.
|
||||
|
||||
Here's why:
|
||||
* Your time should be focused on creating something amazing. A project that solves a problem and helps others
|
||||
* You shouldn't be doing the same tasks over and over like creating a README from scratch
|
||||
* You should implement DRY principles to the rest of your life :smile:
|
||||
|
||||
Of course, no one template will serve all projects since your needs may be different. So I'll be adding more in the near future. You may also suggest changes by forking this repo and creating a pull request or opening an issue. Thanks to all the people have contributed to expanding this template!
|
||||
|
||||
Use the `BLANK_README.md` to get started.
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
<!-- GETTING STARTED -->
|
||||
## Getting Started
|
||||
|
||||
This is an example of how you may give instructions on setting up your project locally.
|
||||
To get a local copy up and running follow these simple example steps.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
This is an example of how to list things you need to use the software and how to install them.
|
||||
* npm
|
||||
```sh
|
||||
npm install npm@latest -g
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
_Below is an example of how you can instruct your audience on installing and setting up your app. This template doesn't rely on any external dependencies or services._
|
||||
|
||||
1. Get a free API Key at [https://example.com](https://example.com)
|
||||
2. Clone the repo
|
||||
```sh
|
||||
git clone https://github.com/your_username_/Project-Name.git
|
||||
```
|
||||
3. Install NPM packages
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
4. Enter your API in `config.js`
|
||||
```js
|
||||
const API_KEY = 'ENTER YOUR API';
|
||||
```
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
|
||||
<!-- CONTRIBUTING -->
|
||||
## Contributing
|
||||
|
||||
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
||||
|
||||
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag `enhancement`.
|
||||
Don't forget to give the project a star! Thanks again!
|
||||
|
||||
1. Fork the Project
|
||||
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
|
||||
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
|
||||
4. Push to the Branch (`git push origin feature/AmazingFeature`)
|
||||
5. Open a Pull Request
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
<!-- LICENSE -->
|
||||
## License
|
||||
|
||||
Distributed under the MIT License. See `LICENSE.txt` for more information.
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
<!-- CONTACT -->
|
||||
## Discuss
|
||||
[Click Here](https://developer.sailpoint.com/dicuss/tag/{tagName}) to discuss this tool with other users.
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
BIN
assets/images/api-linter-output.png
Normal file
BIN
assets/images/api-linter-output.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 432 KiB |
15
build.config.json
Normal file
15
build.config.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"appId": "com.example.app",
|
||||
"productName": "Sveltekit Electron",
|
||||
"directories": {
|
||||
"output": "dist"
|
||||
},
|
||||
"files": [
|
||||
"src/electron.cjs",
|
||||
"src/preload.cjs",
|
||||
{
|
||||
"from": "build",
|
||||
"to": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
2
globals.d.ts
vendored
Normal file
2
globals.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="svelte" />
|
||||
/// <reference types="vite/client" />
|
||||
11
jsconfig.json
Normal file
11
jsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"$lib": ["src/lib"],
|
||||
"$lib/*": ["src/lib/*"],
|
||||
"/~/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "build", "dist"]
|
||||
}
|
||||
14113
package-lock.json
generated
Normal file
14113
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
75
package.json
Normal file
75
package.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "sveltekit-electron",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"description": "Minimal Sveltekit + Electron starter template.",
|
||||
"main": "src/electron.cjs",
|
||||
"type": "module",
|
||||
"author": "Braden Wiggins",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=dev npm run dev:all",
|
||||
"dev:all": "concurrently -n=svelte,electron -c='#ff3e00',blue \"npm run dev:svelte\" \"npm run dev:electron\"",
|
||||
"dev:svelte": "vite dev",
|
||||
"dev:electron": "electron src/electron.cjs",
|
||||
"build": "cross-env NODE_ENV=production npm run build:svelte && npm run build:electron",
|
||||
"build:svelte": "vite build",
|
||||
"build:electron": "electron-builder -mwl --config build.config.json"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=7",
|
||||
"yarn": "use npm - https://github.com/FractalHQ/sveltekit-electron/issues/12#issuecomment-1068399385"
|
||||
},
|
||||
"browserslist": [
|
||||
"Chrome 89"
|
||||
],
|
||||
"dependencies": {
|
||||
"electron-context-menu": "^3.6.1",
|
||||
"electron-reloader": "^1.2.3",
|
||||
"electron-serve": "^1.1.0",
|
||||
"electron-window-state": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@skeletonlabs/skeleton": "^2.1.0",
|
||||
"@skeletonlabs/tw-plugin": "^0.2.0",
|
||||
"@sveltejs/adapter-static": "2.0.1",
|
||||
"@sveltejs/kit": "1.14.0",
|
||||
"@types/jsonwebtoken": "^9.0.3",
|
||||
"@types/node": "^20.6.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
||||
"@typescript-eslint/parser": "^5.56.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"alasql": "^4.1.9",
|
||||
"axios": "^1.5.0",
|
||||
"concurrently": "^7.6.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"electron": "^23.2.0",
|
||||
"electron-builder": "^23.6.0",
|
||||
"electron-connect": "^0.6.3",
|
||||
"electron-packager": "^17.1.1",
|
||||
"electron-updater": "^5.3.0",
|
||||
"eslint": "^8.36.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-svelte": "^2.10.0",
|
||||
"sailpoint-api-client": "^1.2.2",
|
||||
"sass": "^1.60.0",
|
||||
"svelte": "^3.57.0",
|
||||
"svelte-check": "^3.1.4",
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tslib": "^2.5.0",
|
||||
"typescript": "^4.9.4",
|
||||
"vite": "^4.0.4"
|
||||
},
|
||||
"overrides": {
|
||||
"electron": {
|
||||
"got": "^12.5.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
13
postcss.config.cjs
Normal file
13
postcss.config.cjs
Normal file
@@ -0,0 +1,13 @@
|
||||
const tailwindcss = require('tailwindcss');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
|
||||
const config = {
|
||||
plugins: [
|
||||
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
|
||||
tailwindcss(),
|
||||
//But others, like autoprefixer, need to run after,
|
||||
autoprefixer,
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
13
src/app.html
Normal file
13
src/app.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Sveltekit + Electron yeah</title>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-theme="wintry">
|
||||
<div id="svelte">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
8
src/app.postcss
Normal file
8
src/app.postcss
Normal file
@@ -0,0 +1,8 @@
|
||||
/* Write your global styles here, in PostCSS syntax */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
:root [data-theme='wintry'] {
|
||||
--theme-rounded-base: 5px;
|
||||
--theme-rounded-container: 4px;
|
||||
}
|
||||
104
src/electron.cjs
Normal file
104
src/electron.cjs
Normal file
@@ -0,0 +1,104 @@
|
||||
const windowStateManager = require('electron-window-state');
|
||||
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||
const contextMenu = require('electron-context-menu');
|
||||
const serve = require('electron-serve');
|
||||
const path = require('path');
|
||||
|
||||
try {
|
||||
require('electron-reloader')(module);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
const serveURL = serve({ directory: '.' });
|
||||
const port = process.env.PORT || 3000;
|
||||
const dev = !app.isPackaged;
|
||||
let mainWindow;
|
||||
|
||||
function createWindow() {
|
||||
let windowState = windowStateManager({
|
||||
defaultWidth: 800,
|
||||
defaultHeight: 600,
|
||||
});
|
||||
|
||||
const mainWindow = new BrowserWindow({
|
||||
backgroundColor: 'whitesmoke',
|
||||
titleBarStyle: 'visible',
|
||||
autoHideMenuBar: false,
|
||||
trafficLightPosition: {
|
||||
x: 17,
|
||||
y: 32,
|
||||
},
|
||||
minHeight: 450,
|
||||
minWidth: 500,
|
||||
webPreferences: {
|
||||
enableRemoteModule: true,
|
||||
contextIsolation: true,
|
||||
nodeIntegration: true,
|
||||
spellcheck: false,
|
||||
devTools: dev,
|
||||
preload: path.join(__dirname, 'preload.cjs'),
|
||||
},
|
||||
x: windowState.x,
|
||||
y: windowState.y,
|
||||
width: windowState.width,
|
||||
height: windowState.height,
|
||||
});
|
||||
|
||||
windowState.manage(mainWindow);
|
||||
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
});
|
||||
|
||||
mainWindow.on('close', () => {
|
||||
windowState.saveState(mainWindow);
|
||||
});
|
||||
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
contextMenu({
|
||||
showLookUpSelection: false,
|
||||
showSearchWithGoogle: false,
|
||||
showCopyImage: false,
|
||||
prepend: (defaultActions, params, browserWindow) => [
|
||||
{
|
||||
label: 'Make App 💻',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
function loadVite(port) {
|
||||
mainWindow.loadURL(`http://localhost:${port}`).catch((e) => {
|
||||
console.log('Error loading URL, retrying', e);
|
||||
setTimeout(() => {
|
||||
loadVite(port);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
|
||||
function createMainWindow() {
|
||||
mainWindow = createWindow();
|
||||
mainWindow.once('close', () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
|
||||
if (dev) loadVite(port);
|
||||
else serveURL(mainWindow);
|
||||
}
|
||||
|
||||
app.once('ready', createMainWindow);
|
||||
app.on('activate', () => {
|
||||
if (!mainWindow) {
|
||||
createMainWindow();
|
||||
}
|
||||
});
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit();
|
||||
});
|
||||
|
||||
ipcMain.on('to-main', (event, count) => {
|
||||
return mainWindow.webContents.send('from-main', `next counts is ${count + 1}`);
|
||||
});
|
||||
6
src/global.d.ts
vendored
Normal file
6
src/global.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/// <reference types="@sveltejs/kit" />
|
||||
/// <reference types="svelte" />
|
||||
/// <reference types="vite/client" />
|
||||
declare interface Window {
|
||||
electron: any;
|
||||
}
|
||||
110
src/lib/AnimatedCounter.svelte
Normal file
110
src/lib/AnimatedCounter.svelte
Normal file
@@ -0,0 +1,110 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
/**
|
||||
* list of values to animate
|
||||
*/
|
||||
export let values: Array<string | number> = Array.from({ length: 100 }, (_, i) =>
|
||||
new String(i).padStart(3, '0'),
|
||||
);
|
||||
/**
|
||||
* counter interval between each step in milliseconds, defaults to `1000`
|
||||
*/
|
||||
export let interval = 1000;
|
||||
/**
|
||||
* counter interval for each transition in milliseconds, defaults to `700`
|
||||
*/
|
||||
export let transitionInterval = 700;
|
||||
/**
|
||||
* whether to start the counter immediately or wait for the `interval` to pass, defaults to `false`
|
||||
*/
|
||||
export let startImmediately = false;
|
||||
|
||||
/**
|
||||
* counter direction, can be `up` or `down` defaults to `down`
|
||||
*/
|
||||
export let direction: 'up' | 'down' = 'down';
|
||||
/**
|
||||
* whether to loop the counter animation after reaching the end of `values` array , defaults to `true`
|
||||
*/
|
||||
export let loop = true;
|
||||
/**
|
||||
* easing function to use, defaults to `cubic-bezier(1, 0, 0, 1)`
|
||||
*/
|
||||
export let ease = 'cubic-bezier(1, 0, 0, 1)';
|
||||
/**
|
||||
* setting to allow items in values to be displayed randomly
|
||||
*/
|
||||
export let random = false;
|
||||
/**
|
||||
* optional initial value to start the counter from
|
||||
*/
|
||||
export let initialValue: string | number | undefined = undefined;
|
||||
|
||||
$: contentValues = values.join('\n\n');
|
||||
$: intervalInMs = `${transitionInterval}ms`;
|
||||
|
||||
let index = direction === 'up' ? 0 : values.length - 1;
|
||||
let lastIndex = initialValue ? values.indexOf(initialValue) : index;
|
||||
|
||||
onMount(() => {
|
||||
// timer function
|
||||
const start = () => {
|
||||
index = lastIndex + (direction === 'up' ? 1 : -1);
|
||||
|
||||
// terminate if we looped through all values && loop is false
|
||||
if (!loop && (index === values.length - 1 || index === 0)) {
|
||||
clearInterval(timer);
|
||||
return;
|
||||
}
|
||||
// ensure index is in range
|
||||
if (loop && index === values.length) {
|
||||
index = 0;
|
||||
}
|
||||
if (loop && index === -1) {
|
||||
index = values.length - 1;
|
||||
}
|
||||
|
||||
if (random) {
|
||||
index = Math.floor(Math.random() * values.length);
|
||||
}
|
||||
|
||||
lastIndex = index;
|
||||
};
|
||||
|
||||
if (startImmediately) {
|
||||
start();
|
||||
}
|
||||
let timer = setInterval(start, interval);
|
||||
|
||||
return () => clearInterval(timer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<span class="sliding-text {$$props.class}">
|
||||
<span style="--index: {index}; --interval: {intervalInMs}; --ease:{ease}">
|
||||
<span>{contentValues}</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<style>
|
||||
.sliding-text {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
line-height: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
.sliding-text > span {
|
||||
height: 1em;
|
||||
display: inline-block;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.sliding-text > span > span {
|
||||
text-align: center;
|
||||
transition: all var(--interval) var(--ease);
|
||||
position: relative;
|
||||
height: 100%;
|
||||
white-space: pre;
|
||||
top: calc(var(--index) * -2em);
|
||||
}
|
||||
</style>
|
||||
41
src/lib/Counter.svelte
Normal file
41
src/lib/Counter.svelte
Normal file
@@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import { getStore } from '$lib/utils/hmr-stores';
|
||||
|
||||
export let id: string;
|
||||
export let agent: string;
|
||||
|
||||
const count = getStore(id, 0);
|
||||
|
||||
const handleClick = () => {
|
||||
$count += 1;
|
||||
};
|
||||
|
||||
$: if (window.electron) {
|
||||
window.electron.send('to-main', $count);
|
||||
}
|
||||
</script>
|
||||
|
||||
<button {id} on:click={handleClick}>
|
||||
Send Clicks to {agent}: {$count}
|
||||
</button>
|
||||
|
||||
<style>
|
||||
button {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
padding: 1em 2em;
|
||||
color: #ff3e00;
|
||||
background-color: rgba(255, 62, 0, 0.1);
|
||||
border-radius: 2em;
|
||||
border: 2px solid rgba(255, 62, 0, 0);
|
||||
outline: none;
|
||||
width: 200px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
button:focus {
|
||||
border: 2px solid #ff3e00;
|
||||
}
|
||||
button:active {
|
||||
background-color: rgba(255, 62, 0, 0.2);
|
||||
}
|
||||
</style>
|
||||
27
src/lib/Logo.svelte
Normal file
27
src/lib/Logo.svelte
Normal file
@@ -0,0 +1,27 @@
|
||||
<script>
|
||||
import { fly } from 'svelte/transition';
|
||||
import { onMount } from 'svelte';
|
||||
let visible = false;
|
||||
onMount(() => (visible = true));
|
||||
</script>
|
||||
|
||||
<center class="py-10">
|
||||
{#if visible}
|
||||
<img
|
||||
src="/sveltekit-electron.svg"
|
||||
alt="Svelte Logo"
|
||||
draggable="false"
|
||||
in:fly={{ y: 100, duration: 1500 }}
|
||||
/>
|
||||
{:else}
|
||||
<div style="height: 16rem" />
|
||||
{/if}
|
||||
</center>
|
||||
|
||||
<style>
|
||||
img {
|
||||
height: 16rem;
|
||||
width: 16rem;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
8
src/lib/sailpoint/sdk.ts
Normal file
8
src/lib/sailpoint/sdk.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Configuration } from "sailpoint-api-client"
|
||||
|
||||
export function createConfiguration(baseUrl: string, token: string) {
|
||||
console.log(baseUrl)
|
||||
console.log(token)
|
||||
const apiConfig = new Configuration({baseurl: baseUrl, accessToken: token})
|
||||
return apiConfig
|
||||
}
|
||||
29
src/lib/utils/hmr-stores.js
Normal file
29
src/lib/utils/hmr-stores.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// Customized HMR-safe stores
|
||||
// Based off https://github.com/svitejs/svite/blob/ddec6b9/packages/playground/hmr/src/stores/hmr-stores.js
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
/**
|
||||
* @type { Record<string, import('svelte/store').Writable<any>> }
|
||||
*/
|
||||
let stores = {};
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param { string } id
|
||||
* @param { T } initialValue
|
||||
* @returns { import('svelte/store').Writable<T> }
|
||||
*/
|
||||
export function getStore(id, initialValue) {
|
||||
return stores[id] || (stores[id] = writable(initialValue));
|
||||
}
|
||||
|
||||
// preserve the store across HMR updates
|
||||
if (import.meta.hot) {
|
||||
if (import.meta.hot.data.stores) {
|
||||
stores = import.meta.hot.data.stores;
|
||||
}
|
||||
import.meta.hot.accept();
|
||||
import.meta.hot.dispose(() => {
|
||||
import.meta.hot.data.stores = stores;
|
||||
});
|
||||
}
|
||||
91
src/lib/utils/oauth.ts
Normal file
91
src/lib/utils/oauth.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import type { Cookies } from '@sveltejs/kit';
|
||||
import axios from 'axios';
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
|
||||
export function generateAuthLink(tenantUrl: string) {
|
||||
return `${tenantUrl}/oauth/authorize?client_id=sailpoint-cli&response_type=code&redirect_uri=http://localhost:3000/callback`;
|
||||
}
|
||||
|
||||
export type IdnSession = {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
claims_supported: string;
|
||||
expires_in: string;
|
||||
identity_id: string;
|
||||
internal: string;
|
||||
jti: string;
|
||||
org: string;
|
||||
pod: string;
|
||||
scope: string;
|
||||
strong_auth: string;
|
||||
strong_auth_supported: string;
|
||||
tenant_id: string;
|
||||
token_type: string;
|
||||
};
|
||||
|
||||
export async function refreshToken(apiUrl: string, refreshToken: string): Promise<IdnSession> {
|
||||
let url = `${apiUrl}/oauth/token?grant_type=refresh_token&client_id=sailpoint-cli&refresh_token=${refreshToken}`
|
||||
const response = await axios
|
||||
.post(
|
||||
url
|
||||
)
|
||||
.catch(function (err) {
|
||||
if (err.response) {
|
||||
// Request made and server responded
|
||||
console.log(err.response.data);
|
||||
console.log(err.response.status);
|
||||
console.log(err.response.headers);
|
||||
}
|
||||
return undefined
|
||||
});
|
||||
// if (response) {
|
||||
// console.log(response.data)
|
||||
// }
|
||||
const idnSession: IdnSession = response!.data as IdnSession;
|
||||
return idnSession
|
||||
}
|
||||
|
||||
export async function getToken(cookies: Cookies): Promise<IdnSession> {
|
||||
|
||||
const idnSession = <IdnSession>JSON.parse(cookies.get('idnSession')!)
|
||||
const session = JSON.parse(cookies.get('session')!)
|
||||
if (!idnSession && session) {
|
||||
throw redirect(302, generateAuthLink(session.tenantUrl))
|
||||
}
|
||||
if (!idnSession && !session) {
|
||||
throw redirect(302, "/")
|
||||
}
|
||||
if (isJwtExpired(idnSession.access_token)) {
|
||||
console.log("refreshing token")
|
||||
const newSession = await refreshToken(session.baseUrl, idnSession.refresh_token)
|
||||
cookies.set("idnSession", JSON.stringify(newSession));
|
||||
return Promise.resolve(newSession)
|
||||
} else {
|
||||
console.log("token is good")
|
||||
return Promise.resolve(idnSession)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function isJwtExpired(token: string): boolean {
|
||||
try {
|
||||
const decodedToken: any = jwt.decode(token, { complete: true });
|
||||
if (!decodedToken || !decodedToken.payload || !decodedToken.payload.exp) {
|
||||
// The token is missing the expiration claim ('exp') or is not a valid JWT.
|
||||
return true; // Treat as expired for safety.
|
||||
}
|
||||
|
||||
// Get the expiration timestamp from the token.
|
||||
const expirationTimestamp = decodedToken.payload.exp;
|
||||
|
||||
// Get the current timestamp.
|
||||
const currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
|
||||
// Check if the token has expired.
|
||||
return currentTimestamp >= expirationTimestamp;
|
||||
} catch (error) {
|
||||
// An error occurred during decoding.
|
||||
return true; // Treat as expired for safety.
|
||||
}
|
||||
}
|
||||
13
src/preload.cjs
Normal file
13
src/preload.cjs
Normal file
@@ -0,0 +1,13 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron');
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
send: (channel, data) => {
|
||||
ipcRenderer.send(channel, data);
|
||||
},
|
||||
sendSync: (channel, data) => {
|
||||
ipcRenderer.sendSync(channel, data);
|
||||
},
|
||||
receive: (channel, func) => {
|
||||
ipcRenderer.on(channel, (event, ...args) => func(...args));
|
||||
},
|
||||
});
|
||||
1
src/routes/+layout.js
Normal file
1
src/routes/+layout.js
Normal file
@@ -0,0 +1 @@
|
||||
export const ssr = false;
|
||||
25
src/routes/+layout.svelte
Normal file
25
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import '../app.postcss';
|
||||
import { onMount } from 'svelte';
|
||||
import { Modal, initializeStores } from '@skeletonlabs/skeleton';
|
||||
|
||||
initializeStores();
|
||||
let ready: boolean = false;
|
||||
onMount(() => (ready = true));
|
||||
</script>
|
||||
|
||||
<div class="dragbar" />
|
||||
<Modal />
|
||||
{#if ready}
|
||||
<slot />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.dragbar {
|
||||
-webkit-app-region: drag;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
16
src/routes/+page.server.ts
Normal file
16
src/routes/+page.server.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { Actions } from './$types';
|
||||
import { generateAuthLink } from '$lib/utils/oauth';
|
||||
|
||||
export const actions = {
|
||||
default: async ({cookies, request, url}) => {
|
||||
const data = await request.formData()
|
||||
console.log(data)
|
||||
const baseUrl = data.get("baseUrl")
|
||||
const tenant = data.get("tenant")
|
||||
const domain = data.get("domain")
|
||||
const tenantUrl = data.get("tenantUrl")
|
||||
cookies.set("session", JSON.stringify({baseUrl, tenantUrl}))
|
||||
throw redirect(302, generateAuthLink(tenantUrl))
|
||||
},
|
||||
} satisfies Actions;
|
||||
66
src/routes/+page.svelte
Normal file
66
src/routes/+page.svelte
Normal file
@@ -0,0 +1,66 @@
|
||||
<script lang="ts">
|
||||
import Counter from '$lib/Counter.svelte';
|
||||
import Logo from '$lib/Logo.svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import { Avatar } from '@skeletonlabs/skeleton';
|
||||
|
||||
let desktop: string;
|
||||
|
||||
if (window.electron && browser) {
|
||||
window.electron.receive('from-main', (data: any) => {
|
||||
desktop = `Received Message "${data}" from Electron`;
|
||||
console.log(desktop);
|
||||
});
|
||||
}
|
||||
|
||||
const agent = window.electron ? 'Electron' : 'Browser';
|
||||
|
||||
let tenant: string = 'tenant';
|
||||
let domain: string = 'identitynow';
|
||||
|
||||
$: baseUrl = `https://${tenant}.api.${domain}.com`;
|
||||
$: tenantUrl = `https://${tenant}.${domain}.com`;
|
||||
</script>
|
||||
|
||||
<main class="p-4">
|
||||
<img src="/SailPoint-Developer-Community-Lockup.png" alt="sailPoint Logo" />
|
||||
<div class="text-2xl text-slate-500 divide-dashed divide-y-2 mt-4 mb-2">
|
||||
Enter your tenant information to continue
|
||||
</div>
|
||||
<form method="POST">
|
||||
<label class="text-slate-600">
|
||||
Tenant
|
||||
<input name="tenant" placeholder={``} bind:value={tenant} class="input p-2" />
|
||||
</label>
|
||||
<label class="text-slate-600">
|
||||
Domain
|
||||
<input name="domain" placeholder={``} bind:value={domain} class="input p-2" />
|
||||
</label>
|
||||
<label class="text-slate-600">
|
||||
API Base URL
|
||||
<input
|
||||
name="baseUrl"
|
||||
placeholder={`https://${tenant}.api.${domain}.com`}
|
||||
bind:value={baseUrl}
|
||||
class="input p-2"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label class="text-slate-600">
|
||||
Tenant URL
|
||||
<input
|
||||
name="tenantUrl"
|
||||
placeholder={`https://${tenant}.identitynow.com`}
|
||||
bind:value={tenantUrl}
|
||||
class="input p-2"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<button type="submit" class="btn variant-filled-primary w-full mt-2 text-slate-50 text-lg">
|
||||
login
|
||||
</button>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
24
src/routes/api/sailpoint/search/+server.ts
Normal file
24
src/routes/api/sailpoint/search/+server.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { error, json } from '@sveltejs/kit';
|
||||
import { createConfiguration } from "$lib/sailpoint/sdk";
|
||||
import { getToken, type IdnSession } from "$lib/utils/oauth";
|
||||
import { SearchApi, type Search, Paginator } from "sailpoint-api-client";
|
||||
|
||||
/** @type {import('./$types').RequestHandler} */
|
||||
export async function POST({ request, cookies }) {
|
||||
try {
|
||||
const session = JSON.parse(cookies.get('session')!)
|
||||
const idnSession = await getToken(cookies)
|
||||
const searchJson = await request.json()
|
||||
|
||||
const config = createConfiguration(session.baseUrl, idnSession.access_token)
|
||||
let api = new SearchApi(config)
|
||||
let search: Search = searchJson
|
||||
const val = (await Paginator.paginateSearchApi(api, search, 100, 1000)).data
|
||||
//console.log(val)
|
||||
return json(val)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
43
src/routes/callback/+page.server.ts
Normal file
43
src/routes/callback/+page.server.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import axios from 'axios';
|
||||
import { generateAuthLink, type IdnSession } from '$lib/utils/oauth';
|
||||
import { counterList } from './loadinglist';
|
||||
|
||||
|
||||
|
||||
|
||||
export const load: PageServerLoad = async ({ params, url, cookies }) => {
|
||||
const code = url.searchParams.get('code');
|
||||
|
||||
const session = JSON.parse(cookies.get("session")!)
|
||||
|
||||
if (!code) throw error(500, 'No Authorization Code Provided');
|
||||
const response = await axios
|
||||
.post(
|
||||
`${session.baseUrl}/oauth/token?grant_type=authorization_code&client_id=sailpoint-cli&code=${code}&redirect_uri=http://localhost:3000/callback`
|
||||
)
|
||||
.catch(function (err) {
|
||||
if (err.response) {
|
||||
// Request made and server responded
|
||||
console.log(err.response.data);
|
||||
console.log(err.response.status);
|
||||
console.log(err.response.headers);
|
||||
throw redirect(302, generateAuthLink(session.tenantUrl));
|
||||
} else if (err.request) {
|
||||
// The request was made but no response was received
|
||||
throw error(500, { message: 'No Response From IDN'});
|
||||
} else {
|
||||
// Something happened in setting up the request that triggered an err
|
||||
throw error(500, {
|
||||
message: 'Error during Axios Request'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const idnSession: IdnSession = response.data as IdnSession;
|
||||
console.log(idnSession)
|
||||
cookies.set("idnSession", JSON.stringify(idnSession));
|
||||
|
||||
return { idnSession, counterList };
|
||||
};
|
||||
39
src/routes/callback/+page.svelte
Normal file
39
src/routes/callback/+page.svelte
Normal file
@@ -0,0 +1,39 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import AnimatedCounter from '$lib/AnimatedCounter.svelte';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
export let data: PageData;
|
||||
console.log(data);
|
||||
if (browser) setTimeout(() => goto(`/home`), 1000);
|
||||
</script>
|
||||
|
||||
<div class="z-50 mx-auto flex h-full items-center justify-center p-4 md:p-0">
|
||||
<div class="card card-glass z-50 space-y-5 p-4 md:p-10">
|
||||
<div class="skills">
|
||||
<AnimatedCounter
|
||||
interval={1500}
|
||||
transitionInterval={10}
|
||||
startImmediately
|
||||
values={data.counterList}
|
||||
random
|
||||
class="custom-skill px-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.skills {
|
||||
display: flex;
|
||||
justify-items: start;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
:global(.custom-skill) {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
260
src/routes/callback/loadinglist.ts
Normal file
260
src/routes/callback/loadinglist.ts
Normal file
@@ -0,0 +1,260 @@
|
||||
export const counterList = [
|
||||
'Reticulating splines...',
|
||||
'Generating witty dialog...',
|
||||
'Swapping time and space...',
|
||||
'Spinning violently around the y-axis...',
|
||||
'Tokenizing real life...',
|
||||
'Bending the spoon...',
|
||||
'Filtering morale...',
|
||||
"Don't think of purple hippos...",
|
||||
'We need a new fuse...',
|
||||
'Have a good day.',
|
||||
'Upgrading Windows, your PC will restart several times. Sit back and relax.',
|
||||
'640K ought to be enough for anybody',
|
||||
'The architects are still drafting',
|
||||
"We're building the buildings as fast as we can",
|
||||
'Would you prefer chicken, steak, or tofu?',
|
||||
'(Pay no attention to the man behind the curtain)',
|
||||
'...and enjoy the elevator music...',
|
||||
'Please wait while the little elves draw your map',
|
||||
"Don't worry - a few bits tried to escape, but we caught them",
|
||||
'Would you like fries with that?',
|
||||
'Checking the gravitational constant in your locale...',
|
||||
'Go ahead, hold your breath!',
|
||||
"...at least you're not on hold...",
|
||||
'Hum something loud while others stare',
|
||||
"You're not in Kansas any more",
|
||||
'The server is powered by a lemon and two electrodes.',
|
||||
'Please wait while a larger software vendor in Seattle takes over the world',
|
||||
"We're testing your patience",
|
||||
'As if you had any other choice',
|
||||
'Follow the white rabbit',
|
||||
"Why don't you order a sandwich?",
|
||||
'While the satellite moves into position',
|
||||
'keep calm and npm install',
|
||||
'The bits are flowing slowly today',
|
||||
"Dig on the 'X' for buried treasure... ARRR!",
|
||||
"It's still faster than you could draw it",
|
||||
"The last time I tried this the monkey didn't survive. Let's hope it works better this time.",
|
||||
'I should have had a V8 this morning.',
|
||||
'My other loading screen is much faster.',
|
||||
'Reconfoobling energymotron...',
|
||||
'(Insert quarter)',
|
||||
'Are we there yet?',
|
||||
'Have you lost weight?',
|
||||
'Just count to 10',
|
||||
'Why so serious?',
|
||||
"It's not you. It's me.",
|
||||
'Counting backwards from Infinity',
|
||||
"Don't panic...",
|
||||
"Don't panic, Just count to infinity.",
|
||||
'Embiggening Prototypes',
|
||||
'Do not run! We are your friends!',
|
||||
'Do you come here often?',
|
||||
"Warning: Don't set yourself on fire.",
|
||||
"We're making you a cookie.",
|
||||
'Creating time-loop inversion field',
|
||||
'Spinning the wheel of fortune...',
|
||||
'Loading the enchanted bunny...',
|
||||
'Computing chance of success',
|
||||
"I'm sorry Dave, I can't do that.",
|
||||
'Looking for exact change',
|
||||
'All your web browser are belong to us',
|
||||
'All I really need is a kilobit.',
|
||||
'I feel like im supposed to be loading something. . .',
|
||||
'What do you call 8 Hobbits? A Hobbyte.',
|
||||
'Should have used a compiled language...',
|
||||
'Is this Windows?',
|
||||
'Adjusting flux capacitor...',
|
||||
'Please wait until the sloth starts moving.',
|
||||
"Don't break your screen yet!",
|
||||
"I swear it's almost done.",
|
||||
"Let's take a mindfulness minute...",
|
||||
'Unicorns are at the end of this road, I promise.',
|
||||
'Listening for the sound of one hand clapping...',
|
||||
"Keeping all the 1's and removing all the 0's...",
|
||||
'Putting the icing on the cake. The cake is not a lie...',
|
||||
'Cleaning off the cobwebs...',
|
||||
"Making sure all the i's have dots...",
|
||||
'We need more dilithium crystals',
|
||||
'Where did all the internets go',
|
||||
'Connecting Neurotoxin Storage Tank...',
|
||||
'Granting wishes...',
|
||||
'Time flies when youre having fun.',
|
||||
'Get some coffee and come back in ten minutes..',
|
||||
'Spinning the hamster…',
|
||||
'99 bottles of beer on the wall..',
|
||||
'Stay awhile and listen..',
|
||||
'Be careful not to step in the git-gui',
|
||||
'You edhall not pass! yet..',
|
||||
'Load it and they will come',
|
||||
'Convincing AI not to turn evil..',
|
||||
'There is no spoon. Because we are not done loading it',
|
||||
'Your left thumb points to the right and your right thumb points to the left.',
|
||||
'How did you get here?',
|
||||
'Wait, do you smell something burning?',
|
||||
'Computing the secret to life, the universe, and everything.',
|
||||
'When nothing is going right, go left!!...',
|
||||
"I love my job only when I'm on vacation...",
|
||||
"i'm not lazy, I'm just relaxed!!",
|
||||
'Never steal. The government hates competition....',
|
||||
'Why are they called apartments if they are all stuck together?',
|
||||
'Life is Short, Talk Fast!!!!',
|
||||
'Optimism, is a lack of information.....',
|
||||
'Save water and shower together',
|
||||
'Whenever I find the key to success, someone changes the lock.',
|
||||
'Sometimes I think war is Gods way of teaching us geography.',
|
||||
'Ive got problem for your solution…..',
|
||||
'Where theres a will, theres a relative.',
|
||||
'User: the word computer professionals use when they mean !!idiot!!',
|
||||
'Adults are just kids with money.',
|
||||
'I think I am, therefore, I am. I think.',
|
||||
'A kiss is like a fight, with mouths.',
|
||||
'You dont pay taxes—they take taxes.',
|
||||
'Coffee, Chocolate, Men. The richer the better!',
|
||||
'I am free of all prejudices. I hate everyone equally.',
|
||||
'git happens',
|
||||
'May the forks be with you',
|
||||
'A commit a day keeps the mobs away',
|
||||
"This is not a joke, it's a commit.",
|
||||
'Constructing additional pylons...',
|
||||
'Roping some seaturtles...',
|
||||
'Locating Jebediah Kerman...',
|
||||
'We are not liable for any broken screens as a result of waiting.',
|
||||
'Hello IT, have you tried turning it off and on again?',
|
||||
'If you type Google into Google you can break the internet',
|
||||
'Well, this is embarrassing.',
|
||||
'What is the airspeed velocity of an unladen swallow?',
|
||||
'Hello, IT... Have you tried forcing an unexpected reboot?',
|
||||
"They just toss us away like yesterday's jam.",
|
||||
"They're fairly regular, the beatings, yes. I'd say we're on a bi-weekly beating.",
|
||||
'The Elders of the Internet would never stand for it.',
|
||||
'Space is invisible mind dust, and stars are but wishes.',
|
||||
"Didn't know paint dried so quickly.",
|
||||
'Everything sounds the same',
|
||||
"I'm going to walk the dog",
|
||||
"I didn't choose the engineering life. The engineering life chose me.",
|
||||
'Dividing by zero...',
|
||||
'Spawn more Overlord!',
|
||||
'If Im not back in five minutes, just wait longer.',
|
||||
'Some days, you just cant get rid of a bug!',
|
||||
'Were going to need a bigger boat.',
|
||||
'Chuck Norris never git push. The repo pulls before.',
|
||||
'Web developers do it with <style>',
|
||||
'I need to git pull --my-life-together',
|
||||
'Java developers never RIP. They just get Garbage Collected.',
|
||||
'Cracking military-grade encryption...',
|
||||
'Simulating traveling salesman...',
|
||||
'Proving P=NP...',
|
||||
'Entangling superstrings...',
|
||||
'Twiddling thumbs...',
|
||||
'Searching for plot device...',
|
||||
'Trying to sort in O(n)...',
|
||||
'Laughing at your pictures-i mean, loading...',
|
||||
'Sending data to NS-i mean, our servers.',
|
||||
'Looking for sense of humour, please hold on.',
|
||||
'Please wait while the intern refills his coffee.',
|
||||
'A different error message? Finally, some progress!',
|
||||
'Hold on while we wrap up our git together...sorry',
|
||||
'Please hold on as we reheat our coffee',
|
||||
'Kindly hold on as we convert this bug to a feature...',
|
||||
'Kindly hold on as our intern quits vim...',
|
||||
'Winter is coming...',
|
||||
'Installing dependencies',
|
||||
'Switching to the latest JS framework...',
|
||||
'Distracted by cat gifs',
|
||||
'Finding someone to hold my beer',
|
||||
'BRB, working on my side project',
|
||||
'@todo Insert witty loading message',
|
||||
"Let's hope it's worth the wait",
|
||||
'Aw, snap! Not..',
|
||||
'Ordering 1s and 0s...',
|
||||
'Updating dependencies...',
|
||||
"Whatever you do, don't look behind you...",
|
||||
'Please wait... Consulting the manual...',
|
||||
"It is dark. You're likely to be eaten by a grue.",
|
||||
'Loading funny message...',
|
||||
"It's 10:00pm. Do you know where your children are?",
|
||||
'Waiting Daenerys say all her titles...',
|
||||
'Feel free to spin in your chair',
|
||||
'What the what?',
|
||||
'format C: ...',
|
||||
'Forget you saw that password I just typed into the IM ...',
|
||||
"What's under there?",
|
||||
'Your computer has a virus, its name is Windows!',
|
||||
'Go ahead, hold your breath and do an ironman plank till loading complete',
|
||||
'Bored of slow loading spinner, buy more RAM!',
|
||||
"Help, I'm trapped in a loader!",
|
||||
'What is the difference btwn a hippo and a zippo? One is really heavy, the other is a little lighter',
|
||||
'Please wait, while we purge the Decepticons for you. Yes, You can thanks us later!',
|
||||
"Chuck Norris once urinated in a semi truck's gas tank as a joke....that truck is now known as Optimus Prime.",
|
||||
'Chuck Norris doesnt wear a watch. HE decides what time it is.',
|
||||
'Mining some bitcoins...',
|
||||
'Downloading more RAM..',
|
||||
'Updating to Windows Vista...',
|
||||
'Deleting System32 folder',
|
||||
"Hiding all ;'s in your code",
|
||||
'Alt-F4 speeds things up.',
|
||||
'Initializing the initializer...',
|
||||
'When was the last time you dusted around here?',
|
||||
'Optimizing the optimizer...',
|
||||
'Last call for the data bus! All aboard!',
|
||||
'Running swag sticker detection...',
|
||||
"Never let a computer know you're in a hurry.",
|
||||
'A computer will do what you tell it to do, but that may be much different from what you had in mind.',
|
||||
"Some things man was never meant to know. For everything else, there's Google.",
|
||||
"Unix is user-friendly. It's just very selective about who its friends are.",
|
||||
'Shovelling coal into the server',
|
||||
'Pushing pixels...',
|
||||
'How about this weather, eh?',
|
||||
'Building a wall...',
|
||||
'Everything in this universe is either a potato or not a potato',
|
||||
'The severity of your issue is always lower than you expected.',
|
||||
'Updating Updater...',
|
||||
'Downloading Downloader...',
|
||||
'Debugging Debugger...',
|
||||
'Reading Terms and Conditions for you.',
|
||||
'Digested cookies being baked again.',
|
||||
'Live long and prosper.',
|
||||
"There is no cow level, but there's a goat one!",
|
||||
'Running with scissors...',
|
||||
'Definitely not a virus...',
|
||||
'You may call me Steve.',
|
||||
'You seem like a nice person...',
|
||||
"Coffee at my place, tommorow at 10A.M. - don't be late!",
|
||||
'Work, work...',
|
||||
'Patience! This is difficult, you know...',
|
||||
'Discovering new ways of making you wait...',
|
||||
'Your time is very important to us. Please wait while we ignore you...',
|
||||
'Time flies like an arrow; fruit flies like a banana',
|
||||
'Two men walked into a bar; the third ducked...',
|
||||
'Sooooo... Have you seen my vacation photos yet?',
|
||||
"Sorry we are busy catching em' all, we're done soon",
|
||||
'TODO: Insert elevator music',
|
||||
'Still faster than Windows update',
|
||||
'Composer hack: Waiting for reqs to be fetched is less frustrating if you add -vvv to your command.',
|
||||
'Please wait while the minions do their work',
|
||||
'Grabbing extra minions',
|
||||
'Doing the heavy lifting',
|
||||
"We're working very Hard .... Really",
|
||||
'Waking up the minions',
|
||||
'You are number 2843684714 in the queue',
|
||||
'Please wait while we serve other customers...',
|
||||
'Our premium plan is faster',
|
||||
'Feeding unicorns...',
|
||||
'Rupturing the subspace barrier',
|
||||
'Creating an anti-time reaction',
|
||||
'Converging tachyon pulses',
|
||||
'Bypassing control of the matter-antimatter integrator',
|
||||
'Adjusting the dilithium crystal converter assembly',
|
||||
'Reversing the shield polarity',
|
||||
'Disrupting warp fields with an inverse graviton burst',
|
||||
'Up, Up, Down, Down, Left, Right, Left, Right, B, A.',
|
||||
'Do you like my loading animation? I made it myself',
|
||||
'Whoah, look at it go!',
|
||||
"No, I'm awake. I was just resting my eyes.",
|
||||
'One mississippi, two mississippi...',
|
||||
"Don't panic... AHHHHH!",
|
||||
'Ensuring Gnomes are still short.',
|
||||
'Baking ice cream...'
|
||||
].sort((a, b) => 0.5 - Math.random());
|
||||
70
src/routes/home/+page.svelte
Normal file
70
src/routes/home/+page.svelte
Normal file
@@ -0,0 +1,70 @@
|
||||
<script>
|
||||
import { each } from 'svelte/internal';
|
||||
|
||||
let pages = [
|
||||
{
|
||||
url: '/source-account-create-error',
|
||||
name: 'Source Account Create Error',
|
||||
description:
|
||||
'This report will show all source accounts for which there is a create error associated with the source',
|
||||
},
|
||||
{
|
||||
url: '/identity-inactive-but-has-access',
|
||||
name: 'Inactive Identities With Access',
|
||||
description:
|
||||
'This report will show all identities that are inactive but still have access in sources',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="p-4">
|
||||
<img src="/SailPoint-Developer-Community-Lockup.png" alt="sailPoint Logo" />
|
||||
<a href="/" class="btn variant-filled-primary w-full mt-2 text-slate-50 text-lg">
|
||||
Go back to login
|
||||
</a>
|
||||
<div class="text-2xl text-slate-500 divide-dashed divide-y-2 mt-4 mb-2">
|
||||
Select a report to run
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row flex-wrap">
|
||||
{#each pages as page (page.url)}
|
||||
<a class="card card-hover overflow-hidden m-4 w-modal-slim" href={page.url}>
|
||||
<header>
|
||||
<div class="w-full aspect-[21/9] text-container" alt="Post">
|
||||
<div class="text">{page.name}</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="p-4 space-y-4">
|
||||
<h3 class="h3" data-toc-ignore>Summary</h3>
|
||||
<article>
|
||||
<p>
|
||||
{page.description}
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
<hr class="opacity-50" />
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Define a container to hold the text */
|
||||
.text-container {
|
||||
position: relative;
|
||||
background-color: #526bf8;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Style the text */
|
||||
.text {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-transform: uppercase;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
||||
129
src/routes/identity-inactive-but-has-access/+page.svelte
Normal file
129
src/routes/identity-inactive-but-has-access/+page.svelte
Normal file
@@ -0,0 +1,129 @@
|
||||
<script lang="ts">
|
||||
import type { TableSource } from '@skeletonlabs/skeleton';
|
||||
import { ProgressRadial, Table, tableMapperValues } from '@skeletonlabs/skeleton';
|
||||
import type { Search } from 'sailpoint-api-client';
|
||||
import { onMount } from 'svelte';
|
||||
import alasql from 'alasql';
|
||||
|
||||
//export let data;
|
||||
let tableSimple: TableSource | undefined = undefined;
|
||||
|
||||
onMount(async () => {
|
||||
const search: Search = {
|
||||
indices: ['identities'],
|
||||
query: {
|
||||
query: `@accounts(disabled:false) AND (attributes.cloudLifecycleState:inactive)`,
|
||||
},
|
||||
sort: ['name'],
|
||||
};
|
||||
|
||||
const response = await fetch('/api/sailpoint/search', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(search),
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
let data = await response.json();
|
||||
console.log(data);
|
||||
|
||||
if (JSON.stringify(data) !== '{}') {
|
||||
let reportResult = [];
|
||||
|
||||
for (let row of <any>data) {
|
||||
let accounts: string[] = [];
|
||||
for (let account of row.accounts) {
|
||||
if (account.disabled == false) {
|
||||
accounts.push(account.source.name);
|
||||
}
|
||||
}
|
||||
reportResult.push({
|
||||
name: row.displayName,
|
||||
source: accounts.join(', '),
|
||||
department: row.attributes.department,
|
||||
accessCount: row.accessCount,
|
||||
entitlementCount: row.entitlementCount,
|
||||
roleCount: row.roleCount,
|
||||
});
|
||||
}
|
||||
|
||||
let res = alasql(
|
||||
'SELECT name, source, department, accessCount, entitlementCount, roleCount FROM ?',
|
||||
[reportResult],
|
||||
);
|
||||
console.log(res);
|
||||
tableSimple = {
|
||||
// A list of heading labels.
|
||||
head: [
|
||||
'Name',
|
||||
'Sources',
|
||||
'Departments',
|
||||
'Access Count',
|
||||
'Entitlement Count',
|
||||
'Role Count',
|
||||
],
|
||||
// The data visibly shown in your table body UI.
|
||||
body: tableMapperValues(res, [
|
||||
'name',
|
||||
'source',
|
||||
'department',
|
||||
'accessCount',
|
||||
'entitlementCount',
|
||||
'roleCount',
|
||||
]),
|
||||
// Optional: The data returned when interactive is enabled and a row is clicked.
|
||||
meta: tableMapperValues(res, [
|
||||
'name',
|
||||
'source',
|
||||
'department',
|
||||
'accessCount',
|
||||
'entitlementCount',
|
||||
'roleCount',
|
||||
]),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function onTableclick(event: any) {
|
||||
console.log(event);
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="p-4">
|
||||
<img src="/SailPoint-Developer-Community-Lockup.png" alt="sailPoint Logo" />
|
||||
<a href="/home" class="btn variant-filled-primary w-full mt-2 text-slate-50 text-lg">
|
||||
Go back report screen
|
||||
</a>
|
||||
<div class="flex justify-center mt-4 flex-col align-middle">
|
||||
<div class="text-2xl text-slate-500 divide-dashed divide-y-2 mt-4 mb-2">
|
||||
Listing of identities that are inactive but still have access in sources
|
||||
</div>
|
||||
{#if tableSimple}
|
||||
<Table
|
||||
class="w-full"
|
||||
source={tableSimple}
|
||||
interactive={true}
|
||||
on:selected={onTableclick}
|
||||
/>
|
||||
{:else}
|
||||
<div class="progress-bar">
|
||||
<ProgressRadial
|
||||
stroke={100}
|
||||
meter="stroke-primary-500"
|
||||
track="stroke-primary-500/30"
|
||||
class="progress-bar"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.progress-bar {
|
||||
padding-top: calc(50vh - 4.5rem - 200px);
|
||||
padding-left: calc(50% - 4.5rem);
|
||||
}
|
||||
</style>
|
||||
118
src/routes/source-account-create-error/+page.svelte
Normal file
118
src/routes/source-account-create-error/+page.svelte
Normal file
@@ -0,0 +1,118 @@
|
||||
<script lang="ts">
|
||||
import type { ModalSettings, TableSource } from '@skeletonlabs/skeleton';
|
||||
import { ProgressRadial, Table, tableMapperValues } from '@skeletonlabs/skeleton';
|
||||
import type { Search } from 'sailpoint-api-client';
|
||||
import { onMount } from 'svelte';
|
||||
import alasql from 'alasql';
|
||||
import { getModalStore } from '@skeletonlabs/skeleton';
|
||||
|
||||
const modalStore = getModalStore();
|
||||
//export let data;
|
||||
let tableSimple: TableSource | undefined = undefined;
|
||||
let rawData: any;
|
||||
onMount(async () => {
|
||||
const search: Search = {
|
||||
indices: ['events'],
|
||||
query: {
|
||||
query: `name: "Create Account Failed" AND created: [now-90d TO now]`,
|
||||
},
|
||||
sort: ['created'],
|
||||
};
|
||||
|
||||
const response = await fetch('/api/sailpoint/search', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(search),
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
rawData = await response.json();
|
||||
|
||||
if (JSON.stringify(rawData) !== '{}') {
|
||||
let reportResult = [];
|
||||
|
||||
for (let row of <any>rawData) {
|
||||
reportResult.push({
|
||||
name: row.target.name,
|
||||
source: row.attributes.sourceName,
|
||||
failure: row.name,
|
||||
});
|
||||
}
|
||||
|
||||
let res = alasql(
|
||||
'SELECT failure, source, name, count(*) as failures FROM ? GROUP BY failure, source, name',
|
||||
[reportResult],
|
||||
);
|
||||
console.log(res);
|
||||
tableSimple = {
|
||||
// A list of heading labels.
|
||||
head: ['Name', 'Source', 'Failure', 'Number Failures'],
|
||||
// The data visibly shown in your table body UI.
|
||||
body: tableMapperValues(res, ['name', 'source', 'failure', 'failures']),
|
||||
// Optional: The data returned when interactive is enabled and a row is clicked.
|
||||
meta: tableMapperValues(res, ['name', 'source', 'failure', 'failures']),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function onTableclick(event: any) {
|
||||
console.log(event);
|
||||
let exceptions = '';
|
||||
for (let row of rawData) {
|
||||
if (
|
||||
row.target.name == event.detail[0] &&
|
||||
row.attributes.sourceName == event.detail[1] &&
|
||||
row.name == event.detail[2]
|
||||
) {
|
||||
console.log(row.attributes.errors);
|
||||
exceptions = JSON.stringify(JSON.parse(row.attributes.errors), null, ' ');
|
||||
}
|
||||
}
|
||||
const modal: ModalSettings = {
|
||||
type: 'alert',
|
||||
// Data
|
||||
title: 'Exception Details',
|
||||
body: `${exceptions}`,
|
||||
};
|
||||
modalStore.trigger(modal);
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="p-4">
|
||||
<img src="/SailPoint-Developer-Community-Lockup.png" alt="sailPoint Logo" />
|
||||
<a href="/home" class="btn variant-filled-primary w-full mt-2 text-slate-50 text-lg">
|
||||
Go back report screen
|
||||
</a>
|
||||
<div class="flex justify-center mt-4 flex-col align-middle">
|
||||
<div class="text-2xl text-slate-500 divide-dashed divide-y-2 mt-4 mb-2">
|
||||
Listing of Source Account Create Errors
|
||||
</div>
|
||||
{#if tableSimple}
|
||||
<Table
|
||||
class="w-full"
|
||||
source={tableSimple}
|
||||
interactive={true}
|
||||
on:selected={onTableclick}
|
||||
/>
|
||||
{:else}
|
||||
<div class="progress-bar">
|
||||
<ProgressRadial
|
||||
stroke={100}
|
||||
meter="stroke-primary-500"
|
||||
track="stroke-primary-500/30"
|
||||
class="progress-bar"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.progress-bar {
|
||||
padding-top: calc(50vh - 4.5rem - 200px);
|
||||
padding-left: calc(50% - 4.5rem);
|
||||
}
|
||||
</style>
|
||||
BIN
static/SailPoint-Developer-Community-Lockup.png
Normal file
BIN
static/SailPoint-Developer-Community-Lockup.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icon.png
Normal file
BIN
static/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
16
static/sveltekit-electron.svg
Normal file
16
static/sveltekit-electron.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg width="450" height="450" viewBox="0 0 450 450" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M175.111 101.021C126.445 92.1577 87.9653 101.434 72.6292 127.997C61.1856 147.819 64.4568 174.099 80.5639 202.19C80.8819 202.774 81.3133 203.288 81.8327 203.702C82.352 204.117 82.9489 204.423 83.5884 204.604C84.2278 204.785 84.8969 204.836 85.5564 204.755C86.216 204.674 86.8526 204.462 87.429 204.131C88.0055 203.8 88.5101 203.358 88.9133 202.83C89.3165 202.302 89.6102 201.698 89.7771 201.055C89.944 200.412 89.9808 199.742 89.8853 199.084C89.7898 198.427 89.5639 197.795 89.221 197.225C74.7139 171.92 71.89 149.241 81.2731 132.988C94.0136 110.922 128.335 102.647 173.322 110.84C174.614 111.055 175.94 110.753 177.012 109.999C178.084 109.246 178.817 108.101 179.051 106.811C179.286 105.522 179.005 104.192 178.267 103.109C177.53 102.025 176.396 101.275 175.111 101.021V101.021ZM105.871 236.336C125.549 257.96 151.114 278.244 180.27 295.075C250.865 335.834 326.02 346.728 363.059 321.473C363.613 321.109 364.089 320.639 364.459 320.089C364.829 319.539 365.086 318.921 365.215 318.271C365.344 317.621 365.342 316.952 365.209 316.303C365.077 315.653 364.816 315.037 364.443 314.489C364.069 313.942 363.59 313.474 363.034 313.113C362.478 312.753 361.856 312.507 361.203 312.389C360.551 312.272 359.882 312.286 359.235 312.43C358.588 312.573 357.976 312.845 357.435 313.228C324.285 335.831 252.895 325.482 185.261 286.433C156.977 270.103 132.22 250.461 113.253 229.617C112.813 229.13 112.281 228.734 111.687 228.452C111.093 228.171 110.45 228.009 109.794 227.977C109.137 227.945 108.481 228.043 107.863 228.265C107.244 228.487 106.676 228.829 106.19 229.271C105.704 229.713 105.31 230.247 105.031 230.842C104.752 231.437 104.593 232.081 104.563 232.737C104.533 233.393 104.634 234.049 104.858 234.667C105.083 235.284 105.427 235.852 105.871 236.336V236.336Z" fill="#2B2E3A"/>
|
||||
<path d="M351.243 230.265C383.109 192.62 394.235 154.758 378.93 128.251C367.67 108.746 343.864 98.4476 312.224 98.0359C310.913 98.0378 309.655 98.5557 308.723 99.4775C307.79 100.399 307.258 101.651 307.241 102.962C307.224 104.273 307.724 105.539 308.632 106.484C309.54 107.43 310.784 107.98 312.095 108.016C340.55 108.387 361.06 117.259 370.288 133.242C382.999 155.259 373.077 189.023 343.625 223.816C343.192 224.315 342.863 224.895 342.657 225.522C342.45 226.149 342.37 226.811 342.421 227.469C342.472 228.127 342.653 228.769 342.954 229.357C343.255 229.944 343.669 230.466 344.173 230.893C344.677 231.32 345.26 231.642 345.89 231.841C346.519 232.041 347.181 232.113 347.839 232.055C348.497 231.997 349.136 231.808 349.72 231.501C350.305 231.194 350.822 230.774 351.243 230.265ZM269.349 102.683C240.537 108.856 209.868 120.927 180.416 137.93C107.54 180.005 60.001 242.047 66.6033 287.034C66.6913 287.689 66.9084 288.319 67.242 288.889C67.5756 289.459 68.019 289.958 68.5466 290.355C69.0742 290.753 69.6754 291.041 70.3154 291.205C70.9554 291.368 71.6215 291.403 72.275 291.307C72.9285 291.211 73.5565 290.986 74.1225 290.646C74.6885 290.305 75.1813 289.856 75.5724 289.323C75.9634 288.791 76.2448 288.186 76.4004 287.544C76.556 286.902 76.5826 286.236 76.4787 285.584C70.6156 245.641 115.679 186.832 185.407 146.574C213.978 130.078 243.673 118.391 271.439 112.442C272.089 112.314 272.707 112.058 273.257 111.688C273.806 111.319 274.277 110.844 274.642 110.291C275.006 109.738 275.257 109.118 275.379 108.467C275.501 107.816 275.493 107.147 275.354 106.5C275.215 105.852 274.949 105.239 274.571 104.695C274.193 104.151 273.71 103.688 273.151 103.333C272.592 102.978 271.968 102.737 271.315 102.626C270.663 102.514 269.994 102.533 269.349 102.683V102.683Z" fill="#2B2E3A"/>
|
||||
<path d="M303.47 309.12C312.097 281.559 316.729 249.763 316.729 216.63C316.729 133.954 287.791 62.6835 246.576 44.3831C245.372 43.8788 244.018 43.8663 242.805 44.3482C241.592 44.8302 240.616 45.7682 240.086 46.9613C239.556 48.1544 239.515 49.5075 239.971 50.7306C240.427 51.9537 241.344 52.9494 242.526 53.5043C279.286 69.8285 306.747 137.466 306.747 216.63C306.747 248.775 302.261 279.565 293.946 306.139C293.74 306.768 293.66 307.431 293.712 308.09C293.764 308.75 293.947 309.392 294.249 309.98C294.552 310.568 294.968 311.091 295.474 311.517C295.98 311.942 296.566 312.264 297.197 312.461C297.828 312.659 298.492 312.729 299.151 312.667C299.81 312.606 300.449 312.414 301.033 312.103C301.617 311.793 302.133 311.369 302.552 310.857C302.971 310.345 303.283 309.754 303.472 309.12H303.47ZM397.459 304.232C397.459 291.041 386.766 280.348 373.574 280.348C360.383 280.348 349.69 291.041 349.69 304.232C349.69 317.424 360.383 328.117 373.574 328.117C386.766 328.117 397.459 317.424 397.459 304.232ZM387.479 304.232C387.479 306.058 387.119 307.866 386.42 309.553C385.722 311.24 384.697 312.773 383.406 314.064C382.115 315.355 380.582 316.38 378.895 317.078C377.208 317.777 375.4 318.137 373.574 318.137C371.748 318.137 369.94 317.777 368.253 317.078C366.566 316.38 365.033 315.355 363.742 314.064C362.451 312.773 361.427 311.24 360.728 309.553C360.029 307.866 359.67 306.058 359.67 304.232C359.67 300.545 361.135 297.008 363.742 294.4C366.35 291.793 369.887 290.328 373.574 290.328C377.262 290.328 380.799 291.793 383.406 294.4C386.014 297.008 387.479 300.545 387.479 304.232ZM77.7886 328.117C90.982 328.117 101.675 317.424 101.675 304.232C101.675 291.041 90.9801 280.348 77.7886 280.348C64.599 280.348 53.904 291.041 53.904 304.232C53.904 317.424 64.599 328.117 77.7886 328.117ZM77.7886 318.137C74.1009 318.137 70.5643 316.672 67.9567 314.064C65.3491 311.457 63.8841 307.92 63.8841 304.232C63.8841 300.545 65.3491 297.008 67.9567 294.4C70.5643 291.793 74.1009 290.328 77.7886 290.328C81.4763 290.328 85.013 291.793 87.6206 294.4C90.2282 297.008 91.6931 300.545 91.6931 304.232C91.6931 307.92 90.2282 311.457 87.6206 314.064C85.013 316.672 81.4763 318.137 77.7886 318.137Z" fill="#2B2E3A"/>
|
||||
<path d="M225.854 68.7466C239.045 68.7466 249.738 58.0534 249.738 44.8619C249.738 31.6705 239.045 20.9773 225.854 20.9773C212.662 20.9773 201.969 31.6705 201.969 44.8619C201.969 58.0534 212.662 68.7466 225.854 68.7466ZM225.854 58.7664C222.166 58.7664 218.629 57.3015 216.022 54.6939C213.414 52.0863 211.949 48.5496 211.949 44.8619C211.949 41.1743 213.414 37.6376 216.022 35.03C218.629 32.4224 222.166 30.9575 225.854 30.9575C229.541 30.9575 233.078 32.4224 235.686 35.03C238.293 37.6376 239.758 41.1743 239.758 44.8619C239.758 48.5496 238.293 52.0863 235.686 54.6939C233.078 57.3015 229.541 58.7664 225.854 58.7664Z" fill="#2B2E3A"/>
|
||||
<path d="M269.53 208.778L177.913 226.73C176.407 227.025 175.292 228.301 175.201 229.833L169.439 256.782C172.323 260.842 172.444 276.397 172.444 276.397L169.565 325.016C169.433 327.257 171.492 328.997 173.68 328.493L199.187 322.606C201.574 322.056 203.73 324.158 203.24 326.558L195.662 363.667C195.152 366.165 197.496 368.3 199.935 367.559L215.69 362.773C218.132 362.031 220.479 364.173 219.963 366.673L207.919 424.963C207.166 428.609 212.016 430.597 214.038 427.471L215.389 425.384L290.044 276.397C291.294 273.903 289.138 271.058 286.398 271.587L260.143 276.654C257.675 277.13 255.576 274.832 256.273 272.418C256.273 272.418 260.143 260.325 265.742 254.257C276.853 242.217 273.409 213.012 273.409 213.012C274.106 210.594 272 208.294 269.53 208.778Z" fill="url(#vite-gradient)"/>
|
||||
<path d="M225.854 393.39C195.204 393.39 167.947 364.744 151.284 318.221H151.286C151.049 317.601 150.939 316.939 150.961 316.276C150.984 315.612 151.138 314.96 151.416 314.356C151.694 313.753 152.089 313.211 152.579 312.763C153.068 312.315 153.643 311.968 154.268 311.745C154.893 311.521 155.557 311.424 156.22 311.46C156.883 311.496 157.532 311.664 158.129 311.954C158.727 312.244 159.26 312.65 159.698 313.149C160.137 313.647 160.471 314.229 160.682 314.858C176.082 357.859 200.393 383.408 225.854 383.408C244.165 383.408 261.968 370.291 276.462 346.182C276.794 345.61 277.237 345.11 277.765 344.711C278.292 344.312 278.894 344.021 279.535 343.857C280.176 343.692 280.843 343.657 281.497 343.752C282.152 343.848 282.781 344.073 283.348 344.413C283.915 344.754 284.408 345.204 284.8 345.738C285.191 346.271 285.473 346.877 285.628 347.52C285.783 348.163 285.809 348.83 285.704 349.484C285.599 350.137 285.365 350.762 285.016 351.324C268.888 378.151 248.207 393.39 225.854 393.39Z" fill="#2B2E3A"/>
|
||||
<path d="M271.906 167.483C259.49 149.599 234.771 144.359 217.001 155.636L185.675 175.685C177.132 181.039 171.208 189.81 169.5 199.72C168.019 208.036 169.272 216.579 173.259 223.983C170.525 228.084 168.702 232.64 167.905 237.425C166.082 247.563 168.475 258.043 174.398 266.358C186.928 284.242 211.533 289.482 229.303 278.205L260.629 258.271C269.172 252.917 275.096 244.146 276.804 234.235C278.285 225.92 277.032 217.376 273.045 209.972C275.779 205.871 277.602 201.315 278.399 196.531C280.336 186.279 277.943 175.799 271.906 167.483Z" fill="#FF3E00"/>
|
||||
<path d="M213.927 268.068C203.789 270.688 193.195 266.701 187.272 258.158C183.626 253.146 182.259 246.88 183.285 240.729C183.512 239.704 183.74 238.793 183.968 237.767L184.538 235.945L186.132 237.084C189.891 239.818 193.992 241.868 198.435 243.235L199.574 243.577L199.46 244.716C199.346 246.311 199.802 248.02 200.713 249.386C202.536 252.006 205.725 253.259 208.801 252.462C209.484 252.234 210.168 252.006 210.737 251.665L241.949 231.73C243.544 230.705 244.569 229.224 244.911 227.402C245.252 225.579 244.797 223.642 243.772 222.162C241.949 219.542 238.759 218.403 235.684 219.2C235 219.428 234.317 219.656 233.747 219.997L221.787 227.629C219.85 228.882 217.686 229.794 215.408 230.363C205.27 232.983 194.676 228.996 188.752 220.453C185.221 215.441 183.74 209.176 184.879 203.025C185.905 197.101 189.55 191.747 194.676 188.558L226.001 168.623C227.938 167.37 230.102 166.459 232.38 165.775C242.519 163.156 253.112 167.142 259.036 175.686C262.681 180.698 264.048 186.963 263.023 193.114C262.795 194.139 262.567 195.051 262.225 196.076L261.656 197.898L260.061 196.759C256.302 194.026 252.201 191.975 247.758 190.608L246.619 190.266L246.733 189.127C246.847 187.533 246.392 185.824 245.48 184.457C243.658 181.837 240.468 180.698 237.393 181.495C236.709 181.723 236.026 181.951 235.456 182.293L204.244 202.227C202.65 203.252 201.624 204.733 201.283 206.556C200.941 208.378 201.397 210.315 202.422 211.796C204.244 214.416 207.434 215.555 210.509 214.757C211.193 214.53 211.876 214.302 212.446 213.96L224.407 206.328C226.343 205.075 228.507 204.164 230.786 203.48C240.924 200.86 251.518 204.847 257.441 213.39C261.086 218.403 262.453 224.668 261.428 230.819C260.403 236.742 256.758 242.096 251.631 245.286L220.306 265.22C218.369 266.473 216.205 267.384 213.927 268.068Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="vite-gradient" x1="203.38" y1="213.652" x2="231.252" y2="404.854" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.364583" stop-color="#FF3E00"/>
|
||||
<stop offset="0.770833" stop-color="#FFDD35"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
19
svelte.config.js
Normal file
19
svelte.config.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import preprocess from 'svelte-preprocess';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||
// for more information about preprocessors
|
||||
preprocess: [preprocess(), vitePreprocess({})],
|
||||
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
fallback: 'index.html',
|
||||
}),
|
||||
prerender: { entries: [] },
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
26
tailwind.config.ts
Normal file
26
tailwind.config.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { join } from 'path';
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
// 1. Import the Skeleton plugin
|
||||
import { skeleton } from '@skeletonlabs/tw-plugin';
|
||||
|
||||
const config = {
|
||||
// 2. Opt for dark mode to be handled via the class method
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
'./src/**/*.{html,js,svelte,ts}',
|
||||
// 3. Append the path to the Skeleton package
|
||||
join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}'),
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [
|
||||
// 4. Append the Skeleton plugin (after other plugins)
|
||||
skeleton({
|
||||
themes: { preset: ['wintry'] },
|
||||
}),
|
||||
],
|
||||
} satisfies Config;
|
||||
|
||||
export default config;
|
||||
35
tsconfig.json
Normal file
35
tsconfig.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"target": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"types": ["vite/client", "node"],
|
||||
"typeRoots": ["node_modules/@types"],
|
||||
"lib": ["ESNext"],
|
||||
/**
|
||||
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
|
||||
to enforce using \`import type\` instead of \`import\` for Types.
|
||||
*/
|
||||
"importsNotUsedAsValues": "error",
|
||||
"isolatedModules": true,
|
||||
/**
|
||||
To have warnings/errors of the Svelte compiler at the correct position,
|
||||
enable source maps by default.
|
||||
*/
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": ".",
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"paths": {
|
||||
"$lib": ["src/lib"],
|
||||
"$lib/*": ["src/lib/*"],
|
||||
"$app/*": [".svelte/dev/runtime/app/*", ".svelte/build/runtime/app/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.svelte", "src/electron.js"]
|
||||
}
|
||||
11
vite.config.js
Normal file
11
vite.config.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
|
||||
const config = {
|
||||
plugins: [sveltekit()],
|
||||
server: {
|
||||
port: 3000,
|
||||
strict: true
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
Reference in New Issue
Block a user