@real1ty-obsidian-plugins/utils 2.22.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,11 @@ export declare function isTemplaterAvailable(app: App): boolean;
13
13
  * Checks if a template should be used based on availability and file existence.
14
14
  */
15
15
  export declare function shouldUseTemplate(app: App, templatePath: string | undefined): boolean;
16
+ /**
17
+ * Creates a file at the specified full path with optional frontmatter and content.
18
+ * Returns existing file if it already exists.
19
+ */
20
+ export declare function createFileAtPath(app: App, filePath: string, content?: string, frontmatter?: Record<string, unknown>): Promise<TFile>;
16
21
  /**
17
22
  * Creates a file manually with optional frontmatter and content.
18
23
  * Returns existing file if it already exists.
@@ -1 +1 @@
1
- {"version":3,"file":"templater.d.ts","sourceRoot":"","sources":["../../src/file/templater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAyB,KAAK,EAAE,MAAM,UAAU,CAAC;AAiBlE,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAmBD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAGtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAOrF;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,GAAG,EACR,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,KAAK,CAAC,CAqBhB;AAED,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,UAAQ,EACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CA8CvB;AAED,wBAAsB,sBAAsB,CAC3C,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,mBAAmB,GAC1B,OAAO,CAAC,KAAK,CAAC,CA4BhB"}
1
+ {"version":3,"file":"templater.d.ts","sourceRoot":"","sources":["../../src/file/templater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAyB,KAAK,EAAE,MAAM,UAAU,CAAC;AAiBlE,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAmBD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAGtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAOrF;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,KAAK,CAAC,CAkBhB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,GAAG,EACR,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,KAAK,CAAC,CAKhB;AAED,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,UAAQ,EACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CA8CvB;AAED,wBAAsB,sBAAsB,CAC3C,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,mBAAmB,GAC1B,OAAO,CAAC,KAAK,CAAC,CA4BhB"}
@@ -35,13 +35,11 @@ export function shouldUseTemplate(app, templatePath) {
35
35
  app.vault.getFileByPath(templatePath));
36
36
  }
37
37
  /**
38
- * Creates a file manually with optional frontmatter and content.
38
+ * Creates a file at the specified full path with optional frontmatter and content.
39
39
  * Returns existing file if it already exists.
40
40
  */
