aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/naive.plugin.ts2
-rw-r--r--src/tools/chmod-calculator/chmod-calculator.service.test.ts68
-rw-r--r--src/tools/chmod-calculator/chmod-calculator.service.ts17
-rw-r--r--src/tools/chmod-calculator/chmod-calculator.types.ts10
-rw-r--r--src/tools/chmod-calculator/chmod-calculator.vue83
-rw-r--r--src/tools/chmod-calculator/index.ts22
-rw-r--r--src/tools/index.ts3
7 files changed, 204 insertions, 1 deletions
diff --git a/src/plugins/naive.plugin.ts b/src/plugins/naive.plugin.ts
index 981d787..2a9ac82 100644
--- a/src/plugins/naive.plugin.ts
+++ b/src/plugins/naive.plugin.ts
@@ -53,9 +53,11 @@ import {
NTooltip,
NUpload,
NUploadDragger,
+ NCheckbox,
} from 'naive-ui';
const components = [
+ NCheckbox,
NDynamicInput,
NDatePicker,
NCode,
diff --git a/src/tools/chmod-calculator/chmod-calculator.service.test.ts b/src/tools/chmod-calculator/chmod-calculator.service.test.ts
new file mode 100644
index 0000000..fafb393
--- /dev/null
+++ b/src/tools/chmod-calculator/chmod-calculator.service.test.ts
@@ -0,0 +1,68 @@
+import { expect, describe, it } from 'vitest';
+import { computeChmodOctalRepresentation } from './chmod-calculator.service';
+
+describe('chmod-calculator', () => {
+ describe('computeChmodOctalRepresentation', () => {
+ it('get the octal representation from permissions', () => {
+ expect(
+ computeChmodOctalRepresentation({
+ permissions: {
+ owner: { read: true, write: true, execute: true },
+ group: { read: true, write: true, execute: true },
+ public: { read: true, write: true, execute: true },
+ },
+ }),
+ ).to.eql('777');
+
+ expect(
+ computeChmodOctalRepresentation({
+ permissions: {
+ owner: { read: false, write: false, execute: false },
+ group: { read: false, write: false, execute: false },
+ public: { read: false, write: false, execute: false },
+ },
+ }),
+ ).to.eql('000');
+
+ expect(
+ computeChmodOctalRepresentation({
+ permissions: {
+ owner: { read: false, write: true, execute: false },
+ group: { read: false, write: true, execute: true },
+ public: { read: true, write: false, execute: true },
+ },
+ }),
+ ).to.eql('235');
+
+ expect(
+ computeChmodOctalRepresentation({
+ permissions: {
+ owner: { read: true, write: false, execute: false },
+ group: { read: false, write: true, execute: false },
+ public: { read: false, write: false, execute: true },
+ },
+ }),
+ ).to.eql('421');
+
+ expect(
+ computeChmodOctalRepresentation({
+ permissions: {
+ owner: { read: false, write: false, execute: true },
+ group: { read: false, write: true, execute: false },
+ public: { read: true, write: false, execute: false },
+ },
+ }),
+ ).to.eql('124');
+
+ expect(
+ computeChmodOctalRepresentation({
+ permissions: {
+ owner: { read: false, write: true, execute: false },
+ group: { read: false, write: true, execute: false },
+ public: { read: false, write: true, execute: false },
+ },
+ }),
+ ).to.eql('222');
+ });
+ });
+});
diff --git a/src/tools/chmod-calculator/chmod-calculator.service.ts b/src/tools/chmod-calculator/chmod-calculator.service.ts
new file mode 100644
index 0000000..8953551
--- /dev/null
+++ b/src/tools/chmod-calculator/chmod-calculator.service.ts
@@ -0,0 +1,17 @@
+import _ from 'lodash';
+import type { GroupPermissions, Permissions } from './chmod-calculator.types';
+
+export { computeChmodOctalRepresentation };
+
+function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string {
+ const permissionValue = { read: 4, write: 2, execute: 1 };
+
+ const getGroupPermissionValue = (permission: GroupPermissions) =>
+ _.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(permissionValue, key, 0) : 0), 0);
+
+ return [
+ getGroupPermissionValue(permissions.owner),
+ getGroupPermissionValue(permissions.group),
+ getGroupPermissionValue(permissions.public),
+ ].join('');
+}
diff --git a/src/tools/chmod-calculator/chmod-calculator.types.ts b/src/tools/chmod-calculator/chmod-calculator.types.ts
new file mode 100644
index 0000000..d3dc915
--- /dev/null
+++ b/src/tools/chmod-calculator/chmod-calculator.types.ts
@@ -0,0 +1,10 @@
+export type Scope = 'read' | 'write' | 'execute';
+export type Group = 'owner' | 'group' | 'public';
+
+export type GroupPermissions = {
+ [k in Scope]: boolean;
+};
+
+export type Permissions = {
+ [k in Group]: GroupPermissions;
+};
diff --git a/src/tools/chmod-calculator/chmod-calculator.vue b/src/tools/chmod-calculator/chmod-calculator.vue
new file mode 100644
index 0000000..31f8b9f
--- /dev/null
+++ b/src/tools/chmod-calculator/chmod-calculator.vue
@@ -0,0 +1,83 @@
+<template>
+ <div>
+ <n-table :bordered="false" :bottom-bordered="false" single-column class="permission-table">
+ <thead>
+ <tr>
+ <th class="text-center" scope="col"></th>
+ <th class="text-center" scope="col">Owner (u)</th>
+ <th class="text-center" scope="col">Group (g)</th>
+ <th class="text-center" scope="col">Public (o)</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="{ scope, title } of scopes" :key="scope">
+ <td class="line-header">{{ title }}</td>
+ <td v-for="group of groups" :key="group" class="text-center">
+ <!-- <n-switch v-model:value="permissions[group][scope]" /> -->
+ <n-checkbox v-model:checked="permissions[group][scope]" size="large" />
+ </td>
+ </tr>
+ </tbody>
+ </n-table>
+
+ <div class="octal-result">
+ {{ octal }}
+ </div>
+
+ <input-copyable :value="`chmod ${octal} path`" readonly style="margin-bottom: 5px" />
+ </div>
+</template>
+
+<script setup lang="ts">
+import { useThemeVars } from 'naive-ui';
+import { computed, ref } from 'vue';
+import { computeChmodOctalRepresentation } from './chmod-calculator.service';
+import InputCopyable from '../../components/InputCopyable.vue';
+
+import type { Group, Scope } from './chmod-calculator.types';
+
+const themeVars = useThemeVars();
+
+const scopes: { scope: Scope; title: string }[] = [
+ { scope: 'read', title: 'Read (4)' },
+ { scope: 'write', title: 'Write (2)' },
+ { scope: 'execute', title: 'Execute (1)' },
+];
+const groups: Group[] = ['owner', 'group', 'public'];
+
+const permissions = ref({
+ owner: { read: false, write: false, execute: false },
+ group: { read: false, write: false, execute: false },
+ public: { read: false, write: false, execute: false },
+});
+
+const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value }));
+</script>
+
+<style lang="less" scoped>
+.octal-result {
+ text-align: center;
+ font-size: 50px;
+ font-family: monospace;
+ color: v-bind('themeVars.primaryColor');
+ margin: 20px 0;
+}
+.permission-table {
+ td,
+ th {
+ padding: 15px;
+
+ @media screen and (max-width: 600px) {
+ padding: 5px;
+ }
+ }
+}
+.line-header {
+ font-weight: bold;
+ text-align: right;
+ max-width: 80px;
+}
+.text-center {
+ text-align: center;
+}
+</style>
diff --git a/src/tools/chmod-calculator/index.ts b/src/tools/chmod-calculator/index.ts
new file mode 100644
index 0000000..7d299e4
--- /dev/null
+++ b/src/tools/chmod-calculator/index.ts
@@ -0,0 +1,22 @@
+import { FileInvoice } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Chmod calculator',
+ path: '/chmod-calculator',
+ description: 'Compute your chmod permissions and commands with this online chmod calculator.',
+ keywords: [
+ 'chmod',
+ 'calculator',
+ 'file',
+ 'permission',
+ 'files',
+ 'directory',
+ 'folder',
+ 'recursive',
+ 'generator',
+ 'octal',
+ ],
+ component: () => import('./chmod-calculator.vue'),
+ icon: FileInvoice,
+});
diff --git a/src/tools/index.ts b/src/tools/index.ts
index bc5192a..60ad21d 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,6 +1,7 @@
import { LockOpen } from '@vicons/tabler';
import type { ToolCategory } from './tool';
+import { tool as chmodCalculator } from './chmod-calculator';
import { tool as mimeTypes } from './mime-types';
import { tool as otpCodeGeneratorAndValidator } from './otp-code-generator-and-validator';
import { tool as base64FileConverter } from './base64-file-converter';
@@ -77,7 +78,7 @@ export const toolsByCategory: ToolCategory[] = [
{
name: 'Development',
icon: LockOpen,
- components: [gitMemo, randomPortGenerator, crontabGenerator, jsonViewer, sqlPrettify],
+ components: [gitMemo, randomPortGenerator, crontabGenerator, jsonViewer, sqlPrettify, chmodCalculator],
},
{
name: 'Math',
itle='2022-04-26 18:12:17 -0400'>2022-04-26Revert "fix: replace serialize-javascript & random-bytes with custom internal...Gravatar Nate Moore 7-565/+215 2022-04-26[ci] formatGravatar okikio 2-271/+315 2022-04-26fix: replace serialize-javascript & random-bytes with custom internal modulesGravatar Okiki 7-215/+521 2022-04-26[ci] release (#3182)create-astro@0.10.0astro@1.0.0-beta.18@astrojs/vercel@0.1.4@astrojs/tailwind@0.2.1@astrojs/svelte@0.1.2@astrojs/netlify@0.3.3Gravatar github-actions[bot] 54-146/+130 2022-04-26[ci] formatGravatar matthewp 1-1/+1 2022-04-26fix(vercel): `trailingSlash` fix for non-html pages (#3185)Gravatar Juan Martín Seery 2-29/+42 2022-04-26Prevent watcher from running during the build (#3207)Gravatar Matthew Phillips 2-0/+9 2022-04-26Fix lockfile (#3210)Gravatar Juan Martín Seery 1-6/+0 2022-04-26Add missing is:raw in AstroBuiltinAttributes (#3209)Gravatar Erika 2-0/+6 2022-04-26Feat: support `astro add` without npm installing (#3183)Gravatar Ben Holmes 6-30/+49 2022-04-26Add Astro attributes to svg elements (#3205)Gravatar Erika 2-1/+9 2022-04-26[ci] formatGravatar bholmesdev 2-9/+9 2022-04-26Feat: `create astro` add install step (#3190)Gravatar Ben Holmes 7-162/+299 2022-04-26[ci] collect statsGravatar FredKSchott 1-0/+1 2022-04-25fix(markdown): file.url fixes (#3198)Gravatar Juan Martín Seery 11-10/+149 2022-04-25[ci] collect statsGravatar FredKSchott 1-0/+1 2022-04-24add vite to licenseGravatar Fred K. Schott 2-24/+29 2022-04-24feat(markdown): Improved types (#3191)Gravatar Juan Martín Seery 3-6/+47 2022-04-24[ci] collect statsGravatar FredKSchott 1-0/+1 2022-04-23[ci] collect statsGravatar FredKSchott 1-0/+1