initial
This commit is contained in:
commit
74ae93a96e
24 changed files with 94691 additions and 0 deletions
121
joplin notion extension/Web Development/Javascript/Basics.md
Normal file
121
joplin notion extension/Web Development/Javascript/Basics.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
Basics
|
||||
https://www.w3schools.com/js/js_htmldom_document.asp
|
||||
- DOM manipulation
|
||||
- To remove a node
|
||||
use `formElement.remove()`
|
||||
- To append at last
|
||||
`formElement.appendChild()`
|
||||
- `remove` only needs a reference to the child. `removeChild` needs a reference both to the parent and the child. The result is identical.
|
||||
document.body.removeChild(formElement). here body is upper section where formElement is lower one
|
||||
- replaceChild(new, old)
|
||||
- finding through collections : instead of finding though css selectors we can find through collections like body,head,forms,images,links. So to find form element through id use
|
||||
`const x = document.forms["frm1"];`
|
||||
here `frm1` is id
|
||||
- `insertBefore(newNode,referenceNode)` : insert new node before refernce node
|
||||
```js
|
||||
// Get a reference to the parent node
|
||||
const parentDiv = document.getElementById("childElement").parentNode;
|
||||
|
||||
// Begin test case [ 1 ] : Existing childElement (all works correctly)
|
||||
let sp2 = document.getElementById("childElement");
|
||||
parentDiv.insertBefore(newNode, sp2);
|
||||
```
|
||||
- `insertAfter(newnode,referenceNode)` : insert new node after refernce node
|
||||
we can create it by
|
||||
```js
|
||||
function insertAfter(newNode, existingNode) {
|
||||
existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
|
||||
}
|
||||
```
|
||||
- Insert at first position
|
||||
`document.body.insertBefore(formElement,document.body.children[0])`
|
||||
- access child and parent element
|
||||
formElement.children => array of nodes
|
||||
formElement.parentElement => node
|
||||
- write vs appendChild
|
||||
https://stackoverflow.com/questions/22172589/document-write-vs-appendchild
|
||||
There is a difference between sequence. appendChild will execute on last but write during the stream
|
||||
eg:
|
||||
index1.html
|
||||
```html
|
||||
<script>
|
||||
console.log('1');
|
||||
var script = document.createElement('script');
|
||||
script.src = 'someScript.js';
|
||||
document.write(script.outerHTML);
|
||||
</script>
|
||||
<script>
|
||||
console.log('3');
|
||||
</script>
|
||||
```
|
||||
|
||||
index2.html
|
||||
```html
|
||||
<script>
|
||||
console.log('1');
|
||||
var script = document.createElement('script');
|
||||
script.src = 'someScript.js';
|
||||
document.body.appendChild(script);
|
||||
</script>
|
||||
<script>
|
||||
console.log('3');
|
||||
</script>
|
||||
```
|
||||
Output in 1st case will be `1,2,3` and in second case will be `1,3,2`.
|
||||
|
||||
- html
|
||||
innerHTML, innerText, textContent,outerHTML
|
||||
unlike innerHTML, outerHTML also include the outer structure too
|
||||
eg
|
||||
```js
|
||||
const div = document.createElement('div')
|
||||
div.innerHTML= `<p> Hello </p>`
|
||||
console.log(div.outerHTML) // outputs div and its innerHTML both
|
||||
```
|
||||
|
||||
|
||||
js maps
|
||||
```js
|
||||
const map = new Map();
|
||||
|
||||
map.set("a", 1);
|
||||
map.set("b", 2);
|
||||
map.set("c", 3);
|
||||
|
||||
console.log(map.get("a"));
|
||||
// Expected output: 1
|
||||
|
||||
map.set("a", 97);
|
||||
|
||||
console.log(map.get("a"));
|
||||
// Expected output: 97
|
||||
|
||||
console.log(map.size);
|
||||
// Expected output: 3
|
||||
|
||||
map.delete("b");
|
||||
|
||||
console.log(map.size);
|
||||
// Expected output: 2
|
||||
```
|
||||
|
||||
forEach is also supported in maps in latest version of js, in old versions they may not be supported so use
|
||||
`[...mapVariable].forEach` instead of `mapVariable.forEach`
|
||||
|
||||
|
||||
|
||||
collect all arrays from something and also being unique
|
||||
```js
|
||||
|
||||
|
||||
const VIDEOS = [
|
||||
{
|
||||
folder: "Nature Docs",
|
||||
title: "Coral Reef at Dawn",
|
||||
tags: ["ocean", "wildlife", "4k"],
|
||||
url: "https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
||||
},
|
||||
]
|
||||
|
||||
const allTags = [...new Set(VIDEOS.flatMap((v) => v.tags))].sort();
|
||||
```
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
Basics
|
||||
|
||||
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension
|
||||
|
||||
- For extension named borderify , directory order should be like this:
|
||||
```
|
||||
borderify/
|
||||
-- icons/
|
||||
---- border-48.png
|
||||
--borderify.js
|
||||
--manifest.json
|
||||
```
|
||||
- contents of manifest.json
|
||||
` "matches": ["*://*.mozilla.org/*"],` this means that extension will work for the domain **mozilla.org**
|
||||
```json
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Borderify",
|
||||
"version": "1.0",
|
||||
|
||||
"description": "Adds a red border to all webpages matching mozilla.org.",
|
||||
|
||||
"icons": {
|
||||
"48": "icons/border-48.png"
|
||||
},
|
||||
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["*://*.mozilla.org/*"],
|
||||
"js": ["borderify.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- Contents of borderify.js
|
||||
`document.body.style.border = "5px solid red";`
|
||||
|
||||
- Go to `about:debugging` in firefox url tab and click on load temporary extension and go to borderify folder and click on manifest.json as it links to every thing. now this extension is added until browser restart
|
||||
|
||||
|
||||
- ### More (popups and content script)*
|
||||
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension
|
||||

|
||||
|
||||
Structure
|
||||
```text
|
||||
beastify/
|
||||
|
||||
beasts/
|
||||
frog.jpg
|
||||
snake.jpg
|
||||
turtle.jpg
|
||||
|
||||
content_scripts/
|
||||
beastify.js
|
||||
|
||||
icons/
|
||||
beasts-32.png
|
||||
beasts-48.png
|
||||
|
||||
popup/
|
||||
choose_beast.css
|
||||
choose_beast.html
|
||||
choose_beast.js
|
||||
|
||||
manifest.json
|
||||
|
||||
```
|
||||
browser methods
|
||||
This browser object is a main difference between web apps and firefox add on as it let popup access paths and ability to communicate with content scripts.
|
||||
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API
|
||||
Some are
|
||||
`browser.`
|
||||
- `runttime.` : This module provides information about your extension and the environment it's running in.
|
||||
- `getURL` : get url for the path. this path is used to access resources of the extension whole folder
|
||||
eg: `browser.runtime.getURL("beasts/frog.jpg")`
|
||||
- `onMessage`: Use this event to listen for messages from another part of your extension.
|
||||
eg
|
||||
```js
|
||||
browser.runtime.onMessage.addListener((message)=>{
|
||||
if(message.command==="beastify") {
|
||||
insertBeast(message.beastURL);
|
||||
}
|
||||
else if( message.command === "reset" ){
|
||||
removeExistingBeasts();
|
||||
}
|
||||
})
|
||||
```
|
||||
- `tabs.`
|
||||
- `insertCSS` : to inject css to active tab. this is an asynchronous function that returns promise
|
||||
eg :
|
||||
```js
|
||||
const hidePage=`body > :not(.beastify-image){
|
||||
display : none;
|
||||
}`;
|
||||
|
||||
await browser.tabs.insertCSS({code: hidePage})
|
||||
|
||||
```
|
||||
- `sendMessage` : to send single message from extension background script(or popup_script or page_script) to content scripts. its an asynchronous function
|
||||
eg :
|
||||
```js
|
||||
browser.tabs.sendMessage(tabs[0].id, {
|
||||
command : "beastify",
|
||||
beastURL : url
|
||||
})
|
||||
```
|
||||
- `removeCSS` : to remove css from the page which was injected by insertCSS method. it wont remove original CSS of page
|
||||
eg : `await browser.tabs.removeCSS({code: hidePage})`
|
||||
- `query` : Gets all tabs that have the specified properties, or all tabs if no properties are specified. an asynchronous function that returns `Promise<array>`
|
||||
eg : `const tabs=await browser.tabs.query({active: true, currentWindow : true})`
|
||||
- `executeScript` : injects javascript code to page. It is available for manifest v2 only
|
||||
eg : `browser.tabs.executeScript({file: "/content_scripts/beastify.js"})`
|
||||
or
|
||||
`browser.tabs.executeScript({code: "console.log('hello')"`
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Chrome
|
||||
|
||||
- Simple one
|
||||
https://www.freecodecamp.org/news/building-chrome-extension/
|
||||
Manifest.json
|
||||
```json
|
||||
{
|
||||
"name": "Covid-19 Stats UK",
|
||||
"version": "1.0.0",
|
||||
"description": "latest covid data of UK",
|
||||
"manifest_version": 3,
|
||||
"author": "Sampurna Chapagain",
|
||||
"action":{
|
||||
"default_popup": "index.html",
|
||||
"default_title": "Latest Covid Report"
|
||||
}
|
||||
}
|
||||
```
|
||||
- Access active page dom
|
||||
https://infoheap.com/chrome-extension-tutorial-access-dom/
|
||||
https://www.sung.codes/blog/2019/getting-dom-content-from-chrome-extension-2
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Debugging
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Signing
|
||||
|
||||
- After uploading it and getting approved by firefox add on store we get uuid. so now if we wanna distribute it wothout firefox add on store as it may get unlisted so only way is using xpi or zip format
|
||||
Before packing it add uuid in **manifest.json** like this:
|
||||
browser_specific_settings > gecko > id
|
||||
i believe that's the structure
|
||||
|
||||
```json
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "{id-in-curlys}",
|
||||
"strict_min_version": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
firefox structure btw
|
||||
chromium bit different if you had planned to develop for that
|
||||
i think for chromium it's chrome_settings
|
||||
chrome_settings_overrides
|
||||
no not that
|
||||
it seems i'm mistaken
|
||||
both use same
|
||||
oh wait i'm not mistaken
|
||||
idk what chromium uses tho
|
||||
turns out you can also combine manifest for an extension
|
||||
use gecko for desktop
|
||||
and gecko_android for android
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
Tips
|
||||
|
||||
- Bypass caching
|
||||
When injecting link element for css file, the problem of caching can be annoying so append something in the url like this
|
||||
```js
|
||||
// Create a link element for the CSS file
|
||||
const linkElement = document.createElement('link');
|
||||
linkElement.rel = 'stylesheet';
|
||||
linkElement.href = browser.runtime.getURL('styles.css') + '?v=' + Date.now(); // Append a timestamp
|
||||
document.head.appendChild(linkElement);
|
||||
|
||||
```
|
||||
- Reset injected element
|
||||
When we inject DOM element and reload extension previous one wont get removed unless page is reloaded so tag all those inserted element with extension name or by adding it in class.
|
||||
`contentScript.js`
|
||||
```js
|
||||
|
||||
// removing elements of class of ext_name
|
||||
function reset1(){
|
||||
|
||||
const elements=document.querySelectorAll(`.${ext_name}`)
|
||||
|
||||
for(let ele of elements){
|
||||
ele.remove()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
reset1();
|
||||
|
||||
const navibar= document.createElement("div")
|
||||
navibar.className=`${ext_name} navigation_bar`
|
||||
navibar.innerHTML=`
|
||||
<button class=" nav_btn"> All Replies </button>
|
||||
`
|
||||
|
||||
|
||||
console.log('navibar: ',navibar.outerHTML);
|
||||
|
||||
|
||||
|
||||
const app=document.querySelector("body")
|
||||
app.insertBefore(navibar, app.children[0])
|
||||
|
||||
```
|
||||
|
||||
|
||||
in firefox to allow custom extensions for permanent without uploading in firefox
|
||||
|
||||
Type `about:config` in the address bar and press Enter
|
||||
Search for `xpinstall.signatures.required`.
|
||||
Ensure the value is set to false (toggle it by double-clicking if necessary).
|
||||
191
joplin notion extension/Web Development/Javascript/Extras.md
Normal file
191
joplin notion extension/Web Development/Javascript/Extras.md
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
Extras
|
||||
|
||||
- event delegation
|
||||
to detect events in child elements without need to attach listener to each of them
|
||||
```js
|
||||
// Assuming ulElement is a reference to your <ul> element
|
||||
const ulElement = document.querySelector('ul');
|
||||
|
||||
// Add a click event listener to the ul element
|
||||
ulElement.addEventListener('click', function(event) {
|
||||
// Check if the clicked element is an li element
|
||||
if (event.target.tagName === 'LI') {
|
||||
// Get the text content of the clicked li element
|
||||
const clickedText = event.target.textContent;
|
||||
|
||||
// Do something with the clicked text
|
||||
console.log('Clicked li:', clickedText);
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
- generate random string
|
||||
```js
|
||||
function generateRandomString(length) {
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
const charactersLength = characters.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Example usage:
|
||||
const randomString = generateRandomString(10); // Generates a random string of length 10
|
||||
console.log(randomString);
|
||||
|
||||
```
|
||||
- form data directly through form element
|
||||
Note : make sure that input element contains name attribute as its value is the key/field of formdata
|
||||
just use
|
||||
```js
|
||||
<form action="/route/api" method="POST">
|
||||
<input type="text" name="city">
|
||||
</form>
|
||||
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(e.currentTarget);
|
||||
|
||||
// Convert FormData to a plain object for logging
|
||||
const formDataObj = {};
|
||||
formData.forEach((value, key) => {
|
||||
formDataObj[key] = value;
|
||||
});
|
||||
|
||||
console.log(formDataObj); // This will log a plain object with form data
|
||||
|
||||
const response = await fetch("/addschool/api", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
};
|
||||
|
||||
```
|
||||
this will just Formdata which is not multipart but of urlencoded and field will be `city`
|
||||
|
||||
for multipart form data
|
||||
|
||||
```html
|
||||
<form onSubmit={onSubmit}>
|
||||
<input type="text" name="city">
|
||||
</form>
|
||||
```
|
||||
- extract query params from url
|
||||
```js
|
||||
let searchParams = new URLSearchParams(window.location.search);
|
||||
const value = searchParams.get('field_name');
|
||||
|
||||
```
|
||||
- form validation methods
|
||||
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#the-constraint-validation-api
|
||||
- to launch custom events use this
|
||||
```js
|
||||
const invalidEvent = new Event("invalid", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
|
||||
console.log("invalid event");
|
||||
e.target.dispatchEvent(invalidEvent);
|
||||
```
|
||||
|
||||
|
||||
|
||||
- Creating most apis easily
|
||||
To create mock api easily use something like json-server(simple way with less features) or hoverfly(complex way with more features)
|
||||
https://github.com/typicode/json-server
|
||||
https://github.com/SpectoLabs/hoverfly
|
||||
|
||||
|
||||
regex tip
|
||||
- When using parentheis for grouping in js, sometimes we just want to group and not to capture when usng exec method in js so use
|
||||
`/^(?:http|ftp):\/\/(.+)/` instead of `/^(http|ftp):\/\/(.+)/` .
|
||||
this `?:` signals exec to not capture
|
||||
|
||||
|
||||
conditionally set properties
|
||||
```js
|
||||
const isAdmin = true;
|
||||
|
||||
const user = {
|
||||
id: 1,
|
||||
name: "Alice",
|
||||
...(isAdmin && { role: "admin" }) // Spreads { role: "admin" } only if isAdmin is true
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
to convert intput element itno number easily use this
|
||||
```js
|
||||
const inputElement = document.getElementById("myInput");
|
||||
|
||||
// Returns a native JavaScript number directly (or NaN if empty/invalid)
|
||||
const num = inputElement.valueAsNumber;
|
||||
// const number = parseInt(inputElement.value)
|
||||
```
|
||||
|
||||
|
||||
|
||||
abort async tasks in between
|
||||
```js
|
||||
const processController = new AbortController();
|
||||
|
||||
async function performHeavyTask(signal) {
|
||||
try {
|
||||
console.log("Step 1 started...");
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Check if the event fired while Step 1 was running
|
||||
signal.throwIfAborted();
|
||||
|
||||
console.log("Step 2 started...");
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Check again before proceeding
|
||||
signal.throwIfAborted();
|
||||
|
||||
console.log("Task completed perfectly!");
|
||||
} catch (error) {
|
||||
if (error.name === 'AbortError') {
|
||||
console.log("Custom async workflow was stopped safely.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Triggering the stop on a custom event
|
||||
window.addEventListener('userLeftPage', () => {
|
||||
processController.abort();
|
||||
});
|
||||
|
||||
performHeavyTask(processController.signal);
|
||||
|
||||
```
|
||||
|
||||
for video hover and all this
|
||||
```js
|
||||
|
||||
let processController = null;
|
||||
|
||||
videoEle.addEventListener("mouseenter", () => {
|
||||
processController = new AbortController();
|
||||
|
||||
rotateThumbnails(processController.signal);
|
||||
});
|
||||
videoEle.addEventListener("mouseleave", () => {
|
||||
processController.abort();
|
||||
});
|
||||
```
|
||||
|
||||
to get content-type of response use
|
||||
|
||||
```js
|
||||
const response = await fetch('https://example.com');
|
||||
|
||||
// Get the raw content-type string (e.g., "application/json; charset=utf-8")
|
||||
const contentType = response.headers.get('content-type');
|
||||
console.log(contentType);
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
File handling
|
||||
|
||||
- Client(browser)
|
||||
|
||||
```jsx
|
||||
const encryptedFileInput = document.getElementById("encryptedFileInput");
|
||||
const encryptedFile = encryptedFileInput.files[0];
|
||||
|
||||
// Read the encrypted file
|
||||
const encryptedData = await encryptedFile.arrayBuffer();
|
||||
```
|
||||
- arrayBuffer vs blob
|
||||
blob is immutable and is the data type when we submit the file in form in client(browser)
|
||||
arraybuffer is the binary representation of file as thats how `fs.readFileSync` returns it
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Frameworks
|
||||
https://www.youtube.com/watch?v=WJRf7dh5Zws
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
Resources
|
||||
|
||||
- https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/README.md : book
|
||||
- https://www.udemy.com/course/the-complete-javascript-course/ : https://pixeldrain.com/l/wtrfxMof
|
||||
[The Complete JavaScript Course 2023 From Zero to Expert!.torrent](../../../_resources/The%20Complete%20JavaScript%20Course%202023%20From%20Zero%20to%20E.torrent)
|
||||
|
||||
- compare all js framwork
|
||||
https://component-party.dev/
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
Snippet links
|
||||
|
||||
- https://www.codingthai.com/tic-tac-toe-game-using-javascript/
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Setup
|
||||
|
||||
- `npm create tauri-app@latest` and then fill prompts to configure your project
|
||||
Then use `npm i`
|
||||
- to run project in dev mode use `npm run tauri dev`
|
||||
- to build use `npm run tauri build` . if facing problem in build then use `NO_STRIP=true npm run tauri build`
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
Basics
|
||||
|
||||
- By default if we inittialize variable we dont need to define type there as it will be automatically type inferenced.
|
||||
```ts
|
||||
let age = 30;
|
||||
```
|
||||
- Or we can use type annotations too
|
||||
```ts
|
||||
let age : number = 30;
|
||||
```
|
||||
- If we try to assign string then it will give error. Even if we dont add explicit type annotation `number` it will be still type inferenced as number so only way is to use type annotaion `any`.
|
||||
```ts
|
||||
let age : any = 30;
|
||||
age="31";
|
||||
```
|
||||
|
||||
|
||||
### Better workflow with tsconfig
|
||||
- Automating compiling and running commands by configuration
|
||||
- Initiate config file by
|
||||
`tsc --init`
|
||||
- Configure rootDir and outputDir to appropriate folders. These properties are in compilerOptions in tsconfig.json
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
|
||||
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs" /* Specify what module code is generated. */,
|
||||
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
||||
"noEmitOnError": true /* Disable emitting files if any type checking errors are reported. */,
|
||||
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
||||
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
Also set noEmitOnError as true to stop compiling from ts to js if there are errors.
|
||||
- Now instead of `tsc app.ts` `tsc` is enough but in order to compile to automatically when changed made and file is saved use `tsc --watch` in one instance of terminal. For running too when on save `node --watch dist/app.js`. watch flag for nodejs is only available for node version greater than 18.11.
|
||||
|
||||
### Arrays and Objects
|
||||
- for array containing only string values
|
||||
```ts
|
||||
let names: string[] = ["Mario", "Peach", "Feron"];
|
||||
```
|
||||
- for array containing string or number or boolean values
|
||||
```ts
|
||||
let things: (string | number | boolean)[] = [1, true, "hello"];
|
||||
const t: string | number | boolean = things[0];
|
||||
```
|
||||
|
||||
- **Objects literals**
|
||||
We can not only manage types but fields of objects too using interface like this.
|
||||
```ts
|
||||
let user: { firstname: string; age: number; id: number } = {
|
||||
firstname: "mario",
|
||||
age: 30,
|
||||
id: 1,
|
||||
};
|
||||
```
|
||||
So now all these 3 fields must be defined and no new field can be accessed or added too
|
||||
|
||||
### Functions
|
||||
- Function parameters type must be defined and as for return value of function can be type interfered on basis of return type. if no return then type will be interfered to void
|
||||
```ts
|
||||
function addTwoNumbers(a: number, b: number): number {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
const subtractTowNumbers = (a: number, b: number) : number => {
|
||||
return a + b;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Tuples
|
||||
```ts
|
||||
let person: [string, number, boolean] = ["mario", 30, true];
|
||||
```
|
||||
- here first value of array will be string, 2nd being number and 3rd being boolean and we cant have different type than specified. Purpose of tuple is to return/store multiple values in single variable
|
||||
```ts
|
||||
let xy: [number,number]
|
||||
xy = [74.7,20.1]
|
||||
```
|
||||
- From typesript version 4, these tuple elements can be named too for feedback, they cant be accessed in code by name but its for LSP only
|
||||
```ts
|
||||
let user: [name: string, age: number]
|
||||
|
||||
user= ['peach',25]
|
||||
console.log(user[0])
|
||||
```
|
||||
|
||||
### Interfaces
|
||||
- Ability to create custom types for objects, arrays,etc
|
||||
- For Objects
|
||||
```ts
|
||||
// interfaces
|
||||
interface Author {
|
||||
name: string;
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
const authorOne: Author = { name: "mario", avatar: "img/mario/png" };
|
||||
|
||||
interface Post {
|
||||
title: string;
|
||||
body: string;
|
||||
tags: string[];
|
||||
create_at: Date;
|
||||
author: Author;
|
||||
}
|
||||
|
||||
const newPost: Post = {
|
||||
title: "my first post",
|
||||
body: "something interesting",
|
||||
tags: ["gaming", "tech"],
|
||||
create_at: new Date(),
|
||||
author: authorOne,
|
||||
};
|
||||
|
||||
function createPost(post: Post): void {
|
||||
console.log(`Create post ${post.title} by ${post.author.name}`);
|
||||
}
|
||||
|
||||
createPost(newPost);
|
||||
|
||||
//interfaces in arrays
|
||||
let posts: Post[] = [];
|
||||
posts.push(newPost);
|
||||
```
|
||||
|
||||
### Type aliases
|
||||
- Assigning name to types like tuples and object literals
|
||||
- Example
|
||||
```ts
|
||||
type Rgb = [number, number, number];
|
||||
function getRandomColor(): Rgb {
|
||||
const r = Math.floor(Math.random() * 255);
|
||||
const g = Math.floor(Math.random() * 255);
|
||||
const b = Math.floor(Math.random() * 255);
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
const colorOne = getRandomColor();
|
||||
const colorTwo = getRandomColor();
|
||||
console.log(colorOne, colorTwo);
|
||||
|
||||
type User = {
|
||||
name: string;
|
||||
score: number;
|
||||
};
|
||||
|
||||
const userOne: User = { name: "mario", score: 75 };
|
||||
|
||||
function formatUser(user: User): void {
|
||||
console.log(`${user.name} has a score of ${user.score} `);
|
||||
}
|
||||
|
||||
formatUser(userOne);
|
||||
formatUser({ name: "yoshi", score: 100 });
|
||||
```
|
||||
|
||||
Union
|
||||
- Union are in C/C++ too and is used to store values of different data type. Unlike structures which is used to store multiple values in same record, union can store only one value and its usecase is when we dont know fixed data type but know range of data type .
|
||||
- Example
|
||||
```ts
|
||||
// unions types
|
||||
|
||||
let someId: number | String
|
||||
|
||||
someId=1
|
||||
someId='2'
|
||||
|
||||
let email : string|null= null
|
||||
|
||||
email = 'mario@netninja.dev'
|
||||
|
||||
type Id = number | string
|
||||
|
||||
function swapIdType(id: Id): Id {
|
||||
// can only use props and methods common to both number and string
|
||||
// parseInt(id) // => this will result in error
|
||||
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
```
|
||||
|
||||
### Type Guards
|
||||
- Allows us to methods and props of particular type even it is not available for other type
|
||||
- typescript compiler is smart enough and when we use typeof to create a if block we can use methods of particular type
|
||||
```ts
|
||||
type Id = number | string;
|
||||
|
||||
function swapIdType(id: Id): Id {
|
||||
// can only use props and methods common to both number and string
|
||||
// parseInt(id) // => this will result in error
|
||||
|
||||
// so in order to use methods of particular type type guards is necessary
|
||||
if (typeof id === "string") {
|
||||
// can use string methods
|
||||
return parseInt(id);
|
||||
} else {
|
||||
return id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
const idOne = swapIdType(1);
|
||||
const idTwo = swapIdType("2");
|
||||
|
||||
console.log(idOne, idTwo);
|
||||
```
|
||||
- Tagging interfaces to differenciate them in case there is union of interfaces. Means in interface, we can set propery say type and assign it as same name as of interface. Normally we assign types but in this case we have assigned it as hardcoded string
|
||||
```ts
|
||||
// Union of interfaces
|
||||
interface User3 {
|
||||
type: "User3";
|
||||
username: string;
|
||||
email: string;
|
||||
id: Id;
|
||||
}
|
||||
|
||||
interface Person {
|
||||
type: "Person";
|
||||
firstname: string;
|
||||
age: number;
|
||||
id: Id;
|
||||
}
|
||||
|
||||
function logDetails(value: User3 | Person): void {
|
||||
if (value.type === "User3") {
|
||||
console.log(value.email, value.username);
|
||||
}
|
||||
|
||||
if (value.type === "Person") {
|
||||
console.log(value.firstname, value.age);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
**interface for nested objeects**
|
||||
|
||||
Index Signature (Standard Approach)
|
||||
```ts
|
||||
interface UserProfile {
|
||||
name: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
// This interface accepts ANY key name, but enforces the UserProfile value
|
||||
interface TeamRoles {
|
||||
[roleName: string]: UserProfile;
|
||||
}
|
||||
|
||||
// 🟩 Valid usage: You can name the keys whatever you want
|
||||
const team: TeamRoles = {
|
||||
manager: { name: "Alice", role: "Manager" },
|
||||
lead: { name: "Bob", role: "Tech Lead" },
|
||||
intern: { name: "Charlie", role: "Intern" },
|
||||
consultant: { name: "Diana", role: "Advisor" } // Any new key works seamlessly
|
||||
};
|
||||
|
||||
```
|
||||
or for inline approach
|
||||
|
||||
```ts
|
||||
interface UserProfile {
|
||||
name: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
// You can use the Record type directly on your variable
|
||||
const flexibleTeam: Record<string, UserProfile> = {
|
||||
manager: { name: "Alice", role: "Manager" },
|
||||
lead: { name: "Bob", role: "Tech Lead" }
|
||||
};
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Intro
|
||||
https://www.youtube.com/playlist?list=PL4cUxeGkcC9gNhFQgS4edYLqP7LkZcFMN
|
||||
|
||||
Why Typescript
|
||||
- Reducing run time errors
|
||||
- Autocompletion and feedback(code hints)
|
||||
- Custom types : Able to make our own types using interfaces, classea and type aliases
|
||||
|
||||
Installing and Compiling
|
||||
- Install typescript by
|
||||
`npm i -g typscript`
|
||||
- Compile it and run it
|
||||
`tsc app.ts && node app.js`
|
||||
Compiling it with produce js file of same name
|
||||
- Sample code
|
||||
```ts
|
||||
const err = "sasas";
|
||||
|
||||
let str: string;
|
||||
|
||||
str = "1";
|
||||
|
||||
console.log(str);
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
imports and exports
|
||||
|
||||
**exporting types**
|
||||
```ts
|
||||
export interface VideoData {
|
||||
title: string;
|
||||
path: string;
|
||||
description: string;
|
||||
}
|
||||
```
|
||||
|
||||
**importing it**
|
||||
```ts
|
||||
import type { VideoData } from "./types";
|
||||
// or
|
||||
import type types = require("./types");
|
||||
```
|
||||
|
||||
both method can be used as exporting and importing type codes are not included in conveted js file so it dont matter if its es or commonjs
|
||||
|
||||
|
||||
|
||||
### attaching types for imported variables
|
||||
|
||||
|
||||
**for commonjs**
|
||||
|
||||
index.ts
|
||||
```ts
|
||||
const { videoData } = require("./constants") as {
|
||||
videoData: VideoData[];
|
||||
};
|
||||
```
|
||||
|
||||
constants.ts
|
||||
```ts
|
||||
import type { VideoData } from "./types";
|
||||
|
||||
const videoData: VideoData[] = [
|
||||
{
|
||||
title: "fallout new vegas burning sj and dermont",
|
||||
path: "/home/hpmi/Videos/fnv burning sj and dermont.mp4",
|
||||
description: "killing child traffickers brutally in fallout new vegas",
|
||||
},
|
||||
];
|
||||
|
||||
module.exports = { videoData };
|
||||
```
|
||||
|
||||
for esmodule
|
||||
|
||||
```ts
|
||||
export const videoData: VideoData = {
|
||||
title: "test",
|
||||
size: 123,
|
||||
duration: 60
|
||||
};
|
||||
|
||||
import { videoData } from "./constants";
|
||||
```
|
||||
|
||||
no need use `as` as it is automatically inferred in case of esmodule
|
||||
|
||||
|
||||
### importing libraries or inbuilt modules
|
||||
- if importing any modules like `fs` then import it like this
|
||||
```ts
|
||||
const fs = require("fs") as typeof import("fs");
|
||||
```
|
||||
and make sure to have `@types/node` module installed as dev dependency module by
|
||||
`npm install --save-dev @types/node`
|
||||
in case of esmodule simply `import fs from "fs";` will work
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Uploading file through axios
|
||||
|
||||
```jsx
|
||||
const fs = require('fs');
|
||||
const FormData = require('form-data');
|
||||
const axios = require('axios');
|
||||
|
||||
const file = fs.readFileSync('image_icon.png');
|
||||
const url = 'https://sdrive.app/publicapi/upload';
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file, { filename: 'image_icon.png' }); // Specify the filename when appending the file
|
||||
|
||||
axios.post(url, formData, {
|
||||
headers: {
|
||||
...formData.getHeaders() // Include headers from FormData
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
console.log('File uploaded successfully:', response.data);
|
||||
// Handle the response data as needed
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
// Handle any errors that occurred during the upload
|
||||
});
|
||||
```
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
Using form-urlencoded
|
||||
https://stackoverflow.com/questions/35325370/how-do-i-post-a-x-www-form-urlencoded-request-using-fetch
|
||||
|
||||
```js
|
||||
const requestBody = new URLSearchParams({
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
code: code,
|
||||
grant_type: "authorization_code",
|
||||
});
|
||||
|
||||
fetch(apiUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: requestBody,
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Handle the response data here
|
||||
console.log(data);
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle errors here
|
||||
console.error("Error:", error);
|
||||
});
|
||||
```
|
||||
|
||||
Curl equivalent
|
||||
```bash
|
||||
curl -i -X POST "https://api.box.com/oauth2/token" \
|
||||
-H "content-type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=[CLIENT_ID]" \
|
||||
-d "client_secret=[CLIENT_SECRET]" \
|
||||
-d "code=[CODE]" \
|
||||
-d "grant_type=authorization_code"
|
||||
|
||||
```
|
||||
|
||||
2nd method
|
||||
```js
|
||||
var details = {
|
||||
'userName': 'test@gmail.com',
|
||||
'password': 'Password!',
|
||||
'grant_type': 'password'
|
||||
};
|
||||
|
||||
var formBody = [];
|
||||
for (var property in details) {
|
||||
var encodedKey = encodeURIComponent(property);
|
||||
var encodedValue = encodeURIComponent(details[property]);
|
||||
formBody.push(encodedKey + "=" + encodedValue);
|
||||
}
|
||||
formBody = formBody.join("&");
|
||||
|
||||
fetch('https://example.com/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
||||
},
|
||||
body: formBody
|
||||
})
|
||||
```
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
blob file download
|
||||
|
||||
```jsx
|
||||
const download=()=>{
|
||||
fetch(`${HOST}`,{
|
||||
|
||||
})
|
||||
.then(res=>res.blob())
|
||||
.then(blob=>{
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.download = "extraordinary12.mp3";
|
||||
link.href = url;
|
||||
link.click();
|
||||
})
|
||||
.catch(console.log)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
creating a text blob
|
||||
```js
|
||||
const textData = "Hello, this is my text content!";
|
||||
const textBlob = new Blob([textData], { type: 'text/plain' });
|
||||
```
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
capacitor
|
||||
|
||||
https://capacitorjs.com/docs/getting-started
|
||||
and
|
||||
https://github.com/fruzelee/capacitor-web2app/tree/main
|
||||
|
||||
in terminal create project
|
||||
|
||||
`npm init @capacitor/app@latest`
|
||||
it will be interactive so select app name, name of directory and app id (com.example.appname)
|
||||
|
||||
`npm i` this will download capacitor/core and capacitor/cli
|
||||
|
||||
|
||||
then
|
||||
**2nd section**
|
||||
|
||||
`npx cap init`
|
||||
|
||||
`npm i @capacitor/android`
|
||||
|
||||
then
|
||||
|
||||
`npm run build`
|
||||
|
||||
`npx cap add android`
|
||||
|
||||
|
||||
instead of `npm init @capacitor/app@latest` use vite to simply create a vanilla one
|
||||
`npm create vite@latest`
|
||||
and then install
|
||||
`npm install @capacitor/cli @capacitor/core`
|
||||
|
||||
then from 2nd section
|
||||
|
||||
|
||||
status bar fix
|
||||
https://capacitorjs.com/docs/apis/status-bar
|
||||
|
||||
install this and then in configs add it and in js file
|
||||
```js
|
||||
import { StatusBar, Style } from '@capacitor/status-bar';
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await StatusBar.setStyle({ style: Style.Dark }); // Forces white icons
|
||||
} catch (e) {
|
||||
console.error("Status bar styling failed", e);
|
||||
}
|
||||
}, 200);
|
||||
```
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
check file type
|
||||
|
||||
```js
|
||||
const isFileImage = (file) => {
|
||||
return file && file["type"].split("/")[0] === "image";
|
||||
};
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue