mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-08 17:22:29 +08:00
Merge branch 'develop' into shortcuts-i18n
This commit is contained in:
commit
555c596a0f
@ -40,7 +40,7 @@
|
|||||||
"@types/express": "5.0.1",
|
"@types/express": "5.0.1",
|
||||||
"@types/node": "22.15.29",
|
"@types/node": "22.15.29",
|
||||||
"@types/yargs": "17.0.33",
|
"@types/yargs": "17.0.33",
|
||||||
"@vitest/coverage-v8": "3.2.0",
|
"@vitest/coverage-v8": "3.2.1",
|
||||||
"eslint": "9.28.0",
|
"eslint": "9.28.0",
|
||||||
"eslint-plugin-simple-import-sort": "12.1.1",
|
"eslint-plugin-simple-import-sort": "12.1.1",
|
||||||
"esm": "3.2.25",
|
"esm": "3.2.25",
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdNoteId", response.body.note.noteId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attachments
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"ownerId": "{{createdNoteId}}",
|
|
||||||
"role": "file",
|
|
||||||
"mime": "text/plain",
|
|
||||||
"title": "my attachment",
|
|
||||||
"content": "text"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdAttachmentId", response.body.attachmentId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/attachments/{{createdAttachmentId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
### repeat the DELETE request to test the idempotency
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/attachments/{{createdAttachmentId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/attachments/{{createdAttachmentId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code === "ATTACHMENT_NOT_FOUND");
|
|
||||||
%}
|
|
@ -1,52 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdNoteId", response.body.note.noteId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attributes
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{createdNoteId}}",
|
|
||||||
"type": "label",
|
|
||||||
"name": "mylabel",
|
|
||||||
"value": "val",
|
|
||||||
"isInheritable": true
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdAttributeId", response.body.attributeId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
### repeat the DELETE request to test the idempotency
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code === "ATTRIBUTE_NOT_FOUND");
|
|
||||||
%}
|
|
@ -1,87 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.global.set("createdNoteId", response.body.note.noteId);
|
|
||||||
client.global.set("createdBranchId", response.body.branch.branchId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
### Clone to another location
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/branches
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{createdNoteId}}",
|
|
||||||
"parentNoteId": "_hidden"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("clonedBranchId", response.body.branchId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{createdBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{clonedBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/branches/{{createdBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
### repeat the DELETE request to test the idempotency
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/branches/{{createdBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{createdBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code === "BRANCH_NOT_FOUND");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{clonedBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
@ -1,126 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.global.set("createdNoteId", response.body.note.noteId);
|
|
||||||
client.global.set("createdBranchId", response.body.branch.branchId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attributes
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{createdNoteId}}",
|
|
||||||
"type": "label",
|
|
||||||
"name": "mylabel",
|
|
||||||
"value": "val",
|
|
||||||
"isInheritable": true
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdAttributeId", response.body.attributeId); %}
|
|
||||||
|
|
||||||
### Clone to another location
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/branches
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{createdNoteId}}",
|
|
||||||
"parentNoteId": "_hidden"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("clonedBranchId", response.body.branchId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{createdBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{clonedBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
### repeat the DELETE request to test the idempotency
|
|
||||||
|
|
||||||
DELETE {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 204, "Response status is not 204"); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{createdBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code === "BRANCH_NOT_FOUND");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/branches/{{clonedBranchId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code == "BRANCH_NOT_FOUND");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code === "NOTE_NOT_FOUND");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 404, "Response status is not 404");
|
|
||||||
client.assert(response.body.code === "ATTRIBUTE_NOT_FOUND");
|
|
||||||
%}
|
|
@ -1,72 +0,0 @@
|
|||||||
GET {{triliumHost}}/etapi/inbox/2022-01-01
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/days/2022-01-01
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/days/2022-1
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 400);
|
|
||||||
client.assert(response.body.code === "DATE_INVALID");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/weeks/2022-01-01
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/weeks/2022-1
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 400);
|
|
||||||
client.assert(response.body.code === "DATE_INVALID");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/months/2022-01
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/months/2022-1
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 400);
|
|
||||||
client.assert(response.body.code === "MONTH_INVALID");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/years/2022
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {% client.assert(response.status === 200); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/calendar/years/202
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 400);
|
|
||||||
client.assert(response.body.code === "YEAR_INVALID");
|
|
||||||
%}
|
|
@ -1,116 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello parent",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 201);
|
|
||||||
client.global.set("parentNoteId", response.body.note.noteId);
|
|
||||||
client.global.set("parentBranchId", response.body.branch.branchId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
### Create inheritable parent attribute
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attributes
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{parentNoteId}}",
|
|
||||||
"type": "label",
|
|
||||||
"name": "mylabel",
|
|
||||||
"value": "",
|
|
||||||
"isInheritable": true,
|
|
||||||
"position": 10
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 201);
|
|
||||||
client.global.set("parentAttributeId", response.body.attributeId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
### Create child note under root
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello child",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 201);
|
|
||||||
client.global.set("childNoteId", response.body.note.noteId);
|
|
||||||
client.global.set("childBranchId", response.body.branch.branchId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
### Create child attribute
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attributes
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{childNoteId}}",
|
|
||||||
"type": "label",
|
|
||||||
"name": "mylabel",
|
|
||||||
"value": "val",
|
|
||||||
"isInheritable": false,
|
|
||||||
"position": 10
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 201);
|
|
||||||
client.global.set("childAttributeId", response.body.attributeId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
### Clone child to parent
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/branches
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{childNoteId}}",
|
|
||||||
"parentNoteId": "{{parentNoteId}}"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 201);
|
|
||||||
client.assert(response.body.parentNoteId == client.global.get("parentNoteId"));
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/notes/{{childNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
|
|
||||||
function hasAttribute(list, attributeId) {
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
|
||||||
if (list[i]["attributeId"] === attributeId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
client.log(JSON.stringify(response.body.attributes));
|
|
||||||
|
|
||||||
client.assert(response.status === 200);
|
|
||||||
client.assert(response.body.noteId == client.global.get("childNoteId"));
|
|
||||||
client.assert(response.body.attributes.length == 2);
|
|
||||||
client.assert(hasAttribute(response.body.attributes, client.global.get("parentAttributeId")));
|
|
||||||
client.assert(hasAttribute(response.body.attributes, client.global.get("childAttributeId")));
|
|
||||||
%}
|
|
@ -1,61 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "GetInheritedAttributes Test Note",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 201);
|
|
||||||
client.global.set("parentNoteId", response.body.note.noteId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attributes
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{parentNoteId}}",
|
|
||||||
"type": "label",
|
|
||||||
"name": "mylabel",
|
|
||||||
"value": "val",
|
|
||||||
"isInheritable": true
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdAttributeId", response.body.attributeId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "{{parentNoteId}}",
|
|
||||||
"title": "Hello",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.global.set("createdNoteId", response.body.note.noteId);
|
|
||||||
client.global.set("createdBranchId", response.body.branch.branchId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/notes/{{createdNoteId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 200);
|
|
||||||
client.assert(response.body.noteId == client.global.get("createdNoteId"));
|
|
||||||
client.assert(response.body.attributes.length == 1);
|
|
||||||
client.assert(response.body.attributes[0].attributeId == client.global.get("createdAttributeId"));
|
|
||||||
%}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"dev": {
|
|
||||||
"triliumHost": "http://localhost:37740"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
POST {{triliumHost}}/etapi/create-note
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"parentNoteId": "root",
|
|
||||||
"title": "Hello",
|
|
||||||
"type": "text",
|
|
||||||
"content": "Hi there!"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.global.set("createdNoteId", response.body.note.noteId);
|
|
||||||
client.global.set("createdBranchId", response.body.branch.branchId);
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
POST {{triliumHost}}/etapi/attributes
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "{{createdNoteId}}",
|
|
||||||
"type": "label",
|
|
||||||
"name": "mylabel",
|
|
||||||
"value": "val",
|
|
||||||
"isInheritable": true
|
|
||||||
}
|
|
||||||
|
|
||||||
> {% client.global.set("createdAttributeId", response.body.attributeId); %}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
PATCH {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"value": "CHANGED"
|
|
||||||
}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.body.value === "CHANGED");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
PATCH {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"noteId": "root"
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 400);
|
|
||||||
client.assert(response.body.code == "PROPERTY_NOT_ALLOWED");
|
|
||||||
%}
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
PATCH {{triliumHost}}/etapi/attributes/{{createdAttributeId}}
|
|
||||||
Authorization: {{authToken}}
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"value": null
|
|
||||||
}
|
|
||||||
|
|
||||||
> {%
|
|
||||||
client.assert(response.status === 400);
|
|
||||||
client.assert(response.body.code == "PROPERTY_VALIDATION_ERROR");
|
|
||||||
%}
|
|
@ -222,7 +222,6 @@ export function buildFloatingToolbar() {
|
|||||||
"|",
|
"|",
|
||||||
"code",
|
"code",
|
||||||
"link",
|
"link",
|
||||||
"bookmark",
|
|
||||||
"removeFormat",
|
"removeFormat",
|
||||||
"internallink",
|
"internallink",
|
||||||
"cuttonote"
|
"cuttonote"
|
||||||
@ -244,7 +243,7 @@ export function buildFloatingToolbar() {
|
|||||||
{
|
{
|
||||||
label: "Insert",
|
label: "Insert",
|
||||||
icon: "plus",
|
icon: "plus",
|
||||||
items: ["internallink", "includeNote", "|", "math", "mermaid", "horizontalLine", "pageBreak"]
|
items: ["bookmark", "internallink", "includeNote", "|", "math", "mermaid", "horizontalLine", "pageBreak"]
|
||||||
},
|
},
|
||||||
"|",
|
"|",
|
||||||
"outdent",
|
"outdent",
|
||||||
|
@ -85,10 +85,10 @@
|
|||||||
"jsdom": "26.1.0",
|
"jsdom": "26.1.0",
|
||||||
"marked": "15.0.12",
|
"marked": "15.0.12",
|
||||||
"mime-types": "3.0.1",
|
"mime-types": "3.0.1",
|
||||||
"multer": "2.0.0",
|
"multer": "2.0.1",
|
||||||
"normalize-strings": "1.1.1",
|
"normalize-strings": "1.1.1",
|
||||||
"ollama": "0.5.16",
|
"ollama": "0.5.16",
|
||||||
"openai": "5.0.2",
|
"openai": "5.1.0",
|
||||||
"rand-token": "1.0.1",
|
"rand-token": "1.0.1",
|
||||||
"safe-compare": "1.1.4",
|
"safe-compare": "1.1.4",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
|
@ -21,6 +21,6 @@ describe("etapi/backup", () => {
|
|||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.put("/etapi/backup/etapi_test")
|
.put("/etapi/backup/etapi_test")
|
||||||
.auth(USER, token, { "type": "basic"})
|
.auth(USER, token, { "type": "basic"})
|
||||||
.expect(201);
|
.expect(204);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
172
apps/server/spec/etapi/delete-entities.spec.ts
Normal file
172
apps/server/spec/etapi/delete-entities.spec.ts
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import { Application } from "express";
|
||||||
|
import { beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import supertest from "supertest";
|
||||||
|
import { login } from "./utils.js";
|
||||||
|
import config from "../../src/services/config.js";
|
||||||
|
import { randomInt } from "crypto";
|
||||||
|
|
||||||
|
let app: Application;
|
||||||
|
let token: string;
|
||||||
|
let createdNoteId: string;
|
||||||
|
let createdBranchId: string;
|
||||||
|
|
||||||
|
const USER = "etapi";
|
||||||
|
|
||||||
|
type EntityType = "attachments" | "attributes" | "branches" | "notes";
|
||||||
|
|
||||||
|
describe("etapi/delete-entities", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
config.General.noAuthentication = false;
|
||||||
|
const buildApp = (await (import("../../src/app.js"))).default;
|
||||||
|
app = await buildApp();
|
||||||
|
token = await login(app);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
({ createdNoteId, createdBranchId } = await createNote());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("deletes attachment", async () => {
|
||||||
|
const attachmentId = await createAttachment();
|
||||||
|
await deleteEntity("attachments", attachmentId);
|
||||||
|
await expectNotFound("attachments", attachmentId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("deletes attribute", async () => {
|
||||||
|
const attributeId = await createAttribute();
|
||||||
|
await deleteEntity("attributes", attributeId);
|
||||||
|
await expectNotFound("attributes", attributeId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("deletes cloned branch", async () => {
|
||||||
|
const clonedBranchId = await createClone();
|
||||||
|
|
||||||
|
await expectFound("branches", createdBranchId);
|
||||||
|
await expectFound("branches", clonedBranchId);
|
||||||
|
|
||||||
|
await deleteEntity("branches", createdBranchId);
|
||||||
|
await expectNotFound("branches", createdBranchId);
|
||||||
|
|
||||||
|
await expectFound("branches", clonedBranchId);
|
||||||
|
await expectFound("notes", createdNoteId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("deletes note with all branches", async () => {
|
||||||
|
const attributeId = await createAttribute();
|
||||||
|
|
||||||
|
const clonedBranchId = await createClone();
|
||||||
|
|
||||||
|
await expectFound("notes", createdNoteId);
|
||||||
|
await expectFound("branches", createdBranchId);
|
||||||
|
await expectFound("branches", clonedBranchId);
|
||||||
|
await expectFound("attributes", attributeId);
|
||||||
|
await deleteEntity("notes", createdNoteId);
|
||||||
|
|
||||||
|
await expectNotFound("branches", createdBranchId);
|
||||||
|
await expectNotFound("branches", clonedBranchId);
|
||||||
|
await expectNotFound("notes", createdNoteId);
|
||||||
|
await expectNotFound("attributes", attributeId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function createNote() {
|
||||||
|
const noteId = `forcedId${randomInt(1000)}`;
|
||||||
|
const response = await supertest(app)
|
||||||
|
.post("/etapi/create-note")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"noteId": noteId,
|
||||||
|
"parentNoteId": "root",
|
||||||
|
"title": "Hello",
|
||||||
|
"type": "text",
|
||||||
|
"content": "Hi there!",
|
||||||
|
"dateCreated": "2023-08-21 23:38:51.123+0200",
|
||||||
|
"utcDateCreated": "2023-08-21 23:38:51.123Z"
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
expect(response.body.note.noteId).toStrictEqual(noteId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
createdNoteId: response.body.note.noteId,
|
||||||
|
createdBranchId: response.body.branch.branchId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createClone() {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.post("/etapi/branches")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
noteId: createdNoteId,
|
||||||
|
parentNoteId: "_hidden"
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
expect(response.body.parentNoteId).toStrictEqual("_hidden");
|
||||||
|
return response.body.branchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createAttribute() {
|
||||||
|
const attributeId = `forcedId${randomInt(1000)}`;
|
||||||
|
const response = await supertest(app)
|
||||||
|
.post("/etapi/attributes")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"attributeId": attributeId,
|
||||||
|
"noteId": createdNoteId,
|
||||||
|
"type": "label",
|
||||||
|
"name": "mylabel",
|
||||||
|
"value": "val",
|
||||||
|
"isInheritable": true
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
expect(response.body.attributeId).toStrictEqual(attributeId);
|
||||||
|
return response.body.attributeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createAttachment() {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.post("/etapi/attachments")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"ownerId": createdNoteId,
|
||||||
|
"role": "file",
|
||||||
|
"mime": "plain/text",
|
||||||
|
"title": "my attachment",
|
||||||
|
"content": "my text"
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
return response.body.attachmentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteEntity(entity: EntityType, id: string) {
|
||||||
|
// Delete twice to test idempotency.
|
||||||
|
for (let i=0; i < 2; i++) {
|
||||||
|
await supertest(app)
|
||||||
|
.delete(`/etapi/${entity}/${id}`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(204);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const MISSING_ENTITY_ERROR_CODES: Record<EntityType, string> = {
|
||||||
|
attachments: "ATTACHMENT_NOT_FOUND",
|
||||||
|
attributes: "ATTRIBUTE_NOT_FOUND",
|
||||||
|
branches: "BRANCH_NOT_FOUND",
|
||||||
|
notes: "NOTE_NOT_FOUND"
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expectNotFound(entity: EntityType, id: string) {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get(`/etapi/${entity}/${id}`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(404);
|
||||||
|
|
||||||
|
expect(response.body.code).toStrictEqual(MISSING_ENTITY_ERROR_CODES[entity]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expectFound(entity: EntityType, id: string) {
|
||||||
|
await supertest(app)
|
||||||
|
.get(`/etapi/${entity}/${id}`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
}
|
103
apps/server/spec/etapi/get-date-notes.spec.ts
Normal file
103
apps/server/spec/etapi/get-date-notes.spec.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
|
import config from "../../src/services/config.js";
|
||||||
|
import { login } from "./utils.js";
|
||||||
|
import { Application } from "express";
|
||||||
|
import supertest from "supertest";
|
||||||
|
import date_notes from "../../src/services/date_notes.js";
|
||||||
|
import cls from "../../src/services/cls.js";
|
||||||
|
|
||||||
|
let app: Application;
|
||||||
|
let token: string;
|
||||||
|
|
||||||
|
const USER = "etapi";
|
||||||
|
|
||||||
|
describe("etapi/get-date-notes", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
config.General.noAuthentication = false;
|
||||||
|
const buildApp = (await (import("../../src/app.js"))).default;
|
||||||
|
app = await buildApp();
|
||||||
|
token = await login(app);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("obtains inbox", async () => {
|
||||||
|
await supertest(app)
|
||||||
|
.get("/etapi/inbox/2022-01-01")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("days", () => {
|
||||||
|
it("obtains day from calendar", async () => {
|
||||||
|
await supertest(app)
|
||||||
|
.get("/etapi/calendar/days/2022-01-01")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("detects invalid date", async () => {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get("/etapi/calendar/days/2022-1")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.code).toStrictEqual("DATE_INVALID");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("weeks", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
cls.init(() => {
|
||||||
|
const rootCalendarNote = date_notes.getRootCalendarNote();
|
||||||
|
rootCalendarNote.setLabel("enableWeekNote");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("obtains week calendar", async () => {
|
||||||
|
await supertest(app)
|
||||||
|
.get("/etapi/calendar/weeks/2022-W01")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("detects invalid date", async () => {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get("/etapi/calendar/weeks/2022-1")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.code).toStrictEqual("WEEK_INVALID");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("months", () => {
|
||||||
|
it("obtains month calendar", async () => {
|
||||||
|
await supertest(app)
|
||||||
|
.get("/etapi/calendar/months/2022-01")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("detects invalid month", async () => {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get("/etapi/calendar/months/2022-1")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.code).toStrictEqual("MONTH_INVALID");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("years", () => {
|
||||||
|
it("obtains year calendar", async () => {
|
||||||
|
await supertest(app)
|
||||||
|
.get("/etapi/calendar/years/2022")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("detects invalid year", async () => {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get("/etapi/calendar/years/202")
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.code).toStrictEqual("YEAR_INVALID");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,98 @@
|
|||||||
|
import { Application } from "express";
|
||||||
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
|
import supertest from "supertest";
|
||||||
|
import { createNote, login } from "./utils.js";
|
||||||
|
import config from "../../src/services/config.js";
|
||||||
|
|
||||||
|
let app: Application;
|
||||||
|
let token: string;
|
||||||
|
|
||||||
|
let parentNoteId: string;
|
||||||
|
|
||||||
|
describe("etapi/get-inherited-attribute-cloned", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
config.General.noAuthentication = false;
|
||||||
|
const buildApp = (await (import("../../src/app.js"))).default;
|
||||||
|
app = await buildApp();
|
||||||
|
token = await login(app);
|
||||||
|
|
||||||
|
parentNoteId = await createNote(app, token);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("gets inherited attribute", async () => {
|
||||||
|
// Create an inheritable attribute on the parent note.
|
||||||
|
let response = await supertest(app)
|
||||||
|
.post("/etapi/attributes")
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"noteId": parentNoteId,
|
||||||
|
"type": "label",
|
||||||
|
"name": "mylabel",
|
||||||
|
"value": "val",
|
||||||
|
"isInheritable": true,
|
||||||
|
"position": 10
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
const parentAttributeId = response.body.attributeId;
|
||||||
|
expect(parentAttributeId).toBeTruthy();
|
||||||
|
|
||||||
|
// Create a subnote.
|
||||||
|
response = await supertest(app)
|
||||||
|
.post("/etapi/create-note")
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"parentNoteId": parentNoteId,
|
||||||
|
"title": "Hello",
|
||||||
|
"type": "text",
|
||||||
|
"content": "Hi there!"
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
const childNoteId = response.body.note.noteId;
|
||||||
|
|
||||||
|
// Create child attribute
|
||||||
|
response = await supertest(app)
|
||||||
|
.post("/etapi/attributes")
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"noteId": childNoteId,
|
||||||
|
"type": "label",
|
||||||
|
"name": "mylabel",
|
||||||
|
"value": "val",
|
||||||
|
"isInheritable": false,
|
||||||
|
"position": 10
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
const childAttributeId = response.body.attributeId;
|
||||||
|
expect(parentAttributeId).toBeTruthy();
|
||||||
|
|
||||||
|
// Clone child to parent
|
||||||
|
response = await supertest(app)
|
||||||
|
.post("/etapi/branches")
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
noteId: childNoteId,
|
||||||
|
parentNoteId: parentNoteId
|
||||||
|
})
|
||||||
|
.expect(200);
|
||||||
|
parentNoteId = response.body.parentNoteId;
|
||||||
|
|
||||||
|
// Check attribute IDs
|
||||||
|
response = await supertest(app)
|
||||||
|
.get(`/etapi/notes/${childNoteId}`)
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
expect(response.body.noteId).toStrictEqual(childNoteId);
|
||||||
|
expect(response.body.attributes).toHaveLength(2);
|
||||||
|
expect(hasAttribute(response.body.attributes, parentAttributeId));
|
||||||
|
expect(hasAttribute(response.body.attributes, childAttributeId));
|
||||||
|
});
|
||||||
|
|
||||||
|
function hasAttribute(list: object[], attributeId: string) {
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
if (list[i]["attributeId"] === attributeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
60
apps/server/spec/etapi/get-inherited-attribute.spec.ts
Normal file
60
apps/server/spec/etapi/get-inherited-attribute.spec.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { Application } from "express";
|
||||||
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
|
import supertest from "supertest";
|
||||||
|
import { createNote, login } from "./utils.js";
|
||||||
|
import config from "../../src/services/config.js";
|
||||||
|
|
||||||
|
let app: Application;
|
||||||
|
let token: string;
|
||||||
|
|
||||||
|
let parentNoteId: string;
|
||||||
|
|
||||||
|
describe("etapi/get-inherited-attribute", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
config.General.noAuthentication = false;
|
||||||
|
const buildApp = (await (import("../../src/app.js"))).default;
|
||||||
|
app = await buildApp();
|
||||||
|
token = await login(app);
|
||||||
|
|
||||||
|
parentNoteId = await createNote(app, token);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("gets inherited attribute", async () => {
|
||||||
|
// Create an inheritable attribute on the parent note.
|
||||||
|
let response = await supertest(app)
|
||||||
|
.post("/etapi/attributes")
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"noteId": parentNoteId,
|
||||||
|
"type": "label",
|
||||||
|
"name": "mylabel",
|
||||||
|
"value": "val",
|
||||||
|
"isInheritable": true
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
const createdAttributeId = response.body.attributeId;
|
||||||
|
expect(createdAttributeId).toBeTruthy();
|
||||||
|
|
||||||
|
// Create a subnote.
|
||||||
|
response = await supertest(app)
|
||||||
|
.post("/etapi/create-note")
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"parentNoteId": parentNoteId,
|
||||||
|
"title": "Hello",
|
||||||
|
"type": "text",
|
||||||
|
"content": "Hi there!"
|
||||||
|
})
|
||||||
|
.expect(201);
|
||||||
|
const createdNoteId = response.body.note.noteId;
|
||||||
|
|
||||||
|
// Check the attribute is inherited.
|
||||||
|
response = await supertest(app)
|
||||||
|
.get(`/etapi/notes/${createdNoteId}`)
|
||||||
|
.auth("etapi", token, { "type": "basic"})
|
||||||
|
.expect(200);
|
||||||
|
expect(response.body.noteId).toStrictEqual(createdNoteId);
|
||||||
|
expect(response.body.attributes).toHaveLength(1);
|
||||||
|
expect(response.body.attributes[0].attributeId === createdAttributeId);
|
||||||
|
});
|
||||||
|
});
|
@ -21,6 +21,6 @@ describe("etapi/refresh-note-ordering/root", () => {
|
|||||||
await supertest(app)
|
await supertest(app)
|
||||||
.post("/etapi/refresh-note-ordering/root")
|
.post("/etapi/refresh-note-ordering/root")
|
||||||
.auth(USER, token, { "type": "basic"})
|
.auth(USER, token, { "type": "basic"})
|
||||||
.expect(200);
|
.expect(204);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
77
apps/server/spec/etapi/patch-attribute.spec.ts
Normal file
77
apps/server/spec/etapi/patch-attribute.spec.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { Application } from "express";
|
||||||
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
|
import supertest from "supertest";
|
||||||
|
import { createNote, login } from "./utils.js";
|
||||||
|
import config from "../../src/services/config.js";
|
||||||
|
|
||||||
|
let app: Application;
|
||||||
|
let token: string;
|
||||||
|
|
||||||
|
const USER = "etapi";
|
||||||
|
let createdNoteId: string;
|
||||||
|
let createdAttributeId: string;
|
||||||
|
|
||||||
|
describe("etapi/patch-attribute", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
config.General.noAuthentication = false;
|
||||||
|
const buildApp = (await (import("../../src/app.js"))).default;
|
||||||
|
app = await buildApp();
|
||||||
|
token = await login(app);
|
||||||
|
|
||||||
|
createdNoteId = await createNote(app, token);
|
||||||
|
|
||||||
|
// Create an attribute
|
||||||
|
const response = await supertest(app)
|
||||||
|
.post(`/etapi/attributes`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
"noteId": createdNoteId,
|
||||||
|
"type": "label",
|
||||||
|
"name": "mylabel",
|
||||||
|
"value": "val",
|
||||||
|
"isInheritable": true
|
||||||
|
});
|
||||||
|
createdAttributeId = response.body.attributeId;
|
||||||
|
expect(createdAttributeId).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("changes name and value", async () => {
|
||||||
|
const state = {
|
||||||
|
value: "CHANGED"
|
||||||
|
};
|
||||||
|
await supertest(app)
|
||||||
|
.patch(`/etapi/attributes/${createdAttributeId}`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send(state)
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
// Ensure it got changed.
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get(`/etapi/attributes/${createdAttributeId}`)
|
||||||
|
.auth(USER, token, { "type": "basic"});
|
||||||
|
expect(response.body).toMatchObject(state);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("forbids setting disallowed property", async () => {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.patch(`/etapi/attributes/${createdAttributeId}`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
noteId: "root"
|
||||||
|
})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.code).toStrictEqual("PROPERTY_NOT_ALLOWED");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("forbids setting wrong data type", async () => {
|
||||||
|
const response = await supertest(app)
|
||||||
|
.patch(`/etapi/attributes/${createdAttributeId}`)
|
||||||
|
.auth(USER, token, { "type": "basic"})
|
||||||
|
.send({
|
||||||
|
value: null
|
||||||
|
})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.code).toStrictEqual("PROPERTY_VALIDATION_ERROR");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -34,7 +34,7 @@ describe("etapi/patch-note", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("obtains correct note information", async () => {
|
it("obtains correct note information", async () => {
|
||||||
expectNoteToMatch({
|
await expectNoteToMatch({
|
||||||
title: "Hello",
|
title: "Hello",
|
||||||
type: "code",
|
type: "code",
|
||||||
mime: "application/json"
|
mime: "application/json"
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<link rel="shortcut icon" href="../favicon.ico">
|
<link rel="shortcut icon" href="../favicon.ico">
|
||||||
<% } %>
|
<% } %>
|
||||||
<script src="<%= appPath %>/share.js" type="module"></script>
|
<script src="<%= appPath %>/share.js" type="module"></script>
|
||||||
|
<link href="<%= assetPath %>/src/share.css" rel="stylesheet">
|
||||||
<% if (!note.isLabelTruthy("shareOmitDefaultCss")) { %>
|
<% if (!note.isLabelTruthy("shareOmitDefaultCss")) { %>
|
||||||
<link href="<%= assetPath %>/stylesheets/share.css" rel="stylesheet">
|
<link href="<%= assetPath %>/stylesheets/share.css" rel="stylesheet">
|
||||||
<% } %>
|
<% } %>
|
||||||
|
@ -4,10 +4,10 @@ import eu from "./etapi_utils.js";
|
|||||||
import backupService from "../services/backup.js";
|
import backupService from "../services/backup.js";
|
||||||
|
|
||||||
function register(router: Router) {
|
function register(router: Router) {
|
||||||
eu.route(router, "put", "/etapi/backup/:backupName", async (req, res, next) => {
|
eu.route(router, "put", "/etapi/backup/:backupName", (req, res, next) => {
|
||||||
await backupService.backupNow(req.params.backupName);
|
backupService.backupNow(req.params.backupName)
|
||||||
|
.then(() => res.sendStatus(204))
|
||||||
res.sendStatus(204);
|
.catch(() => res.sendStatus(500));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import etapiTokenService from "../services/etapi_tokens.js";
|
|||||||
import config from "../services/config.js";
|
import config from "../services/config.js";
|
||||||
import type { NextFunction, Request, RequestHandler, Response, Router } from "express";
|
import type { NextFunction, Request, RequestHandler, Response, Router } from "express";
|
||||||
import type { ValidatorMap } from "./etapi-interface.js";
|
import type { ValidatorMap } from "./etapi-interface.js";
|
||||||
import type { ApiRequestHandler } from "../routes/route_api.js";
|
import type { ApiRequestHandler, SyncRouteRequestHandler } from "../routes/route_api.js";
|
||||||
const GENERIC_CODE = "GENERIC";
|
const GENERIC_CODE = "GENERIC";
|
||||||
|
|
||||||
type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
|
type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
|
||||||
@ -73,11 +73,11 @@ function processRequest(req: Request, res: Response, routeHandler: ApiRequestHan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function route(router: Router, method: HttpMethod, path: string, routeHandler: ApiRequestHandler) {
|
function route(router: Router, method: HttpMethod, path: string, routeHandler: SyncRouteRequestHandler) {
|
||||||
router[method](path, checkEtapiAuth, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
|
router[method](path, checkEtapiAuth, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
function NOT_AUTHENTICATED_ROUTE(router: Router, method: HttpMethod, path: string, middleware: RequestHandler[], routeHandler: RequestHandler) {
|
function NOT_AUTHENTICATED_ROUTE(router: Router, method: HttpMethod, path: string, middleware: RequestHandler[], routeHandler: SyncRouteRequestHandler) {
|
||||||
router[method](path, ...middleware, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
|
router[method](path, ...middleware, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,46 +15,46 @@ function isValidDate(date: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function register(router: Router) {
|
function register(router: Router) {
|
||||||
eu.route(router, "get", "/etapi/inbox/:date", async (req, res, next) => {
|
eu.route(router, "get", "/etapi/inbox/:date", (req, res, next) => {
|
||||||
const { date } = req.params;
|
const { date } = req.params;
|
||||||
|
|
||||||
if (!isValidDate(date)) {
|
if (!isValidDate(date)) {
|
||||||
throw getDateInvalidError(date);
|
throw getDateInvalidError(date);
|
||||||
}
|
}
|
||||||
const note = await specialNotesService.getInboxNote(date);
|
const note = specialNotesService.getInboxNote(date);
|
||||||
res.json(mappers.mapNoteToPojo(note));
|
res.json(mappers.mapNoteToPojo(note));
|
||||||
});
|
});
|
||||||
|
|
||||||
eu.route(router, "get", "/etapi/calendar/days/:date", async (req, res, next) => {
|
eu.route(router, "get", "/etapi/calendar/days/:date", (req, res, next) => {
|
||||||
const { date } = req.params;
|
const { date } = req.params;
|
||||||
|
|
||||||
if (!isValidDate(date)) {
|
if (!isValidDate(date)) {
|
||||||
throw getDateInvalidError(date);
|
throw getDateInvalidError(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
const note = await dateNotesService.getDayNote(date);
|
const note = dateNotesService.getDayNote(date);
|
||||||
res.json(mappers.mapNoteToPojo(note));
|
res.json(mappers.mapNoteToPojo(note));
|
||||||
});
|
});
|
||||||
|
|
||||||
eu.route(router, "get", "/etapi/calendar/week-first-day/:date", async (req, res, next) => {
|
eu.route(router, "get", "/etapi/calendar/week-first-day/:date", (req, res, next) => {
|
||||||
const { date } = req.params;
|
const { date } = req.params;
|
||||||
|
|
||||||
if (!isValidDate(date)) {
|
if (!isValidDate(date)) {
|
||||||
throw getDateInvalidError(date);
|
throw getDateInvalidError(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
const note = await dateNotesService.getWeekFirstDayNote(date);
|
const note = dateNotesService.getWeekFirstDayNote(date);
|
||||||
res.json(mappers.mapNoteToPojo(note));
|
res.json(mappers.mapNoteToPojo(note));
|
||||||
});
|
});
|
||||||
|
|
||||||
eu.route(router, "get", "/etapi/calendar/weeks/:week", async (req, res, next) => {
|
eu.route(router, "get", "/etapi/calendar/weeks/:week", (req, res, next) => {
|
||||||
const { week } = req.params;
|
const { week } = req.params;
|
||||||
|
|
||||||
if (!/[0-9]{4}-W[0-9]{2}/.test(week)) {
|
if (!/[0-9]{4}-W[0-9]{2}/.test(week)) {
|
||||||
throw getWeekInvalidError(week);
|
throw getWeekInvalidError(week);
|
||||||
}
|
}
|
||||||
|
|
||||||
const note = await dateNotesService.getWeekNote(week);
|
const note = dateNotesService.getWeekNote(week);
|
||||||
|
|
||||||
if (!note) {
|
if (!note) {
|
||||||
throw getWeekNotFoundError(week);
|
throw getWeekNotFoundError(week);
|
||||||
@ -63,14 +63,14 @@ function register(router: Router) {
|
|||||||
res.json(mappers.mapNoteToPojo(note));
|
res.json(mappers.mapNoteToPojo(note));
|
||||||
});
|
});
|
||||||
|
|
||||||
eu.route(router, "get", "/etapi/calendar/months/:month", async (req, res, next) => {
|
eu.route(router, "get", "/etapi/calendar/months/:month", (req, res, next) => {
|
||||||
const { month } = req.params;
|
const { month } = req.params;
|
||||||
|
|
||||||
if (!/[0-9]{4}-[0-9]{2}/.test(month)) {
|
if (!/[0-9]{4}-[0-9]{2}/.test(month)) {
|
||||||
throw getMonthInvalidError(month);
|
throw getMonthInvalidError(month);
|
||||||
}
|
}
|
||||||
|
|
||||||
const note = await dateNotesService.getMonthNote(month);
|
const note = dateNotesService.getMonthNote(month);
|
||||||
res.json(mappers.mapNoteToPojo(note));
|
res.json(mappers.mapNoteToPojo(note));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import searchService from "./search/services/search.js";
|
|||||||
import SearchContext from "./search/search_context.js";
|
import SearchContext from "./search/search_context.js";
|
||||||
import hiddenSubtree from "./hidden_subtree.js";
|
import hiddenSubtree from "./hidden_subtree.js";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
|
import { BNote } from "./backend_script_entrypoint.js";
|
||||||
const { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } = hiddenSubtree;
|
const { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } = hiddenSubtree;
|
||||||
|
|
||||||
function getInboxNote(date: string) {
|
function getInboxNote(date: string) {
|
||||||
@ -17,7 +18,7 @@ function getInboxNote(date: string) {
|
|||||||
throw new Error("Unable to find workspace note");
|
throw new Error("Unable to find workspace note");
|
||||||
}
|
}
|
||||||
|
|
||||||
let inbox;
|
let inbox: BNote;
|
||||||
|
|
||||||
if (!workspaceNote.isRoot()) {
|
if (!workspaceNote.isRoot()) {
|
||||||
inbox = workspaceNote.searchNoteInSubtree("#workspaceInbox");
|
inbox = workspaceNote.searchNoteInSubtree("#workspaceInbox");
|
||||||
|
@ -11,7 +11,6 @@ export default defineConfig(() => ({
|
|||||||
setupFiles: ["./spec/setup.ts"],
|
setupFiles: ["./spec/setup.ts"],
|
||||||
environment: "node",
|
environment: "node",
|
||||||
include: ['{src,spec}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
include: ['{src,spec}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
reporters: ['default'],
|
|
||||||
coverage: {
|
coverage: {
|
||||||
reportsDirectory: './test-output/vitest/coverage',
|
reportsDirectory: './test-output/vitest/coverage',
|
||||||
provider: 'v8' as const,
|
provider: 'v8' as const,
|
||||||
|
57
flake.lock
generated
57
flake.lock
generated
@ -18,6 +18,24 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1701680307,
|
||||||
|
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1748437600,
|
"lastModified": 1748437600,
|
||||||
@ -34,10 +52,32 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pnpm2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748901165,
|
||||||
|
"narHash": "sha256-SctrxW5rVrROBLfh8p4kXfbF7NbJQDkse/Penu4PlEs=",
|
||||||
|
"owner": "FliegendeWurst",
|
||||||
|
"repo": "pnpm2nix-nzbr",
|
||||||
|
"rev": "cda68d63418896a58542f3310c1c757ae92b1f22",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "FliegendeWurst",
|
||||||
|
"repo": "pnpm2nix-nzbr",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs",
|
||||||
|
"pnpm2nix": "pnpm2nix"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
@ -54,6 +94,21 @@
|
|||||||
"repo": "default",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
229
flake.nix
229
flake.nix
@ -4,6 +4,10 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
pnpm2nix = {
|
||||||
|
url = "github:FliegendeWurst/pnpm2nix-nzbr";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
@ -11,69 +15,171 @@
|
|||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
flake-utils,
|
flake-utils,
|
||||||
|
pnpm2nix,
|
||||||
}:
|
}:
|
||||||
flake-utils.lib.eachDefaultSystem (
|
flake-utils.lib.eachDefaultSystem (
|
||||||
system:
|
system:
|
||||||
let
|
let
|
||||||
packageJSON = builtins.fromJSON (builtins.readFile ./package.json);
|
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
electron = pkgs.electron_35;
|
electron = pkgs.electron_35;
|
||||||
|
nodejs = pkgs.nodejs_22;
|
||||||
|
pnpm = pkgs.pnpm_10;
|
||||||
inherit (pkgs)
|
inherit (pkgs)
|
||||||
copyDesktopItems
|
copyDesktopItems
|
||||||
|
darwin
|
||||||
lib
|
lib
|
||||||
makeBinaryWrapper
|
makeBinaryWrapper
|
||||||
makeDesktopItem
|
makeDesktopItem
|
||||||
nodejs
|
moreutils
|
||||||
pnpm
|
removeReferencesTo
|
||||||
stdenv
|
stdenv
|
||||||
wrapGAppsHook3
|
wrapGAppsHook3
|
||||||
xcodebuild
|
xcodebuild
|
||||||
darwin
|
|
||||||
;
|
;
|
||||||
desktop = stdenv.mkDerivation (finalAttrs: {
|
|
||||||
pname = "triliumnext-desktop";
|
|
||||||
version = packageJSON.version;
|
|
||||||
src = lib.cleanSource ./.;
|
|
||||||
|
|
||||||
nativeBuildInputs =
|
fullCleanSourceFilter =
|
||||||
[
|
name: type:
|
||||||
pnpm.configHook
|
(lib.cleanSourceFilter name type)
|
||||||
nodejs
|
|| (
|
||||||
nodejs.python
|
let
|
||||||
copyDesktopItems
|
baseName = baseNameOf (toString name);
|
||||||
makeBinaryWrapper
|
in
|
||||||
wrapGAppsHook3
|
# No need to copy the flake.
|
||||||
]
|
# Don't copy local development instance of NX cache.
|
||||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
baseName == "flake.nix" || baseName == "flake.lock" || baseName == ".nx"
|
||||||
xcodebuild
|
);
|
||||||
darwin.cctools
|
fullCleanSource =
|
||||||
|
src:
|
||||||
|
lib.cleanSourceWith {
|
||||||
|
filter = fullCleanSourceFilter;
|
||||||
|
src = src;
|
||||||
|
};
|
||||||
|
packageJson = builtins.fromJSON (builtins.readFile ./package.json);
|
||||||
|
|
||||||
|
makeApp =
|
||||||
|
{
|
||||||
|
app,
|
||||||
|
buildTask,
|
||||||
|
mainProgram,
|
||||||
|
installCommands,
|
||||||
|
preBuildCommands ? "",
|
||||||
|
}:
|
||||||
|
pnpm2nix.packages.${system}.mkPnpmPackage rec {
|
||||||
|
pname = "triliumnext-${app}";
|
||||||
|
version = packageJson.version + (lib.optionalString (self ? shortRev) "-${self.shortRev}");
|
||||||
|
|
||||||
|
src = fullCleanSource ./.;
|
||||||
|
packageJSON = ./package.json;
|
||||||
|
pnpmLockYaml = ./pnpm-lock.yaml;
|
||||||
|
|
||||||
|
workspace = fullCleanSource ./.;
|
||||||
|
pnpmWorkspaceYaml = ./pnpm-workspace.yaml;
|
||||||
|
|
||||||
|
inherit nodejs pnpm;
|
||||||
|
|
||||||
|
extraNodeModuleSources = [
|
||||||
|
rec {
|
||||||
|
name = "patches";
|
||||||
|
value = ./patches;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
dontWrapGApps = true;
|
# remove pnpm version override
|
||||||
|
preConfigure = ''
|
||||||
|
cat package.json | grep -v 'packageManager' | sponge package.json
|
||||||
|
'';
|
||||||
|
|
||||||
preBuild = lib.optionalString stdenv.hostPlatform.isLinux ''
|
postConfigure =
|
||||||
patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
|
''
|
||||||
node_modules/.pnpm/sass-embedded-linux-x64@*/node_modules/sass-embedded-linux-x64/dart-sass/src/dart
|
chmod +x node_modules/.pnpm/electron@*/node_modules/electron/install.js
|
||||||
'';
|
patchShebangs --build node_modules
|
||||||
|
''
|
||||||
|
+ lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||||
|
patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
|
||||||
|
node_modules/.pnpm/sass-embedded-linux-x64@*/node_modules/sass-embedded-linux-x64/dart-sass/src/dart
|
||||||
|
'';
|
||||||
|
|
||||||
buildPhase = ''
|
extraNativeBuildInputs =
|
||||||
runHook preBuild
|
[
|
||||||
|
makeBinaryWrapper
|
||||||
|
moreutils # sponge
|
||||||
|
nodejs.python
|
||||||
|
removeReferencesTo
|
||||||
|
]
|
||||||
|
++ lib.optionals (app == "desktop") [
|
||||||
|
copyDesktopItems
|
||||||
|
wrapGAppsHook3
|
||||||
|
]
|
||||||
|
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||||
|
xcodebuild
|
||||||
|
darwin.cctools
|
||||||
|
];
|
||||||
|
dontWrapGApps = true;
|
||||||
|
|
||||||
# Disable NX interaction
|
env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
|
||||||
export NX_TUI=false
|
|
||||||
export NX_DAEMON=false
|
|
||||||
|
|
||||||
pnpm nx run desktop:build --outputStyle stream --verbose
|
preBuild = ''
|
||||||
|
${preBuildCommands}
|
||||||
|
'';
|
||||||
|
|
||||||
# Rebuild dependencies
|
scriptFull = "pnpm nx ${buildTask} --outputStyle stream --verbose";
|
||||||
export npm_config_nodedir=${electron.headers}
|
|
||||||
pnpm nx run desktop:rebuild-deps --outputStyle stream --verbose
|
|
||||||
|
|
||||||
runHook postBuild
|
installPhase = ''
|
||||||
'';
|
runHook preInstall
|
||||||
|
|
||||||
installPhase = ''
|
${installCommands}
|
||||||
runHook preInstall
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
components = [
|
||||||
|
"packages/ckeditor5"
|
||||||
|
"packages/ckeditor5-admonition"
|
||||||
|
"packages/ckeditor5-footnotes"
|
||||||
|
"packages/ckeditor5-keyboard-marker"
|
||||||
|
"packages/ckeditor5-math"
|
||||||
|
"packages/ckeditor5-mermaid"
|
||||||
|
"packages/codemirror"
|
||||||
|
"packages/commons"
|
||||||
|
"packages/express-partial-content"
|
||||||
|
"packages/highlightjs"
|
||||||
|
"packages/turndown-plugin-gfm"
|
||||||
|
|
||||||
|
"apps/client"
|
||||||
|
"apps/db-compare"
|
||||||
|
"apps/desktop"
|
||||||
|
"apps/dump-db"
|
||||||
|
"apps/edit-docs"
|
||||||
|
"apps/server"
|
||||||
|
"apps/server-e2e"
|
||||||
|
];
|
||||||
|
|
||||||
|
desktopItems = lib.optionals (app == "desktop") [
|
||||||
|
(makeDesktopItem {
|
||||||
|
name = "TriliumNext Notes";
|
||||||
|
exec = meta.mainProgram;
|
||||||
|
icon = "trilium";
|
||||||
|
comment = meta.description;
|
||||||
|
desktopName = "TriliumNext Notes";
|
||||||
|
categories = [ "Office" ];
|
||||||
|
startupWMClass = "Trilium Notes Next";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "TriliumNext: ${app}";
|
||||||
|
inherit mainProgram;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
desktop = makeApp {
|
||||||
|
app = "desktop";
|
||||||
|
preBuildCommands = "export npm_config_nodedir=${electron.headers}";
|
||||||
|
buildTask = "run desktop:rebuild-deps";
|
||||||
|
mainProgram = "trilium";
|
||||||
|
installCommands = ''
|
||||||
|
remove-references-to -t ${electron.headers} apps/desktop/dist/node_modules/better-sqlite3/build/config.gypi
|
||||||
|
remove-references-to -t ${nodejs.python} apps/desktop/dist/node_modules/better-sqlite3/build/config.gypi
|
||||||
|
|
||||||
mkdir -p $out/{bin,share/icons/hicolor/512x512/apps,opt/trilium}
|
mkdir -p $out/{bin,share/icons/hicolor/512x512/apps,opt/trilium}
|
||||||
cp --archive apps/desktop/dist/* $out/opt/trilium
|
cp --archive apps/desktop/dist/* $out/opt/trilium
|
||||||
@ -82,34 +188,37 @@
|
|||||||
"''${gappsWrapperArgs[@]}" \
|
"''${gappsWrapperArgs[@]}" \
|
||||||
--set-default ELECTRON_IS_DEV 0 \
|
--set-default ELECTRON_IS_DEV 0 \
|
||||||
--add-flags $out/opt/trilium/main.cjs
|
--add-flags $out/opt/trilium/main.cjs
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
desktopItems = [
|
server = makeApp {
|
||||||
(makeDesktopItem {
|
app = "server";
|
||||||
name = "TriliumNext Notes";
|
preBuildCommands = "pushd apps/server; pnpm rebuild; popd";
|
||||||
exec = finalAttrs.meta.mainProgram;
|
buildTask = "--project=server build";
|
||||||
icon = "trilium";
|
mainProgram = "trilium-server";
|
||||||
comment = finalAttrs.meta.description;
|
installCommands = ''
|
||||||
desktopName = "TriliumNext Notes";
|
remove-references-to -t ${nodejs.python} apps/server/dist/node_modules/better-sqlite3/build/config.gypi
|
||||||
categories = [ "Office" ];
|
remove-references-to -t ${pnpm} apps/server/dist/node_modules/better-sqlite3/build/config.gypi
|
||||||
startupWMClass = "Trilium Notes Next";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
pnpmDeps = pnpm.fetchDeps {
|
pushd apps/server/dist
|
||||||
inherit (finalAttrs) pname version src;
|
rm -rf node_modules/better-sqlite3/build/Release/obj \
|
||||||
hash = "sha256-xC0u1h92wtthylOAw+IF9mpFi0c4xajJhUcA9pqzcAw=";
|
node_modules/better-sqlite3/build/Release/obj.target \
|
||||||
};
|
node_modules/better-sqlite3/build/Release/sqlite3.a \
|
||||||
|
node_modules/better-sqlite3/build/{Makefile,better_sqlite3.target.mk,test_extension.target.mk,binding.Makefile} \
|
||||||
|
node_modules/better-sqlite3/deps/sqlite3
|
||||||
|
popd
|
||||||
|
|
||||||
meta = {
|
mkdir -p $out/{bin,opt/trilium-server}
|
||||||
description = "Free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases";
|
cp --archive apps/server/dist/* $out/opt/trilium-server
|
||||||
mainProgram = "trilium";
|
makeWrapper ${lib.getExe nodejs} $out/bin/trilium-server \
|
||||||
};
|
--add-flags $out/opt/trilium-server/main.cjs
|
||||||
});
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
packages.desktop = desktop;
|
||||||
|
packages.server = server;
|
||||||
|
|
||||||
packages.default = desktop;
|
packages.default = desktop;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
262
pnpm-lock.yaml
generated
262
pnpm-lock.yaml
generated
@ -65,7 +65,7 @@ importers:
|
|||||||
version: 21.1.2(@babel/traverse@7.27.0)(@playwright/test@1.52.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(@zkochan/js-yaml@0.0.7)(eslint@9.28.0(jiti@2.4.2))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))(typescript@5.8.3)
|
version: 21.1.2(@babel/traverse@7.27.0)(@playwright/test@1.52.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(@zkochan/js-yaml@0.0.7)(eslint@9.28.0(jiti@2.4.2))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))(typescript@5.8.3)
|
||||||
'@nx/vite':
|
'@nx/vite':
|
||||||
specifier: 21.1.2
|
specifier: 21.1.2
|
||||||
version: 21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.0)
|
version: 21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.1)
|
||||||
'@nx/web':
|
'@nx/web':
|
||||||
specifier: 21.1.2
|
specifier: 21.1.2
|
||||||
version: 21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))
|
version: 21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))
|
||||||
@ -83,10 +83,10 @@ importers:
|
|||||||
version: 22.15.29
|
version: 22.15.29
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^3.0.5
|
specifier: ^3.0.5
|
||||||
version: 3.2.0(@vitest/browser@3.2.0)(vitest@3.2.0)
|
version: 3.2.1(vitest@3.2.1)
|
||||||
'@vitest/ui':
|
'@vitest/ui':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.0(vitest@3.2.0)
|
version: 3.2.1(vitest@3.2.1)
|
||||||
chalk:
|
chalk:
|
||||||
specifier: 5.4.1
|
specifier: 5.4.1
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
@ -146,7 +146,7 @@ importers:
|
|||||||
version: 4.5.4(@types/node@22.15.29)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))
|
version: 4.5.4(@types/node@22.15.29)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.0(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/browser@3.2.0)(@vitest/ui@3.2.0)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
version: 3.2.1(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.1)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
|
||||||
apps/client:
|
apps/client:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -699,8 +699,8 @@ importers:
|
|||||||
specifier: 3.0.1
|
specifier: 3.0.1
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
multer:
|
multer:
|
||||||
specifier: 2.0.0
|
specifier: 2.0.1
|
||||||
version: 2.0.0
|
version: 2.0.1
|
||||||
normalize-strings:
|
normalize-strings:
|
||||||
specifier: 1.1.1
|
specifier: 1.1.1
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
@ -708,8 +708,8 @@ importers:
|
|||||||
specifier: 0.5.16
|
specifier: 0.5.16
|
||||||
version: 0.5.16
|
version: 0.5.16
|
||||||
openai:
|
openai:
|
||||||
specifier: 5.0.2
|
specifier: 5.1.0
|
||||||
version: 5.0.2(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4)
|
version: 5.1.0(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4)
|
||||||
rand-token:
|
rand-token:
|
||||||
specifier: 1.0.1
|
specifier: 1.0.1
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
@ -1426,8 +1426,8 @@ packages:
|
|||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
'@babel/parser@7.27.4':
|
'@babel/parser@7.27.5':
|
||||||
resolution: {integrity: sha512-BRmLHGwpUqLFR2jzx9orBuX/ABDkj2jLKOXrHDTN2aOKL+jFDDKaRNo9nyYsIl9h/UE/7lMKdDjKQQyxKKDZ7g==}
|
resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@ -4864,11 +4864,11 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vitest: 3.2.0
|
vitest: 3.2.0
|
||||||
|
|
||||||
'@vitest/coverage-v8@3.2.0':
|
'@vitest/coverage-v8@3.2.1':
|
||||||
resolution: {integrity: sha512-HjgvaokAiHxRMI5ioXl4WmgAi4zQtKtnltOOlmpzUqApdcTTZrZJAastbbRGydtiqwtYLFaIb6Jpo3PzowZ0cg==}
|
resolution: {integrity: sha512-6dy0uF/0BE3jpUW9bFzg0V2S4F7XVaZHL/7qma1XANvHPQGoJuc3wtx911zSoAgUnpfvcLVK1vancNJ95d+uxQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@vitest/browser': 3.2.0
|
'@vitest/browser': 3.2.1
|
||||||
vitest: 3.2.0
|
vitest: 3.2.1
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
optional: true
|
optional: true
|
||||||
@ -4876,6 +4876,9 @@ packages:
|
|||||||
'@vitest/expect@3.2.0':
|
'@vitest/expect@3.2.0':
|
||||||
resolution: {integrity: sha512-0v4YVbhDKX3SKoy0PHWXpKhj44w+3zZkIoVES9Ex2pq+u6+Bijijbi2ua5kE+h3qT6LBWFTNZSCOEU37H8Y5sA==}
|
resolution: {integrity: sha512-0v4YVbhDKX3SKoy0PHWXpKhj44w+3zZkIoVES9Ex2pq+u6+Bijijbi2ua5kE+h3qT6LBWFTNZSCOEU37H8Y5sA==}
|
||||||
|
|
||||||
|
'@vitest/expect@3.2.1':
|
||||||
|
resolution: {integrity: sha512-FqS/BnDOzV6+IpxrTg5GQRyLOCtcJqkwMwcS8qGCI2IyRVDwPAtutztaf1CjtPHlZlWtl1yUPCd7HM0cNiDOYw==}
|
||||||
|
|
||||||
'@vitest/mocker@3.2.0':
|
'@vitest/mocker@3.2.0':
|
||||||
resolution: {integrity: sha512-HFcW0lAMx3eN9vQqis63H0Pscv0QcVMo1Kv8BNysZbxcmHu3ZUYv59DS6BGYiGQ8F5lUkmsfMMlPm4DJFJdf/A==}
|
resolution: {integrity: sha512-HFcW0lAMx3eN9vQqis63H0Pscv0QcVMo1Kv8BNysZbxcmHu3ZUYv59DS6BGYiGQ8F5lUkmsfMMlPm4DJFJdf/A==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -4887,26 +4890,57 @@ packages:
|
|||||||
vite:
|
vite:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@vitest/mocker@3.2.1':
|
||||||
|
resolution: {integrity: sha512-OXxMJnx1lkB+Vl65Re5BrsZEHc90s5NMjD23ZQ9NlU7f7nZiETGoX4NeKZSmsKjseuMq2uOYXdLOeoM0pJU+qw==}
|
||||||
|
peerDependencies:
|
||||||
|
msw: ^2.4.9
|
||||||
|
vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
msw:
|
||||||
|
optional: true
|
||||||
|
vite:
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@vitest/pretty-format@3.2.0':
|
'@vitest/pretty-format@3.2.0':
|
||||||
resolution: {integrity: sha512-gUUhaUmPBHFkrqnOokmfMGRBMHhgpICud9nrz/xpNV3/4OXCn35oG+Pl8rYYsKaTNd/FAIrqRHnwpDpmYxCYZw==}
|
resolution: {integrity: sha512-gUUhaUmPBHFkrqnOokmfMGRBMHhgpICud9nrz/xpNV3/4OXCn35oG+Pl8rYYsKaTNd/FAIrqRHnwpDpmYxCYZw==}
|
||||||
|
|
||||||
|
'@vitest/pretty-format@3.2.1':
|
||||||
|
resolution: {integrity: sha512-xBh1X2GPlOGBupp6E1RcUQWIxw0w/hRLd3XyBS6H+dMdKTAqHDNsIR2AnJwPA3yYe9DFy3VUKTe3VRTrAiQ01g==}
|
||||||
|
|
||||||
'@vitest/runner@3.2.0':
|
'@vitest/runner@3.2.0':
|
||||||
resolution: {integrity: sha512-bXdmnHxuB7fXJdh+8vvnlwi/m1zvu+I06i1dICVcDQFhyV4iKw2RExC/acavtDn93m/dRuawUObKsrNE1gJacA==}
|
resolution: {integrity: sha512-bXdmnHxuB7fXJdh+8vvnlwi/m1zvu+I06i1dICVcDQFhyV4iKw2RExC/acavtDn93m/dRuawUObKsrNE1gJacA==}
|
||||||
|
|
||||||
|
'@vitest/runner@3.2.1':
|
||||||
|
resolution: {integrity: sha512-kygXhNTu/wkMYbwYpS3z/9tBe0O8qpdBuC3dD/AW9sWa0LE/DAZEjnHtWA9sIad7lpD4nFW1yQ+zN7mEKNH3yA==}
|
||||||
|
|
||||||
'@vitest/snapshot@3.2.0':
|
'@vitest/snapshot@3.2.0':
|
||||||
resolution: {integrity: sha512-z7P/EneBRMe7hdvWhcHoXjhA6at0Q4ipcoZo6SqgxLyQQ8KSMMCmvw1cSt7FHib3ozt0wnRHc37ivuUMbxzG/A==}
|
resolution: {integrity: sha512-z7P/EneBRMe7hdvWhcHoXjhA6at0Q4ipcoZo6SqgxLyQQ8KSMMCmvw1cSt7FHib3ozt0wnRHc37ivuUMbxzG/A==}
|
||||||
|
|
||||||
|
'@vitest/snapshot@3.2.1':
|
||||||
|
resolution: {integrity: sha512-5xko/ZpW2Yc65NVK9Gpfg2y4BFvcF+At7yRT5AHUpTg9JvZ4xZoyuRY4ASlmNcBZjMslV08VRLDrBOmUe2YX3g==}
|
||||||
|
|
||||||
'@vitest/spy@3.2.0':
|
'@vitest/spy@3.2.0':
|
||||||
resolution: {integrity: sha512-s3+TkCNUIEOX99S0JwNDfsHRaZDDZZR/n8F0mop0PmsEbQGKZikCGpTGZ6JRiHuONKew3Fb5//EPwCP+pUX9cw==}
|
resolution: {integrity: sha512-s3+TkCNUIEOX99S0JwNDfsHRaZDDZZR/n8F0mop0PmsEbQGKZikCGpTGZ6JRiHuONKew3Fb5//EPwCP+pUX9cw==}
|
||||||
|
|
||||||
|
'@vitest/spy@3.2.1':
|
||||||
|
resolution: {integrity: sha512-Nbfib34Z2rfcJGSetMxjDCznn4pCYPZOtQYox2kzebIJcgH75yheIKd5QYSFmR8DIZf2M8fwOm66qSDIfRFFfQ==}
|
||||||
|
|
||||||
'@vitest/ui@3.2.0':
|
'@vitest/ui@3.2.0':
|
||||||
resolution: {integrity: sha512-cYFZZSl1usgzsHoGF66GHfYXlEwc06ggapS1TaSLMKCzhTPWBPI9b/t1RvKIsLSjdKUakpSPf33jQMvRjMvvlQ==}
|
resolution: {integrity: sha512-cYFZZSl1usgzsHoGF66GHfYXlEwc06ggapS1TaSLMKCzhTPWBPI9b/t1RvKIsLSjdKUakpSPf33jQMvRjMvvlQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vitest: 3.2.0
|
vitest: 3.2.0
|
||||||
|
|
||||||
|
'@vitest/ui@3.2.1':
|
||||||
|
resolution: {integrity: sha512-xT93aOcPn2wn8vvw4T6rZAK9WjGEHdYrEjN3OJ1zcDpl2UInxvcD9fYI10nmPAERNEK6jUVcSCIPAIfNuaRX6Q==}
|
||||||
|
peerDependencies:
|
||||||
|
vitest: 3.2.1
|
||||||
|
|
||||||
'@vitest/utils@3.2.0':
|
'@vitest/utils@3.2.0':
|
||||||
resolution: {integrity: sha512-gXXOe7Fj6toCsZKVQouTRLJftJwmvbhH5lKOBR6rlP950zUq9AitTUjnFoXS/CqjBC2aoejAztLPzzuva++XBw==}
|
resolution: {integrity: sha512-gXXOe7Fj6toCsZKVQouTRLJftJwmvbhH5lKOBR6rlP950zUq9AitTUjnFoXS/CqjBC2aoejAztLPzzuva++XBw==}
|
||||||
|
|
||||||
|
'@vitest/utils@3.2.1':
|
||||||
|
resolution: {integrity: sha512-KkHlGhePEKZSub5ViknBcN5KEF+u7dSUr9NW8QsVICusUojrgrOnnY3DEWWO877ax2Pyopuk2qHmt+gkNKnBVw==}
|
||||||
|
|
||||||
'@volar/language-core@2.4.13':
|
'@volar/language-core@2.4.13':
|
||||||
resolution: {integrity: sha512-MnQJ7eKchJx5Oz+YdbqyFUk8BN6jasdJv31n/7r6/WwlOOv7qzvot6B66887l2ST3bUW4Mewml54euzpJWA6bg==}
|
resolution: {integrity: sha512-MnQJ7eKchJx5Oz+YdbqyFUk8BN6jasdJv31n/7r6/WwlOOv7qzvot6B66887l2ST3bUW4Mewml54euzpJWA6bg==}
|
||||||
|
|
||||||
@ -5951,6 +5985,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
||||||
engines: {'0': node >= 0.8}
|
engines: {'0': node >= 0.8}
|
||||||
|
|
||||||
|
concat-stream@2.0.0:
|
||||||
|
resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==}
|
||||||
|
engines: {'0': node >= 6.0}
|
||||||
|
|
||||||
confbox@0.1.8:
|
confbox@0.1.8:
|
||||||
resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
|
resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
|
||||||
|
|
||||||
@ -9262,8 +9300,8 @@ packages:
|
|||||||
muggle-string@0.4.1:
|
muggle-string@0.4.1:
|
||||||
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
|
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
|
||||||
|
|
||||||
multer@2.0.0:
|
multer@2.0.1:
|
||||||
resolution: {integrity: sha512-bS8rPZurbAuHGAnApbM9d4h1wSoYqrOqkE+6a64KLMK9yWU7gJXBDDVklKQ3TPi9DRb85cRs6yXaC0+cjxRtRg==}
|
resolution: {integrity: sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==}
|
||||||
engines: {node: '>= 10.16.0'}
|
engines: {node: '>= 10.16.0'}
|
||||||
|
|
||||||
multicast-dns@7.2.5:
|
multicast-dns@7.2.5:
|
||||||
@ -9544,8 +9582,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
openai@5.0.2:
|
openai@5.1.0:
|
||||||
resolution: {integrity: sha512-NN7LAAImgBmd4RIe6WyRpLmwCbn+HQ1iaXeIG7K9DM3Auy/G2waKFhrDfRgaEeY0UUPnm6nohaCsqcS+zO8+2g==}
|
resolution: {integrity: sha512-YQBgPJykHrDOlngB/8QpOsFNg36yofBatpeDWg1zejl9R59/ELuN7AMPSU95ZIdChbKc/o5vg1UnBJ1OEB0IJA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
ws: ^8.18.0
|
ws: ^8.18.0
|
||||||
@ -12386,6 +12424,11 @@ packages:
|
|||||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
vite-node@3.2.1:
|
||||||
|
resolution: {integrity: sha512-V4EyKQPxquurNJPtQJRZo8hKOoKNBRIhxcDbQFPFig0JdoWcUhwRgK8yoCXXrfYVPKS6XwirGHPszLnR8FbjCA==}
|
||||||
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
vite-plugin-dts@4.5.4:
|
vite-plugin-dts@4.5.4:
|
||||||
resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==}
|
resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -12475,6 +12518,34 @@ packages:
|
|||||||
jsdom:
|
jsdom:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
vitest@3.2.1:
|
||||||
|
resolution: {integrity: sha512-VZ40MBnlE1/V5uTgdqY3DmjUgZtIzsYq758JGlyQrv5syIsaYcabkfPkEuWML49Ph0D/SoqpVFd0dyVTr551oA==}
|
||||||
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@edge-runtime/vm': '*'
|
||||||
|
'@types/debug': ^4.1.12
|
||||||
|
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
|
||||||
|
'@vitest/browser': 3.2.1
|
||||||
|
'@vitest/ui': 3.2.1
|
||||||
|
happy-dom: '*'
|
||||||
|
jsdom: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@edge-runtime/vm':
|
||||||
|
optional: true
|
||||||
|
'@types/debug':
|
||||||
|
optional: true
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser':
|
||||||
|
optional: true
|
||||||
|
'@vitest/ui':
|
||||||
|
optional: true
|
||||||
|
happy-dom:
|
||||||
|
optional: true
|
||||||
|
jsdom:
|
||||||
|
optional: true
|
||||||
|
|
||||||
vscode-jsonrpc@8.2.0:
|
vscode-jsonrpc@8.2.0:
|
||||||
resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
|
resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -13128,7 +13199,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.27.1
|
'@babel/types': 7.27.1
|
||||||
|
|
||||||
'@babel/parser@7.27.4':
|
'@babel/parser@7.27.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.27.3
|
'@babel/types': 7.27.3
|
||||||
|
|
||||||
@ -16377,7 +16448,7 @@ snapshots:
|
|||||||
- typescript
|
- typescript
|
||||||
- verdaccio
|
- verdaccio
|
||||||
|
|
||||||
'@nx/vite@21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.0)':
|
'@nx/vite@21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nx/devkit': 21.1.2(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))
|
'@nx/devkit': 21.1.2(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))
|
||||||
'@nx/js': 21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))
|
'@nx/js': 21.1.2(@babel/traverse@7.27.0)(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17))(nx@21.1.2(@swc-node/register@1.10.10(@swc/core@1.11.29(@swc/helpers@0.5.17))(@swc/types@0.1.21)(typescript@5.8.3))(@swc/core@1.11.29(@swc/helpers@0.5.17)))
|
||||||
@ -16389,7 +16460,7 @@ snapshots:
|
|||||||
semver: 7.7.2
|
semver: 7.7.2
|
||||||
tsconfig-paths: 4.2.0
|
tsconfig-paths: 4.2.0
|
||||||
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
vitest: 3.2.0(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/browser@3.2.0)(@vitest/ui@3.2.0)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
vitest: 3.2.1(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.1)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/traverse'
|
- '@babel/traverse'
|
||||||
- '@swc-node/register'
|
- '@swc-node/register'
|
||||||
@ -17241,7 +17312,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.27.4
|
'@babel/parser': 7.27.5
|
||||||
'@babel/types': 7.27.3
|
'@babel/types': 7.27.3
|
||||||
'@types/babel__generator': 7.27.0
|
'@types/babel__generator': 7.27.0
|
||||||
'@types/babel__template': 7.4.4
|
'@types/babel__template': 7.4.4
|
||||||
@ -17253,7 +17324,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/babel__template@7.4.4':
|
'@types/babel__template@7.4.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.27.4
|
'@babel/parser': 7.27.5
|
||||||
'@babel/types': 7.27.3
|
'@babel/types': 7.27.3
|
||||||
|
|
||||||
'@types/babel__traverse@7.20.7':
|
'@types/babel__traverse@7.20.7':
|
||||||
@ -17921,7 +17992,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@vitest/coverage-v8@3.2.0(@vitest/browser@3.2.0)(vitest@3.2.0)':
|
'@vitest/coverage-v8@3.2.1(vitest@3.2.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ampproject/remapping': 2.3.0
|
'@ampproject/remapping': 2.3.0
|
||||||
'@bcoe/v8-coverage': 1.0.2
|
'@bcoe/v8-coverage': 1.0.2
|
||||||
@ -17936,9 +18007,7 @@ snapshots:
|
|||||||
std-env: 3.9.0
|
std-env: 3.9.0
|
||||||
test-exclude: 7.0.1
|
test-exclude: 7.0.1
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.2.0(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/browser@3.2.0)(@vitest/ui@3.2.0)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
vitest: 3.2.1(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.1)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
optionalDependencies:
|
|
||||||
'@vitest/browser': 3.2.0(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(playwright@1.52.0)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.0)(webdriverio@9.15.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@ -17950,6 +18019,14 @@ snapshots:
|
|||||||
chai: 5.2.0
|
chai: 5.2.0
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
|
'@vitest/expect@3.2.1':
|
||||||
|
dependencies:
|
||||||
|
'@types/chai': 5.2.2
|
||||||
|
'@vitest/spy': 3.2.1
|
||||||
|
'@vitest/utils': 3.2.1
|
||||||
|
chai: 5.2.0
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@vitest/mocker@3.2.0(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))':
|
'@vitest/mocker@3.2.0(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/spy': 3.2.0
|
'@vitest/spy': 3.2.0
|
||||||
@ -17959,25 +18036,53 @@ snapshots:
|
|||||||
msw: 2.7.5(@types/node@22.15.29)(typescript@5.8.3)
|
msw: 2.7.5(@types/node@22.15.29)(typescript@5.8.3)
|
||||||
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
|
||||||
|
'@vitest/mocker@3.2.1(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 3.2.1
|
||||||
|
estree-walker: 3.0.3
|
||||||
|
magic-string: 0.30.17
|
||||||
|
optionalDependencies:
|
||||||
|
msw: 2.7.5(@types/node@22.15.29)(typescript@5.8.3)
|
||||||
|
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
|
||||||
'@vitest/pretty-format@3.2.0':
|
'@vitest/pretty-format@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
|
'@vitest/pretty-format@3.2.1':
|
||||||
|
dependencies:
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@vitest/runner@3.2.0':
|
'@vitest/runner@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/utils': 3.2.0
|
'@vitest/utils': 3.2.0
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
'@vitest/runner@3.2.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/utils': 3.2.1
|
||||||
|
pathe: 2.0.3
|
||||||
|
|
||||||
'@vitest/snapshot@3.2.0':
|
'@vitest/snapshot@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/pretty-format': 3.2.0
|
'@vitest/pretty-format': 3.2.0
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
'@vitest/snapshot@3.2.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 3.2.1
|
||||||
|
magic-string: 0.30.17
|
||||||
|
pathe: 2.0.3
|
||||||
|
|
||||||
'@vitest/spy@3.2.0':
|
'@vitest/spy@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
tinyspy: 4.0.3
|
tinyspy: 4.0.3
|
||||||
|
|
||||||
|
'@vitest/spy@3.2.1':
|
||||||
|
dependencies:
|
||||||
|
tinyspy: 4.0.3
|
||||||
|
|
||||||
'@vitest/ui@3.2.0(vitest@3.2.0)':
|
'@vitest/ui@3.2.0(vitest@3.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/utils': 3.2.0
|
'@vitest/utils': 3.2.0
|
||||||
@ -17988,6 +18093,18 @@ snapshots:
|
|||||||
tinyglobby: 0.2.14
|
tinyglobby: 0.2.14
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.2.0(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/browser@3.2.0)(@vitest/ui@3.2.0)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
vitest: 3.2.0(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/browser@3.2.0)(@vitest/ui@3.2.0)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@vitest/ui@3.2.1(vitest@3.2.1)':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/utils': 3.2.1
|
||||||
|
fflate: 0.8.2
|
||||||
|
flatted: 3.3.3
|
||||||
|
pathe: 2.0.3
|
||||||
|
sirv: 3.0.1
|
||||||
|
tinyglobby: 0.2.14
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
vitest: 3.2.1(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.1)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
|
||||||
'@vitest/utils@3.2.0':
|
'@vitest/utils@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -17995,6 +18112,12 @@ snapshots:
|
|||||||
loupe: 3.1.3
|
loupe: 3.1.3
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
|
'@vitest/utils@3.2.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 3.2.1
|
||||||
|
loupe: 3.1.3
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@volar/language-core@2.4.13':
|
'@volar/language-core@2.4.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/source-map': 2.4.13
|
'@volar/source-map': 2.4.13
|
||||||
@ -18009,7 +18132,7 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/compiler-core@3.5.14':
|
'@vue/compiler-core@3.5.14':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.27.4
|
'@babel/parser': 7.27.5
|
||||||
'@vue/shared': 3.5.14
|
'@vue/shared': 3.5.14
|
||||||
entities: 4.5.0
|
entities: 4.5.0
|
||||||
estree-walker: 2.0.2
|
estree-walker: 2.0.2
|
||||||
@ -19290,6 +19413,13 @@ snapshots:
|
|||||||
readable-stream: 2.3.8
|
readable-stream: 2.3.8
|
||||||
typedarray: 0.0.6
|
typedarray: 0.0.6
|
||||||
|
|
||||||
|
concat-stream@2.0.0:
|
||||||
|
dependencies:
|
||||||
|
buffer-from: 1.1.2
|
||||||
|
inherits: 2.0.4
|
||||||
|
readable-stream: 3.6.2
|
||||||
|
typedarray: 0.0.6
|
||||||
|
|
||||||
confbox@0.1.8: {}
|
confbox@0.1.8: {}
|
||||||
|
|
||||||
confbox@0.2.2: {}
|
confbox@0.2.2: {}
|
||||||
@ -22034,7 +22164,7 @@ snapshots:
|
|||||||
istanbul-lib-instrument@5.2.1:
|
istanbul-lib-instrument@5.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.10
|
'@babel/core': 7.26.10
|
||||||
'@babel/parser': 7.27.4
|
'@babel/parser': 7.27.5
|
||||||
'@istanbuljs/schema': 0.1.3
|
'@istanbuljs/schema': 0.1.3
|
||||||
istanbul-lib-coverage: 3.2.2
|
istanbul-lib-coverage: 3.2.2
|
||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
@ -22839,7 +22969,7 @@ snapshots:
|
|||||||
|
|
||||||
magicast@0.3.5:
|
magicast@0.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.27.4
|
'@babel/parser': 7.27.5
|
||||||
'@babel/types': 7.27.3
|
'@babel/types': 7.27.3
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
@ -23428,11 +23558,11 @@ snapshots:
|
|||||||
|
|
||||||
muggle-string@0.4.1: {}
|
muggle-string@0.4.1: {}
|
||||||
|
|
||||||
multer@2.0.0:
|
multer@2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
append-field: 1.0.0
|
append-field: 1.0.0
|
||||||
busboy: 1.6.0
|
busboy: 1.6.0
|
||||||
concat-stream: 1.6.2
|
concat-stream: 2.0.0
|
||||||
mkdirp: 0.5.6
|
mkdirp: 0.5.6
|
||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
type-is: 1.6.18
|
type-is: 1.6.18
|
||||||
@ -23761,7 +23891,7 @@ snapshots:
|
|||||||
is-docker: 2.2.1
|
is-docker: 2.2.1
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
|
|
||||||
openai@5.0.2(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4):
|
openai@5.1.0(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||||
zod: 3.24.4
|
zod: 3.24.4
|
||||||
@ -26868,6 +26998,27 @@ snapshots:
|
|||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
|
vite-node@3.2.1(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0):
|
||||||
|
dependencies:
|
||||||
|
cac: 6.7.14
|
||||||
|
debug: 4.4.1(supports-color@6.0.0)
|
||||||
|
es-module-lexer: 1.7.0
|
||||||
|
pathe: 2.0.3
|
||||||
|
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
- jiti
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
- tsx
|
||||||
|
- yaml
|
||||||
|
|
||||||
vite-plugin-dts@4.5.4(@types/node@22.15.29)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)):
|
vite-plugin-dts@4.5.4(@types/node@22.15.29)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@microsoft/api-extractor': 7.52.8(@types/node@22.15.29)
|
'@microsoft/api-extractor': 7.52.8(@types/node@22.15.29)
|
||||||
@ -26969,6 +27120,51 @@ snapshots:
|
|||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
|
vitest@3.2.1(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.1)(happy-dom@17.6.1)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0):
|
||||||
|
dependencies:
|
||||||
|
'@types/chai': 5.2.2
|
||||||
|
'@vitest/expect': 3.2.1
|
||||||
|
'@vitest/mocker': 3.2.1(msw@2.7.5(@types/node@22.15.29)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0))
|
||||||
|
'@vitest/pretty-format': 3.2.1
|
||||||
|
'@vitest/runner': 3.2.1
|
||||||
|
'@vitest/snapshot': 3.2.1
|
||||||
|
'@vitest/spy': 3.2.1
|
||||||
|
'@vitest/utils': 3.2.1
|
||||||
|
chai: 5.2.0
|
||||||
|
debug: 4.4.1(supports-color@6.0.0)
|
||||||
|
expect-type: 1.2.1
|
||||||
|
magic-string: 0.30.17
|
||||||
|
pathe: 2.0.3
|
||||||
|
picomatch: 4.0.2
|
||||||
|
std-env: 3.9.0
|
||||||
|
tinybench: 2.9.0
|
||||||
|
tinyexec: 0.3.2
|
||||||
|
tinyglobby: 0.2.14
|
||||||
|
tinypool: 1.1.0
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
vite-node: 3.2.1(@types/node@22.15.29)(jiti@2.4.2)(less@4.1.3)(sass-embedded@1.87.0)(sass@1.87.0)(stylus@0.64.0)(sugarss@4.0.1(postcss@8.5.3))(terser@5.39.0)(tsx@4.19.4)(yaml@2.8.0)
|
||||||
|
why-is-node-running: 2.3.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/debug': 4.1.12
|
||||||
|
'@types/node': 22.15.29
|
||||||
|
'@vitest/ui': 3.2.1(vitest@3.2.1)
|
||||||
|
happy-dom: 17.6.1
|
||||||
|
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- jiti
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- msw
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
- tsx
|
||||||
|
- yaml
|
||||||
|
|
||||||
vscode-jsonrpc@8.2.0: {}
|
vscode-jsonrpc@8.2.0: {}
|
||||||
|
|
||||||
vscode-languageserver-protocol@3.17.5:
|
vscode-languageserver-protocol@3.17.5:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user