feat: docker compose maybe

This commit is contained in:
2023-11-13 16:10:04 -05:00
parent 180b261e40
commit b625ccd8d6
8031 changed files with 2182966 additions and 0 deletions

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 [these people](https://github.com/sveltejs/vite-plugin-svelte/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.

View File

@ -0,0 +1,26 @@
# @sveltejs/vite-plugin-svelte-inspector
A [Svelte](https://svelte.dev) inspector plugin for [Vite](https://vitejs.dev).
## Usage
```js
// vite.config.js
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
export default defineConfig({
plugins: [
// the svelte plugin is required to work
svelte(),
svelteInspector({
/* plugin options */
})
]
});
```
## License
[MIT](./LICENSE)

View File

@ -0,0 +1,52 @@
{
"name": "@sveltejs/vite-plugin-svelte-inspector",
"version": "1.0.4",
"license": "MIT",
"author": "dominikg",
"files": [
"src"
],
"type": "module",
"types": "src/index.d.ts",
"exports": {
".": {
"types": "./src/index.d.ts",
"import": "./src/index.js"
}
},
"engines": {
"node": "^14.18.0 || >= 16"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sveltejs/vite-plugin-svelte.git",
"directory": "packages/vite-plugin-svelte-inspector"
},
"keywords": [
"vite-plugin",
"vite plugin",
"vite",
"svelte"
],
"bugs": {
"url": "https://github.com/sveltejs/vite-plugin-svelte/issues"
},
"homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme",
"dependencies": {
"debug": "^4.3.4"
},
"peerDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.2.0",
"svelte": "^3.54.0 || ^4.0.0",
"vite": "^4.0.0"
},
"devDependencies": {
"@types/debug": "^4.1.8",
"svelte": "^4.1.2",
"vite": "^4.4.9"
},
"scripts": {
"check:publint": "publint --strict",
"check:types": "tsc --noEmit"
}
}

View File

@ -0,0 +1,3 @@
import _debug from 'debug';
export const debug = _debug('vite-plugin-svelte-inspector');

View File

@ -0,0 +1,73 @@
import type { Plugin } from 'vite';
export interface Options {
/**
* define a key combo to toggle inspector,
* @default 'meta-shift' on mac, 'control-shift' on other os
*
* any number of modifiers `control` `shift` `alt` `meta` followed by zero or one regular key, separated by -
* examples: control-shift, control-o, control-alt-s meta-x control-meta
* Some keys have native behavior (e.g. alt-s opens history menu on firefox).
* To avoid conflicts or accidentally typing into inputs, modifier only combinations are recommended.
*/
toggleKeyCombo?: string;
/**
* define keys to select elements with via keyboard
* @default {parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' }
*
* improves accessibility and also helps when you want to select elements that do not have a hoverable surface area
* due to tight wrapping
*
* A note for users of screen-readers:
* If you are using arrow keys to navigate the page itself, change the navKeys to avoid conflicts.
* e.g. navKeys: {parent: 'w', prev: 'a', child: 's', next: 'd'}
*
*
* parent: select closest parent
* child: select first child (or grandchild)
* next: next sibling (or parent if no next sibling exists)
* prev: previous sibling (or parent if no prev sibling exists)
*/
navKeys?: { parent: string; child: string; next: string; prev: string };
/**
* define key to open the editor for the currently selected dom node
*
* @default 'Enter'
*/
openKey?: string;
/**
* inspector is automatically disabled when releasing toggleKeyCombo after holding it for a longpress
* @default true
*/
holdMode?: boolean;
/**
* when to show the toggle button
* @default 'active'
*/
showToggleButton?: 'always' | 'active' | 'never';
/**
* where to display the toggle button
* @default top-right
*/
toggleButtonPos?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
/**
* inject custom styles when inspector is active
*/
customStyles?: boolean;
/**
* internal options that are automatically set, not to be set or used by users
*/
__internal?: {
// vite base url
base: string;
};
}
export declare function svelteInspector(options?: Options): Plugin;

View File

@ -0,0 +1,110 @@
import { normalizePath } from 'vite';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { debug } from './debug.js';
import { defaultInspectorOptions, parseEnvironmentOptions } from './options.js';
import { cleanUrl } from './utils.js';
function getInspectorPath() {
const pluginPath = normalizePath(path.dirname(fileURLToPath(import.meta.url)));
return pluginPath.replace(
/\/vite-plugin-svelte-inspector\/src$/,
'/vite-plugin-svelte-inspector/src/runtime/'
);
}
/** @type {import('.').svelteInspector} */
export function svelteInspector(options) {
const inspectorPath = getInspectorPath();
debug(`svelte inspector path: ${inspectorPath}`);
/** @type {import('vite').ResolvedConfig} */
let viteConfig;
/** @type {import('.').Options} */
let inspectorOptions;
let disabled = false;
return {
name: 'vite-plugin-svelte-inspector',
apply: 'serve',
enforce: 'pre',
configResolved(config) {
viteConfig = config;
const environmentOptions = parseEnvironmentOptions(config);
if (environmentOptions === false) {
debug(`environment options set to false, inspector disabled`);
disabled = true;
return;
}
// Handle config from svelte.config.js through vite-plugin-svelte
const vps = config.plugins.find((p) => p.name === 'vite-plugin-svelte');
const configFileOptions = vps?.api?.options?.inspector;
// vite-plugin-svelte can only pass options through it's `api` instead of `options`.
// that means this plugin could be created but should be disabled, so we check this case here.
if (vps && !options && !configFileOptions && !environmentOptions) {
debug(`vite-plugin-svelte didn't pass options, inspector disabled`);
disabled = true;
return;
}
if (environmentOptions === true) {
inspectorOptions = defaultInspectorOptions;
} else {
inspectorOptions = {
...defaultInspectorOptions,
...configFileOptions,
...options,
...(environmentOptions || {})
};
}
inspectorOptions.__internal = {
base: config.base?.replace(/\/$/, '') || ''
};
},
async resolveId(importee, _, options) {
if (options?.ssr || disabled) {
return;
}
if (importee.startsWith('virtual:svelte-inspector-options')) {
return importee;
} else if (importee.startsWith('virtual:svelte-inspector-path:')) {
return importee.replace('virtual:svelte-inspector-path:', inspectorPath);
}
},
async load(id, options) {
if (options?.ssr || disabled) {
return;
}
if (id === 'virtual:svelte-inspector-options') {
return `export default ${JSON.stringify(inspectorOptions ?? {})}`;
} else if (id.startsWith(inspectorPath)) {
// read file ourselves to avoid getting shut out by vites fs.allow check
const file = cleanUrl(id);
if (fs.existsSync(id)) {
return await fs.promises.readFile(file, 'utf-8');
} else {
viteConfig.logger.error(
`[vite-plugin-svelte-inspector] failed to find svelte-inspector: ${id}`
);
}
}
},
transform(code, id, options) {
if (options?.ssr || disabled) {
return;
}
if (id.includes('vite/dist/client/client.mjs')) {
return { code: `${code}\nimport('virtual:svelte-inspector-path:load-inspector.js')` };
}
}
};
}

View File

@ -0,0 +1,61 @@
import { loadEnv } from 'vite';
import { debug } from './debug.js';
/** @type {import('.').Options} */
export const defaultInspectorOptions = {
toggleKeyCombo: process.platform === 'darwin' ? 'meta-shift' : 'control-shift',
navKeys: { parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' },
openKey: 'Enter',
holdMode: true,
showToggleButton: 'active',
toggleButtonPos: 'top-right',
customStyles: true
};
/**
* @param {import('vite').ResolvedConfig} config
* @returns {Partial<import('.').Options> | boolean | void}
*/
export function parseEnvironmentOptions(config) {
const env = loadEnv(config.mode, config.envDir ?? process.cwd(), 'SVELTE_INSPECTOR');
const options = env?.SVELTE_INSPECTOR_OPTIONS;
const toggle = env?.SVELTE_INSPECTOR_TOGGLE;
if (options) {
try {
const parsed = JSON.parse(options);
const parsedType = typeof parsed;
if (parsedType === 'boolean') {
return parsed;
} else if (parsedType === 'object') {
if (Array.isArray(parsed)) {
throw new Error('invalid type, expected object map but got array');
}
const parsedKeys = Object.keys(parsed);
const defaultKeys = Object.keys(defaultInspectorOptions);
const unknownKeys = parsedKeys.filter((k) => !defaultKeys.includes(k));
if (unknownKeys.length) {
config.logger.warn(
`[vite-plugin-svelte-inspector] ignoring unknown options in environment SVELTE_INSPECTOR_OPTIONS: ${unknownKeys.join(
', '
)}`
);
for (const key of unknownKeys) {
delete parsed[key];
}
}
debug('loaded environment config', parsed);
return parsed;
}
} catch (e) {
config.logger.error(
`[vite-plugin-svelte-inspector] failed to parse inspector options from environment SVELTE_INSPECTOR_OPTIONS="${options}"\n${e}`
);
}
} else if (toggle) {
const keyConfig = {
toggleKeyCombo: toggle
};
debug('loaded environment config', keyConfig);
return keyConfig;
}
}

View File

@ -0,0 +1,392 @@
<script>
// do not use TS here so that this component works in non-ts projects too
import { onMount } from 'svelte';
import options from 'virtual:svelte-inspector-options';
const toggle_combo = options.toggleKeyCombo?.toLowerCase().split('-');
const nav_keys = Object.values(options.navKeys).map((k) => k.toLowerCase());
let enabled = false;
let has_opened = false;
const icon = `data:image/svg+xml;base64,${btoa(
`
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="25" viewBox="0 0 107 128">
<title>svelte-inspector-logo</title>
<path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/>
<polygon points="0,0 15,40 40,20" stroke="#ff3e00" fill="#ff3e00"></polygon>
</svg>
`
.replace(/[\n\r\t\s]+/g, ' ')
.trim()
)}`;
// location of code in file
let file_loc;
// cursor pos and width for file_loc overlay positioning
let x, y, w;
let active_el;
let hold_start_ts;
$: show_toggle =
options.showToggleButton === 'always' || (options.showToggleButton === 'active' && enabled);
function mousemove(event) {
x = event.x;
y = event.y;
}
function find_selectable_parent(el, include_self = false) {
if (!include_self) {
el = el.parentNode;
}
while (el) {
if (is_selectable(el)) {
return el;
}
el = el.parentNode;
}
}
function find_selectable_child(el) {
return [...el.querySelectorAll('*')].find(is_selectable);
}
function find_selectable_sibling(el, prev = false) {
do {
el = prev ? el.previousElementSibling : el.nextElementSibling;
if (is_selectable(el)) {
return el;
}
} while (el);
}
function find_selectable_for_nav(key) {
const el = active_el;
if (!el) {
return find_selectable_child(document?.body);
}
switch (key) {
case options.navKeys.parent:
return find_selectable_parent(el);
case options.navKeys.child:
return find_selectable_child(el);
case options.navKeys.next:
return find_selectable_sibling(el) || find_selectable_parent(el);
case options.navKeys.prev:
return find_selectable_sibling(el, true) || find_selectable_parent(el);
default:
return;
}
}
function is_selectable(el) {
const file = el?.__svelte_meta?.loc?.file;
if (!file || file.includes('node_modules/')) {
return false; // no file or 3rd party
}
const id = el.getAttribute('id');
if (id === 'svelte-announcer' || id?.startsWith('svelte-inspector-')) {
return false; // ignore some elements by id that would be selectable from keyboard nav otherwise
}
return true;
}
function mouseover({ target }) {
const el = find_selectable_parent(target, true);
activate(el, false);
}
function activate(el, set_bubble_pos = true) {
if (options.customStyles && el !== active_el) {
if (active_el) {
active_el.classList.remove('svelte-inspector-active-target');
}
if (el) {
el.classList.add('svelte-inspector-active-target');
}
}
if (el) {
const { file, line, column } = el.__svelte_meta.loc;
file_loc = `${file}:${line + 1}:${column + 1}`;
} else {
file_loc = null;
}
active_el = el;
if (set_bubble_pos) {
const pos = el.getBoundingClientRect();
x = Math.ceil(pos.left);
y = Math.ceil(pos.bottom - 20);
}
}
function open_editor(event) {
if (file_loc) {
stop(event);
fetch(`${options.__internal.base}/__open-in-editor?file=${encodeURIComponent(file_loc)}`);
has_opened = true;
if (options.holdMode && is_holding()) {
disable();
}
}
}
function is_key_active(key, event) {
switch (key) {
case 'shift':
case 'control':
case 'alt':
case 'meta':
return event.getModifierState(key.charAt(0).toUpperCase() + key.slice(1));
default:
return key === event.key.toLowerCase();
}
}
function is_combo(event) {
return is_toggle(event) && toggle_combo?.every((key) => is_key_active(key, event));
}
function is_toggle(event) {
return toggle_combo?.includes(event.key.toLowerCase());
}
function is_nav(event) {
return nav_keys?.some((key) => is_key_active(key, event));
}
function is_open(event) {
return options.openKey && options.openKey.toLowerCase() === event.key.toLowerCase();
}
function is_holding() {
return hold_start_ts && Date.now() - hold_start_ts > 250;
}
function stop(event) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
}
function keydown(event) {
if (event.repeat || event.key == null || (!enabled && !is_toggle(event))) {
return;
}
if (is_combo(event)) {
toggle();
if (options.holdMode && enabled) {
hold_start_ts = Date.now();
}
} else if (enabled) {
if (is_nav(event)) {
const el = find_selectable_for_nav(event.key);
if (el) {
activate(el);
stop(event);
}
} else if (is_open(event)) {
open_editor(event);
} else if (is_holding()) {
// unhandled additional key pressed while holding, possibly another shortcut, disable again
disable();
}
}
}
function keyup(event) {
if (event.repeat || event.key == null || !enabled) {
return;
}
if (is_toggle(event)) {
if (is_holding()) {
disable();
} else {
hold_start_ts = null;
}
}
}
function toggle() {
enabled ? disable() : enable();
}
function listeners(body, enabled) {
const l = enabled ? body.addEventListener : body.removeEventListener;
l('mousemove', mousemove);
l('mouseover', mouseover);
l('click', open_editor, true);
}
function enable() {
enabled = true;
const b = document.body;
if (options.customStyles) {
b.classList.add('svelte-inspector-enabled');
}
listeners(b, enabled);
activate_initial_el();
}
function activate_initial_el() {
const hov = innermost_hover_el();
let el = find_selectable_parent(hov, true);
if (!el) {
const act = document.activeElement;
el = find_selectable_parent(act, true);
}
if (!el) {
el = find_selectable_child(document.body);
}
if (el) {
activate(el);
}
}
function innermost_hover_el() {
let e = document.body.querySelector(':hover');
let result;
while (e) {
result = e;
e = e.querySelector(':hover');
}
return result;
}
function disable() {
enabled = false;
has_opened = false;
hold_start_ts = null;
const b = document.body;
listeners(b, enabled);
if (options.customStyles) {
b.classList.remove('svelte-inspector-enabled');
active_el?.classList.remove('svelte-inspector-active-target');
}
active_el = null;
}
function visibilityChange() {
if (document.visibilityState === 'hidden') {
onLeave();
}
}
function onLeave() {
// disable if a file has been opened or combo is held
if (enabled && (has_opened || hold_start_ts)) {
disable();
}
}
onMount(() => {
const s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.setAttribute('id', 'svelte-inspector-style');
s.textContent = `:root { --svelte-inspector-icon: url(${icon})};`;
document.head.append(s);
if (toggle_combo) {
document.body.addEventListener('keydown', keydown);
if (options.holdMode) {
document.body.addEventListener('keyup', keyup);
}
}
document.addEventListener('visibilitychange', visibilityChange);
document.documentElement.addEventListener('mouseleave', onLeave);
return () => {
// make sure we get rid of everything
disable();
const s = document.head.querySelector('#svelte-inspector-style');
if (s) {
document.head.removeChild(s);
}
if (toggle_combo) {
document.body.removeEventListener('keydown', keydown);
if (options.holdMode) {
document.body.removeEventListener('keyup', keyup);
}
}
document.removeEventListener('visibilitychange', visibilityChange);
document.documentElement.removeEventListener('mouseleave', onLeave);
};
});
</script>
{#if show_toggle}
<button
id="svelte-inspector-toggle"
class:enabled
style={`background-image: var(--svelte-inspector-icon);${options.toggleButtonPos
.split('-')
.map((p) => `${p}: 8px;`)
.join('')}`}
on:click={() => toggle()}
aria-label={`${enabled ? 'disable' : 'enable'} svelte-inspector`}
/>
{/if}
{#if enabled && active_el && file_loc}
{@const loc = active_el.__svelte_meta.loc}
<div
id="svelte-inspector-overlay"
style:left="{Math.min(x + 3, document.documentElement.clientWidth - w - 10)}px"
style:top="{document.documentElement.clientHeight < y + 50 ? y - 30 : y + 30}px"
bind:offsetWidth={w}
>
&lt;{active_el.tagName.toLowerCase()}&gt;&nbsp;{file_loc}
</div>
<div id="svelte-inspector-announcer" aria-live="assertive" aria-atomic="true">
{active_el.tagName.toLowerCase()} in file {loc.file} on line {loc.line} column {loc.column}
</div>
{/if}
<style>
:global(body.svelte-inspector-enabled *) {
cursor: var(--svelte-inspector-icon), crosshair !important;
}
:global(.svelte-inspector-active-target) {
outline: 2px dashed #ff3e00 !important;
}
#svelte-inspector-overlay {
position: fixed;
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
padding: 2px 4px;
border-radius: 5px;
z-index: 999999;
pointer-events: none;
}
#svelte-inspector-toggle {
all: unset;
border: 1px solid #ff3e00;
border-radius: 8px;
position: fixed;
height: 32px;
width: 32px;
background-color: white;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
#svelte-inspector-announcer {
position: absolute;
left: 0px;
top: 0px;
clip: rect(0px, 0px, 0px, 0px);
clip-path: inset(50%);
overflow: hidden;
white-space: nowrap;
width: 1px;
height: 1px;
}
#svelte-inspector-toggle:not(.enabled) {
filter: grayscale(1);
}
#svelte-inspector-toggle:hover {
background-color: #facece;
}
</style>

View File

@ -0,0 +1,16 @@
// @ts-expect-error missing
// eslint-disable-next-line n/no-missing-import
import Inspector from 'virtual:svelte-inspector-path:Inspector.svelte';
function create_inspector_host() {
const id = 'svelte-inspector-host';
if (document.getElementById(id) != null) {
throw new Error('svelte-inspector-host element already exists');
}
const el = document.createElement('div');
el.setAttribute('id', id);
document.documentElement.appendChild(el);
return el;
}
new Inspector({ target: create_inspector_host() });

View File

@ -0,0 +1,8 @@
const postfixRE = /[?#].*$/s;
/**
* @param {string} url
*/
export function cleanUrl(url) {
return url.replace(postfixRE, '');
}