obsidian-plugin-config 1.4.7 → 1.5.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.
@@ -44,6 +44,16 @@ async function main(): Promise<void> {
44
44
  process.exit(1);
45
45
  }
46
46
 
47
+ // Prevent injecting into obsidian-plugin-config itself
48
+ const selfPkg = path.join(resolvedPath, 'package.json');
49
+ if (fs.existsSync(selfPkg)) {
50
+ const pkg = JSON.parse(fs.readFileSync(selfPkg, 'utf8'));
51
+ if (pkg.name === 'obsidian-plugin-config') {
52
+ console.error(`āŒ Cannot inject into obsidian-plugin-config itself.`);
53
+ process.exit(1);
54
+ }
55
+ }
56
+
47
57
  console.log(`šŸ“ Target directory: ${resolvedPath}`);
48
58
  console.log(`\nšŸ” Analyzing plugin...`);
49
59
  const plan = await analyzePlugin(resolvedPath);
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
2
 
3
+ import fs from 'fs';
3
4
  import path from 'path';
4
5
  import {
5
6
  analyzePlugin,
@@ -71,6 +72,16 @@ async function main(): Promise<void> {
71
72
  targetPath = await promptForTargetPath();
72
73
  }
73
74
 
75
+ // Prevent injecting into obsidian-plugin-config itself
76
+ const selfPkg = path.join(targetPath, 'package.json');
77
+ if (fs.existsSync(selfPkg)) {
78
+ const pkg = JSON.parse(fs.readFileSync(selfPkg, 'utf8'));
79
+ if (pkg.name === 'obsidian-plugin-config') {
80
+ console.error(`āŒ Cannot inject into obsidian-plugin-config itself.`);
81
+ process.exit(1);
82
+ }
83
+ }
84
+
74
85
  console.log(`\nšŸ” Checking plugin-config repository status...`);
75
86
  await ensurePluginConfigClean();
76
87
 
package/scripts/utils.ts CHANGED
@@ -1,151 +1,151 @@
1
- import { access, mkdir, copyFile, rm } from 'fs/promises';
2
- import path from 'path';
3
- import * as readline from 'readline';
4
- import { execSync } from 'child_process';
5
-
6
- export function createReadlineInterface(): readline.Interface {
7
- return readline.createInterface({
8
- input: process.stdin as NodeJS.ReadableStream,
9
- output: process.stdout as NodeJS.WritableStream
10
- });
11
- }
12
-
13
- export const askQuestion = async (
14
- question: string,
15
- rl: readline.Interface
16
- ): Promise<string> => {
17
- try {
18
- return await new Promise((resolve) =>
19
- rl.question(question, (input) => resolve(input.trim()))
20
- );
21
- } catch (error) {
22
- console.error('Error asking question:', error);
23
- throw error;
24
- }
25
- };
26
-
27
- /**
28
- * Ask a yes/no confirmation question with standardized logic
29
- * Accepts: y, yes, Y, YES, or empty (default to yes)
30
- * Rejects: n, no, N, NO
31
- * Invalid input defaults to no for safety
32
- */
33
- export const askConfirmation = async (
34
- question: string,
35
- rl: readline.Interface
36
- ): Promise<boolean> => {
37
- const answer = await askQuestion(`${question} [Y/n]: `, rl);
38
- const response = answer.toLowerCase();
39
-
40
- // Accept: y, yes, Y, YES, or empty (default to yes)
41
- // Reject: n, no, N, NO
42
- const isYes = response === '' || response === 'y' || response === 'yes';
43
- const isNo = response === 'n' || response === 'no';
44
-
45
- if (isNo) {
46
- return false;
47
- } else if (isYes) {
48
- return true;
49
- } else {
50
- console.log('Please answer Y (yes) or n (no). Defaulting to no for safety.');
51
- return false;
52
- }
53
- };
54
-
55
- export const cleanInput = (inputStr: string): string => {
56
- if (!inputStr) return '';
57
- return inputStr.trim().replace(/["`]/g, "'").replace(/\r\n/g, '\n');
58
- };
59
-
60
- export const isValidPath = async (pathToCheck: string): Promise<boolean> => {
61
- if (!pathToCheck) return false;
62
-
63
- try {
64
- // Using async fs.access is preferred over synchronous existsSync
65
- // as it doesn't block the main thread/event loop
66
- await access(pathToCheck.trim());
67
- return true;
68
- } catch {
69
- return false;
70
- }
71
- };
72
-
73
- export async function copyFilesToTargetDir(buildPath: string): Promise<void> {
74
- const pluginDir = process.cwd();
75
- const manifestSrc = path.join(pluginDir, 'manifest.json');
76
- const manifestDest = path.join(buildPath, 'manifest.json');
77
- const cssDest = path.join(buildPath, 'styles.css');
78
- const folderToRemove = path.join(buildPath, '_.._');
79
-
80
- try {
81
- await mkdir(buildPath, { recursive: true });
82
- } catch (error: unknown) {
83
- if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {
84
- console.error(`Error creating directory: ${(error as Error).message}`);
85
- }
86
- }
87
-
88
- // Copy manifest
89
- try {
90
- await copyFile(manifestSrc, manifestDest);
91
- } catch (error: unknown) {
92
- console.error(`Error copying manifest: ${(error as Error).message}`);
93
- }
94
-
95
- // Copy CSS
96
- try {
97
- const srcStylesPath = path.join(pluginDir, 'src/styles.css');
98
- const rootStylesPath = path.join(pluginDir, 'styles.css');
99
-
100
- // First check if CSS exists in src/styles.css
101
- if (await isValidPath(srcStylesPath)) {
102
- await copyFile(srcStylesPath, cssDest);
103
- }
104
- // Otherwise, check if it exists in the root
105
- else if (await isValidPath(rootStylesPath)) {
106
- await copyFile(rootStylesPath, cssDest);
107
- if (await isValidPath(folderToRemove)) {
108
- await rm(folderToRemove, { recursive: true });
109
- }
110
- } else {
111
- return;
112
- }
113
- } catch (error: unknown) {
114
- console.error(`Error copying CSS: ${(error as Error).message}`);
115
- }
116
- }
117
-
118
- export function gitExec(command: string): void {
119
- try {
120
- execSync(command, { stdio: 'inherit' });
121
- } catch (error: unknown) {
122
- console.error(`Error executing '${command}':`, (error as Error).message);
123
- throw error;
124
- }
125
- }
126
-
127
- /**
128
- * Ensure Git repository is synchronized with remote before pushing
129
- */
130
- export async function ensureGitSync(): Promise<void> {
131
- try {
132
- console.log('šŸ”„ Checking Git synchronization...');
133
-
134
- // Fetch latest changes from remote
135
- execSync('git fetch origin', { stdio: 'pipe' });
136
-
137
- // Check if branch is behind remote
138
- const status = execSync('git status --porcelain -b', { encoding: 'utf8' });
139
-
140
- if (status.includes('behind')) {
141
- console.log('šŸ“„ Branch behind remote. Pulling changes...');
142
- execSync('git pull', { stdio: 'inherit' });
143
- console.log('āœ… Successfully pulled remote changes');
144
- } else {
145
- console.log('āœ… Repository is synchronized with remote');
146
- }
147
- } catch (error: unknown) {
148
- console.error(`āŒ Git sync failed: ${(error as Error).message}`);
149
- throw error;
150
- }
151
- }
1
+ import { access, mkdir, copyFile, rm } from 'fs/promises';
2
+ import path from 'path';
3
+ import * as readline from 'readline';
4
+ import { execSync } from 'child_process';
5
+
6
+ export function createReadlineInterface(): readline.Interface {
7
+ return readline.createInterface({
8
+ input: process.stdin as NodeJS.ReadableStream,
9
+ output: process.stdout as NodeJS.WritableStream
10
+ });
11
+ }
12
+
13
+ export const askQuestion = async (
14
+ question: string,
15
+ rl: readline.Interface
16
+ ): Promise<string> => {
17
+ try {
18
+ return await new Promise((resolve) =>
19
+ rl.question(question, (input) => resolve(input.trim()))
20
+ );
21
+ } catch (error) {
22
+ console.error('Error asking question:', error);
23
+ throw error;
24
+ }
25
+ };
26
+
27
+ /**
28
+ * Ask a yes/no confirmation question with standardized logic
29
+ * Accepts: y, yes, Y, YES, or empty (default to yes)
30
+ * Rejects: n, no, N, NO
31
+ * Invalid input defaults to no for safety
32
+ */
33
+ export const askConfirmation = async (
34
+ question: string,
35
+ rl: readline.Interface
36
+ ): Promise<boolean> => {
37
+ const answer = await askQuestion(`${question} [Y/n]: `, rl);
38
+ const response = answer.toLowerCase();
39
+
40
+ // Accept: y, yes, Y, YES, or empty (default to yes)
41
+ // Reject: n, no, N, NO
42
+ const isYes = response === '' || response === 'y' || response === 'yes';
43
+ const isNo = response === 'n' || response === 'no';
44
+
45
+ if (isNo) {
46
+ return false;
47
+ } else if (isYes) {
48
+ return true;
49
+ } else {
50
+ console.log('Please answer Y (yes) or n (no). Defaulting to no for safety.');
51
+ return false;
52
+ }
53
+ };
54
+
55
+ export const cleanInput = (inputStr: string): string => {
56
+ if (!inputStr) return '';
57
+ return inputStr.trim().replace(/["`]/g, "'").replace(/\r\n/g, '\n');
58
+ };
59
+
60
+ export const isValidPath = async (pathToCheck: string): Promise<boolean> => {
61
+ if (!pathToCheck) return false;
62
+
63
+ try {
64
+ // Using async fs.access is preferred over synchronous existsSync
65
+ // as it doesn't block the main thread/event loop
66
+ await access(pathToCheck.trim());
67
+ return true;
68
+ } catch {
69
+ return false;
70
+ }
71
+ };
72
+
73
+ export async function copyFilesToTargetDir(buildPath: string): Promise<void> {
74
+ const pluginDir = process.cwd();
75
+ const manifestSrc = path.join(pluginDir, 'manifest.json');
76
+ const manifestDest = path.join(buildPath, 'manifest.json');
77
+ const cssDest = path.join(buildPath, 'styles.css');
78
+ const folderToRemove = path.join(buildPath, '_.._');
79
+
80
+ try {
81
+ await mkdir(buildPath, { recursive: true });
82
+ } catch (error: unknown) {
83
+ if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {
84
+ console.error(`Error creating directory: ${(error as Error).message}`);
85
+ }
86
+ }
87
+
88
+ // Copy manifest
89
+ try {
90
+ await copyFile(manifestSrc, manifestDest);
91
+ } catch (error: unknown) {
92
+ console.error(`Error copying manifest: ${(error as Error).message}`);
93
+ }
94
+
95
+ // Copy CSS
96
+ try {
97
+ const srcStylesPath = path.join(pluginDir, 'src/styles.css');
98
+ const rootStylesPath = path.join(pluginDir, 'styles.css');
99
+
100
+ // First check if CSS exists in src/styles.css
101
+ if (await isValidPath(srcStylesPath)) {
102
+ await copyFile(srcStylesPath, cssDest);
103
+ }
104
+ // Otherwise, check if it exists in the root
105
+ else if (await isValidPath(rootStylesPath)) {
106
+ await copyFile(rootStylesPath, cssDest);
107
+ if (await isValidPath(folderToRemove)) {
108
+ await rm(folderToRemove, { recursive: true });
109
+ }
110
+ } else {
111
+ return;
112
+ }
113
+ } catch (error: unknown) {
114
+ console.error(`Error copying CSS: ${(error as Error).message}`);
115
+ }
116
+ }
117
+
118
+ export function gitExec(command: string): void {
119
+ try {
120
+ execSync(command, { stdio: 'inherit' });
121
+ } catch (error: unknown) {
122
+ console.error(`Error executing '${command}':`, (error as Error).message);
123
+ throw error;
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Ensure Git repository is synchronized with remote before pushing
129
+ */
130
+ export async function ensureGitSync(): Promise<void> {
131
+ try {
132
+ console.log('šŸ”„ Checking Git synchronization...');
133
+
134
+ // Fetch latest changes from remote
135
+ execSync('git fetch origin', { stdio: 'pipe' });
136
+
137
+ // Check if branch is behind remote
138
+ const status = execSync('git status --porcelain -b', { encoding: 'utf8' });
139
+
140
+ if (status.includes('behind')) {
141
+ console.log('šŸ“„ Branch behind remote. Pulling changes...');
142
+ execSync('git pull', { stdio: 'inherit' });
143
+ console.log('āœ… Successfully pulled remote changes');
144
+ } else {
145
+ console.log('āœ… Repository is synchronized with remote');
146
+ }
147
+ } catch (error: unknown) {
148
+ console.error(`āŒ Git sync failed: ${(error as Error).message}`);
149
+ throw error;
150
+ }
151
+ }
package/tsconfig.json CHANGED
@@ -1,30 +1,30 @@
1
- {
2
- "compilerOptions": {
3
- "types": ["obsidian-typings"],
4
- "paths": {
5
- "obsidian-typings/implementations": [
6
- "./node_modules/obsidian-typings/dist/cjs/implementations.d.cts",
7
- "./node_modules/obsidian-typings/dist/esm/implementations.mjs"
8
- ]
9
- },
10
- "inlineSourceMap": true,
11
- "inlineSources": true,
12
- "module": "NodeNext",
13
- "moduleResolution": "NodeNext",
14
- "target": "ES2021",
15
- "allowJs": true,
16
- "noImplicitAny": true,
17
- "importHelpers": true,
18
- "isolatedModules": true,
19
- "allowImportingTsExtensions": true,
20
- "noEmit": true,
21
- "allowSyntheticDefaultImports": true,
22
- "verbatimModuleSyntax": true,
23
- "forceConsistentCasingInFileNames": true,
24
- "strictNullChecks": true,
25
- "resolveJsonModule": true,
26
- "lib": ["DOM", "ES2021"]
27
- },
28
- "include": ["./src/**/*.ts", "./scripts/**/*.ts"],
29
- "exclude": ["node_modules", "eslint.config.ts"]
30
- }
1
+ {
2
+ "compilerOptions": {
3
+ "types": ["obsidian-typings"],
4
+ "paths": {
5
+ "obsidian-typings/implementations": [
6
+ "./node_modules/obsidian-typings/dist/cjs/implementations.d.cts",
7
+ "./node_modules/obsidian-typings/dist/esm/implementations.mjs"
8
+ ]
9
+ },
10
+ "inlineSourceMap": true,
11
+ "inlineSources": true,
12
+ "module": "NodeNext",
13
+ "moduleResolution": "NodeNext",
14
+ "target": "ES2021",
15
+ "allowJs": true,
16
+ "noImplicitAny": true,
17
+ "importHelpers": true,
18
+ "isolatedModules": true,
19
+ "allowImportingTsExtensions": true,
20
+ "noEmit": true,
21
+ "allowSyntheticDefaultImports": true,
22
+ "verbatimModuleSyntax": true,
23
+ "forceConsistentCasingInFileNames": true,
24
+ "strictNullChecks": true,
25
+ "resolveJsonModule": true,
26
+ "lib": ["DOM", "ES2021"]
27
+ },
28
+ "include": ["./src/**/*.ts", "./scripts/**/*.ts"],
29
+ "exclude": ["node_modules", "eslint.config.ts"]
30
+ }
package/versions.json CHANGED
@@ -46,5 +46,7 @@
46
46
  "1.4.4": "1.8.9",
47
47
  "1.4.5": "1.8.9",
48
48
  "1.4.6": "1.8.9",
49
- "1.4.7": "1.8.9"
49
+ "1.4.7": "1.8.9",
50
+ "1.4.8": "1.8.9",
51
+ "1.5.0": "1.8.9"
50
52
  }