41
- export function createFileManually(app, targetDirectory, filename, content, frontmatter) {
41
+ export function createFileAtPath(app, filePath, content, frontmatter) {
42
42
  return __awaiter(this, void 0, void 0, function* () {
43
- const baseName = filename.replace(/\.md$/, "");
44
- const filePath = `${targetDirectory}/${baseName}.md`;
45
43
  // Check if file already exists
46
44
  const existingFile = app.vault.getAbstractFileByPath(filePath);
47
45
  if (existingFile instanceof TFile) {
@@ -59,6 +57,17 @@ export function createFileManually(app, targetDirectory, filename, content, fron
59
57
  return file;
60
58
  });
61
59
  }
60
+ /**
61
+ * Creates a file manually with optional frontmatter and content.
62
+ * Returns existing file if it already exists.
63
+ */
64
+ export function createFileManually(app, targetDirectory, filename, content, frontmatter) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ const baseName = filename.replace(/\.md$/, "");
67
+ const filePath = `${targetDirectory}/${baseName}.md`;
68
+ return createFileAtPath(app, filePath, content, frontmatter);
69
+ });
70
+ }
62
71
  export function createFromTemplate(app_1, templatePath_1, targetFolder_1, filename_1) {
63
72
  return __awaiter(this, arguments, void 0, function* (app, templatePath, targetFolder, filename, openNewNote = false, frontmatter) {
64
73
  const templater = yield waitForTemplater(app);
@@ -1 +1 @@
1
- {"version":3,"file":"templater.js","sourceRoot":"","sources":["../../src/file/templater.ts"],"names":[],"mappings":"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","sourcesContent":["import { type App, Notice, normalizePath, TFile } from \"obsidian\";\nimport { waitForFileReady } from \"./file-utils\";\nimport { createFileContentWithFrontmatter } from \"./frontmatter-serialization\";\n\nconst TEMPLATER_ID = \"templater-obsidian\";\n\ntype CreateFn = (\n\ttemplateFile: TFile,\n\tfolder?: string,\n\tfilename?: string,\n\topenNewNote?: boolean\n) => Promise<TFile | undefined>;\n\ninterface TemplaterLike {\n\tcreate_new_note_from_template: CreateFn;\n}\n\nexport interface FileCreationOptions {\n\ttitle: string;\n\ttargetDirectory: string;\n\tfilename?: string;\n\tcontent?: string;\n\tfrontmatter?: Record<string, unknown>;\n\ttemplatePath?: string;\n\tuseTemplater?: boolean;\n}\n\nasync function waitForTemplater(app: App, timeoutMs = 8000): Promise<TemplaterLike | null> {\n\tawait new Promise<void>((resolve) => app.workspace.onLayoutReady(resolve));\n\n\tconst started = Date.now();\n\twhile (Date.now() - started < timeoutMs) {\n\t\tconst plug: any = (app as any).plugins?.getPlugin?.(TEMPLATER_ID);\n\t\tconst api = plug?.templater ?? null;\n\n\t\tconst createFn: CreateFn | undefined = api?.create_new_note_from_template?.bind(api);\n\t\tif (typeof createFn === \"function\") {\n\t\t\treturn { create_new_note_from_template: createFn };\n\t\t}\n\t\tawait new Promise((r) => setTimeout(r, 150));\n\t}\n\treturn null;\n}\n\nexport function isTemplaterAvailable(app: App): boolean {\n\tconst instance = (app as any).plugins?.getPlugin?.(TEMPLATER_ID);\n\treturn !!instance;\n}\n\n/**\n * Checks if a template should be used based on availability and file existence.\n */\nexport function shouldUseTemplate(app: App, templatePath: string | undefined): boolean {\n\treturn !!(\n\t\ttemplatePath &&\n\t\ttemplatePath.trim() !== \"\" &&\n\t\tisTemplaterAvailable(app) &&\n\t\tapp.vault.getFileByPath(templatePath)\n\t);\n}\n\n/**\n * Creates a file manually with optional frontmatter and content.\n * Returns existing file if it already exists.\n */\nexport async function createFileManually(\n\tapp: App,\n\ttargetDirectory: string,\n\tfilename: string,\n\tcontent?: string,\n\tfrontmatter?: Record<string, unknown>\n): Promise<TFile> {\n\tconst baseName = filename.replace(/\\.md$/, \"\");\n\tconst filePath = `${targetDirectory}/${baseName}.md`;\n\n\t// Check if file already exists\n\tconst existingFile = app.vault.getAbstractFileByPath(filePath);\n\tif (existingFile instanceof TFile) {\n\t\treturn existingFile;\n\t}\n\n\tconst bodyContent = content || \"\";\n\n\tlet fileContent: string;\n\tif (frontmatter && Object.keys(frontmatter).length > 0) {\n\t\tfileContent = createFileContentWithFrontmatter(frontmatter, bodyContent);\n\t} else {\n\t\tfileContent = bodyContent;\n\t}\n\n\tconst file = await app.vault.create(filePath, fileContent);\n\treturn file;\n}\n\nexport async function createFromTemplate(\n\tapp: App,\n\ttemplatePath: string,\n\ttargetFolder?: string,\n\tfilename?: string,\n\topenNewNote = false,\n\tfrontmatter?: Record<string, unknown>\n): Promise<TFile | null> {\n\tconst templater = await waitForTemplater(app);\n\tif (!templater) {\n\t\tconsole.warn(\"Templater isn't ready yet (or not installed/enabled).\");\n\t\tnew Notice(\n\t\t\t\"Templater plugin is not available or enabled. Please ensure it is installed and enabled.\"\n\t\t);\n\t\treturn null;\n\t}\n\n\tconst templateFile = app.vault.getFileByPath(normalizePath(templatePath));\n\tif (!templateFile) {\n\t\tconsole.error(`Template not found: ${templatePath}`);\n\t\tnew Notice(`Template file not found: ${templatePath}. Please ensure the template file exists.`);\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst newFile = await templater.create_new_note_from_template(\n\t\t\ttemplateFile,\n\t\t\ttargetFolder,\n\t\t\tfilename,\n\t\t\topenNewNote\n\t\t);\n\n\t\tif (!newFile) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (frontmatter && Object.keys(frontmatter).length > 0) {\n\t\t\tconst readyFile = await waitForFileReady(app, newFile.path);\n\n\t\t\tif (readyFile) {\n\t\t\t\tawait app.fileManager.processFrontMatter(readyFile, (fm) => {\n\t\t\t\t\tObject.assign(fm, frontmatter);\n\t\t\t\t});\n\t\t\t\treturn readyFile;\n\t\t\t}\n\t\t}\n\n\t\treturn newFile;\n\t} catch (error) {\n\t\tconsole.error(\"Error creating file from template:\", error);\n\t\tnew Notice(\"Error creating file from template. Please ensure the template file is valid.\");\n\t\treturn null;\n\t}\n}\n\nexport async function createFileWithTemplate(\n\tapp: App,\n\toptions: FileCreationOptions\n): Promise<TFile> {\n\tconst { title, targetDirectory, filename, content, frontmatter, templatePath, useTemplater } =\n\t\toptions;\n\n\tconst finalFilename = filename || title;\n\n\t// If content is provided, use manual creation to preserve the content\n\tif (content) {\n\t\treturn createFileManually(app, targetDirectory, finalFilename, content, frontmatter);\n\t}\n\n\t// Try to use template if requested and available\n\tif (useTemplater && shouldUseTemplate(app, templatePath)) {\n\t\tconst templateFile = await createFromTemplate(\n\t\t\tapp,\n\t\t\ttemplatePath!,\n\t\t\ttargetDirectory,\n\t\t\tfinalFilename,\n\t\t\tfalse,\n\t\t\tfrontmatter\n\t\t);\n\n\t\tif (templateFile) {\n\t\t\treturn templateFile;\n\t\t}\n\t}\n\n\treturn createFileManually(app, targetDirectory, finalFilename, content, frontmatter);\n}\n"]}
1
+ {"version":3,"file":"templater.js","sourceRoot":"","sources":["../../src/file/templater.ts"],"names":[],"mappings":"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","sourcesContent":["import { type App, Notice, normalizePath, TFile } from \"obsidian\";\nimport { waitForFileReady } from \"./file-utils\";\nimport { createFileContentWithFrontmatter } from \"./frontmatter-serialization\";\n\nconst TEMPLATER_ID = \"templater-obsidian\";\n\ntype CreateFn = (\n\ttemplateFile: TFile,\n\tfolder?: string,\n\tfilename?: string,\n\topenNewNote?: boolean\n) => Promise<TFile | undefined>;\n\ninterface TemplaterLike {\n\tcreate_new_note_from_template: CreateFn;\n}\n\nexport interface FileCreationOptions {\n\ttitle: string;\n\ttargetDirectory: string;\n\tfilename?: string;\n\tcontent?: string;\n\tfrontmatter?: Record<string, unknown>;\n\ttemplatePath?: string;\n\tuseTemplater?: boolean;\n}\n\nasync function waitForTemplater(app: App, timeoutMs = 8000): Promise<TemplaterLike | null> {\n\tawait new Promise<void>((resolve) => app.workspace.onLayoutReady(resolve));\n\n\tconst started = Date.now();\n\twhile (Date.now() - started < timeoutMs) {\n\t\tconst plug: any = (app as any).plugins?.getPlugin?.(TEMPLATER_ID);\n\t\tconst api = plug?.templater ?? null;\n\n\t\tconst createFn: CreateFn | undefined = api?.create_new_note_from_template?.bind(api);\n\t\tif (typeof createFn === \"function\") {\n\t\t\treturn { create_new_note_from_template: createFn };\n\t\t}\n\t\tawait new Promise((r) => setTimeout(r, 150));\n\t}\n\treturn null;\n}\n\nexport function isTemplaterAvailable(app: App): boolean {\n\tconst instance = (app as any).plugins?.getPlugin?.(TEMPLATER_ID);\n\treturn !!instance;\n}\n\n/**\n * Checks if a template should be used based on availability and file existence.\n */\nexport function shouldUseTemplate(app: App, templatePath: string | undefined): boolean {\n\treturn !!(\n\t\ttemplatePath &&\n\t\ttemplatePath.trim() !== \"\" &&\n\t\tisTemplaterAvailable(app) &&\n\t\tapp.vault.getFileByPath(templatePath)\n\t);\n}\n\n/**\n * Creates a file at the specified full path with optional frontmatter and content.\n * Returns existing file if it already exists.\n */\nexport async function createFileAtPath(\n\tapp: App,\n\tfilePath: string,\n\tcontent?: string,\n\tfrontmatter?: Record<string, unknown>\n): Promise<TFile> {\n\t// Check if file already exists\n\tconst existingFile = app.vault.getAbstractFileByPath(filePath);\n\tif (existingFile instanceof TFile) {\n\t\treturn existingFile;\n\t}\n\n\tconst bodyContent = content || \"\";\n\n\tlet fileContent: string;\n\tif (frontmatter && Object.keys(frontmatter).length > 0) {\n\t\tfileContent = createFileContentWithFrontmatter(frontmatter, bodyContent);\n\t} else {\n\t\tfileContent = bodyContent;\n\t}\n\n\tconst file = await app.vault.create(filePath, fileContent);\n\treturn file;\n}\n\n/**\n * Creates a file manually with optional frontmatter and content.\n * Returns existing file if it already exists.\n */\nexport async function createFileManually(\n\tapp: App,\n\ttargetDirectory: string,\n\tfilename: string,\n\tcontent?: string,\n\tfrontmatter?: Record<string, unknown>\n): Promise<TFile> {\n\tconst baseName = filename.replace(/\\.md$/, \"\");\n\tconst filePath = `${targetDirectory}/${baseName}.md`;\n\n\treturn createFileAtPath(app, filePath, content, frontmatter);\n}\n\nexport async function createFromTemplate(\n\tapp: App,\n\ttemplatePath: string,\n\ttargetFolder?: string,\n\tfilename?: string,\n\topenNewNote = false,\n\tfrontmatter?: Record<string, unknown>\n): Promise<TFile | null> {\n\tconst templater = await waitForTemplater(app);\n\tif (!templater) {\n\t\tconsole.warn(\"Templater isn't ready yet (or not installed/enabled).\");\n\t\tnew Notice(\n\t\t\t\"Templater plugin is not available or enabled. Please ensure it is installed and enabled.\"\n\t\t);\n\t\treturn null;\n\t}\n\n\tconst templateFile = app.vault.getFileByPath(normalizePath(templatePath));\n\tif (!templateFile) {\n\t\tconsole.error(`Template not found: ${templatePath}`);\n\t\tnew Notice(`Template file not found: ${templatePath}. Please ensure the template file exists.`);\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst newFile = await templater.create_new_note_from_template(\n\t\t\ttemplateFile,\n\t\t\ttargetFolder,\n\t\t\tfilename,\n\t\t\topenNewNote\n\t\t);\n\n\t\tif (!newFile) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (frontmatter && Object.keys(frontmatter).length > 0) {\n\t\t\tconst readyFile = await waitForFileReady(app, newFile.path);\n\n\t\t\tif (readyFile) {\n\t\t\t\tawait app.fileManager.processFrontMatter(readyFile, (fm) => {\n\t\t\t\t\tObject.assign(fm, frontmatter);\n\t\t\t\t});\n\t\t\t\treturn readyFile;\n\t\t\t}\n\t\t}\n\n\t\treturn newFile;\n\t} catch (error) {\n\t\tconsole.error(\"Error creating file from template:\", error);\n\t\tnew Notice(\"Error creating file from template. Please ensure the template file is valid.\");\n\t\treturn null;\n\t}\n}\n\nexport async function createFileWithTemplate(\n\tapp: App,\n\toptions: FileCreationOptions\n): Promise<TFile> {\n\tconst { title, targetDirectory, filename, content, frontmatter, templatePath, useTemplater } =\n\t\toptions;\n\n\tconst finalFilename = filename || title;\n\n\t// If content is provided, use manual creation to preserve the content\n\tif (content) {\n\t\treturn createFileManually(app, targetDirectory, finalFilename, content, frontmatter);\n\t}\n\n\t// Try to use template if requested and available\n\tif (useTemplater && shouldUseTemplate(app, templatePath)) {\n\t\tconst templateFile = await createFromTemplate(\n\t\t\tapp,\n\t\t\ttemplatePath!,\n\t\t\ttargetDirectory,\n\t\t\tfinalFilename,\n\t\t\tfalse,\n\t\t\tfrontmatter\n\t\t);\n\n\t\tif (templateFile) {\n\t\t\treturn templateFile;\n\t\t}\n\t}\n\n\treturn createFileManually(app, targetDirectory, finalFilename, content, frontmatter);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real1ty-obsidian-plugins/utils",
3
- "version": "2.22.0",
3
+ "version": "2.23.0",
4
4
  "description": "Shared utilities for Obsidian plugins",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,19 +60,15 @@ export function shouldUseTemplate(app: App, templatePath: string | undefined): b
60
60
  }
61
61
 
62
62
  /**
63
- * Creates a file manually with optional frontmatter and content.
63
+ * Creates a file at the specified full path with optional frontmatter and content.
64
64
  * Returns existing file if it already exists.
65
65
  */
66
- export async function createFileManually(
66
+ export async function createFileAtPath(
67
67
  app: App,
68
- targetDirectory: string,
69
- filename: string,
68
+ filePath: string,
70
69
  content?: string,
71
70
  frontmatter?: Record<string, unknown>
72
71
  ): Promise<TFile> {
73
- const baseName = filename.replace(/\.md$/, "");
74
- const filePath = `${targetDirectory}/${baseName}.md`;
75
-
76
72
  // Check if file already exists
77
73
  const existingFile = app.vault.getAbstractFileByPath(filePath);
78
74
  if (existingFile instanceof TFile) {
@@ -92,6 +88,23 @@ export async function createFileManually(
92
88
  return file;
93
89
  }
94
90
 
91
+ /**
92
+ * Creates a file manually with optional frontmatter and content.
93
+ * Returns existing file if it already exists.
94
+ */
95
+ export async function createFileManually(
96
+ app: App,
97
+ targetDirectory: string,
98
+ filename: string,
99
+ content?: string,
100
+ frontmatter?: Record<string, unknown>
101
+ ): Promise<TFile> {
102
+ const baseName = filename.replace(/\.md$/, "");
103
+ const filePath = `${targetDirectory}/${baseName}.md`;
104
+
105
+ return createFileAtPath(app, filePath, content, frontmatter);
106
+ }
107
+
95
108
  export async function createFromTemplate(
96
109
  app: App,
97
110
  templatePath: string,