Skip to content

Commit a8f8fff

Browse files
committed
Merge branch 'feat/mongo-objectid' into chore/all-my-stuffs
# Conflicts: # components.d.ts # src/tools/index.ts
2 parents f9c4d34 + 382a5cc commit a8f8fff

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { tool as certificateKeyParser } from './certificate-key-parser';
4444
import { tool as crcCalculator } from './crc-calculator';
4545
import { tool as ipGeoLocation } from './ip-geo-location';
4646
import { tool as safelinkDecoder } from './safelink-decoder';
47+
import { tool as mongoObjectidConverter } from './mongo-objectid-converter';
4748
import { tool as xmlToJson } from './xml-to-json';
4849
import { tool as jsonToXml } from './json-to-xml';
4950
import { tool as regexTester } from './regex-tester';
@@ -273,6 +274,7 @@ export const toolsByCategory: ToolCategory[] = [
273274
jqMemo,
274275
jsonpathMemo,
275276
jsonToSchema,
277+
mongoObjectidConverter,
276278
],
277279
},
278280
{
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Database } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'MongoDB ObjectId Converter',
6+
path: '/mongo-objectid-converter',
7+
description: 'Convert between MongoDB ObjectId and internal timestamp',
8+
keywords: ['mongo', 'objectid', 'converter', 'timestamp'],
9+
component: () => import('./mongo-objectid-converter.vue'),
10+
icon: Database,
11+
createdAt: new Date('2024-08-15'),
12+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { dateFromObjectId, generateMongoFilter, objectIdFromDate, objectIdSyntaxFromDate } from './mongo-objectid-converter.service';
3+
4+
describe('mongo-objectid-converter', () => {
5+
describe('objectIdFromDate', () => {
6+
it('convert a Date to ObjectId', () => {
7+
expect(objectIdFromDate(new Date(Date.UTC(2024, 0, 1)))).to.eql('659200800000000000000000');
8+
expect(objectIdFromDate(new Date(Date.UTC(2024, 0, 1, 12, 12, 12)))).to.eql('6592ac1c0000000000000000');
9+
});
10+
});
11+
describe('objectIdSyntaxFromDate', () => {
12+
it('convert a Date to ObjectId', () => {
13+
expect(objectIdSyntaxFromDate(new Date(Date.UTC(2024, 0, 1)))).to.eql('ObjectId("659200800000000000000000")');
14+
});
15+
});
16+
describe('dateFromObjectId', () => {
17+
it('convert an ObjectId to Date', () => {
18+
expect(dateFromObjectId('659200800000000000000000')).to.eql(new Date(Date.UTC(2024, 0, 1)));
19+
expect(dateFromObjectId('6592ac1c0000000000000000')).to.eql(new Date(Date.UTC(2024, 0, 1, 12, 12, 12)));
20+
});
21+
});
22+
describe('generateMongoFilter', () => {
23+
it('convert a date to mongo query', () => {
24+
expect(generateMongoFilter({
25+
date: new Date(Date.UTC(2024, 0, 1, 12, 12, 12)),
26+
tableName: 'comments',
27+
})).to.eql('db.comments.find({_id: {$gt: ObjectId("6592ac1c0000000000000000")}})');
28+
});
29+
});
30+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export function objectIdFromDate(date: Date) {
2+
return `${Math.floor(date.getTime() / 1000).toString(16)}0000000000000000`;
3+
};
4+
5+
export function objectIdSyntaxFromDate(date: Date) {
6+
return `ObjectId("${objectIdFromDate(date)}")`;
7+
};
8+
9+
export function generateMongoFilter(
10+
{
11+
tableName, date, operator = 'gt',
12+
}:
13+
{
14+
tableName: string
15+
date: Date
16+
operator?: 'gt' | 'lt'
17+
}) {
18+
return `db.${tableName}.find({_id: {$${operator}: ObjectId("${objectIdFromDate(date)}")}})`;
19+
}
20+
21+
export function dateFromObjectId(objectId: string) {
22+
return new Date(Number.parseInt(objectId.substring(0, 8), 16) * 1000);
23+
};
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<script setup lang="ts">
2+
import { dateFromObjectId, generateMongoFilter, objectIdFromDate, objectIdSyntaxFromDate } from './mongo-objectid-converter.service';
3+
import { withDefaultOnError } from '@/utils/defaults';
4+
5+
const currentTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
6+
7+
const objectIdInput = ref(objectIdFromDate(new Date()));
8+
const dateOutput = computed(() =>
9+
withDefaultOnError(() => dateFromObjectId(objectIdInput.value), 'Invalid ObjectId'),
10+
);
11+
12+
const dateInput = ref(Date.now());
13+
const dateValue = computed(() => new Date(dateInput.value));
14+
const tableName = ref('tbl');
15+
const objectIdOutput = computed(() =>
16+
withDefaultOnError(() => objectIdFromDate(dateValue.value), 'Invalid Date'),
17+
);
18+
const objectIdSyntaxOutput = computed(() =>
19+
withDefaultOnError(() => objectIdSyntaxFromDate(dateValue.value), 'Invalid Date'),
20+
);
21+
const objectIdQueryOutput = computed(() =>
22+
withDefaultOnError(() => generateMongoFilter({ date: dateValue.value, tableName: tableName.value }), 'Invalid Date'),
23+
);
24+
const objectIdUTCDate = computed(() =>
25+
dateValue.value.toISOString(),
26+
);
27+
</script>
28+
29+
<template>
30+
<c-card :title="`ObjectId to Date (${currentTimeZone})`">
31+
<c-input-text
32+
v-model:value="objectIdInput"
33+
placeholder="Put your ObjectId here..."
34+
label="ObjectId to encode"
35+
raw-text
36+
mb-5
37+
/>
38+
39+
<n-divider />
40+
41+
<textarea-copyable
42+
:value="dateOutput instanceof Date ? dateOutput.toLocaleString(undefined, { timeZoneName: 'short' }) : dateOutput"
43+
/>
44+
<textarea-copyable
45+
:value="dateOutput instanceof Date ? dateOutput.toISOString() : dateOutput"
46+
/>
47+
</c-card>
48+
49+
<c-card :title="`Date to ObjectId (${currentTimeZone})`">
50+
<n-form-item label="Date and time" label-placement="left" mb-2 flex-1>
51+
<n-date-picker v-model:value="dateInput" type="datetime" />
52+
</n-form-item>
53+
54+
<c-input-text
55+
v-model:value="tableName"
56+
placeholder="Put your Table Name here..."
57+
label="Table Name"
58+
label-position="left"
59+
raw-text
60+
mb-5
61+
/>
62+
63+
<textarea-copyable :value="objectIdUTCDate" />
64+
<textarea-copyable :value="objectIdOutput" />
65+
<textarea-copyable :value="objectIdSyntaxOutput" />
66+
<textarea-copyable :value="objectIdQueryOutput" />
67+
</c-card>
68+
</template>

0 commit comments

Comments
 (0)