@tolgamorf/env2op-cli 0.2.2 → 0.2.3
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.
- package/LICENSE +1 -1
- package/README.md +32 -6
- package/dist/cli.js +478 -473
- package/dist/index.d.ts +3 -0
- package/dist/index.js +130 -131
- package/dist/op2env-cli.js +472 -469
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -212,11 +212,14 @@ declare const errors: {
|
|
|
212
212
|
envFileEmpty: (path: string) => Env2OpError;
|
|
213
213
|
opCliNotInstalled: () => Env2OpError;
|
|
214
214
|
opNotSignedIn: () => Env2OpError;
|
|
215
|
+
opSigninFailed: () => Env2OpError;
|
|
215
216
|
vaultNotFound: (vault: string) => Env2OpError;
|
|
216
217
|
vaultCreateFailed: (message: string) => Env2OpError;
|
|
217
218
|
itemExists: (title: string, vault: string) => Env2OpError;
|
|
218
219
|
itemCreateFailed: (message: string) => Env2OpError;
|
|
219
220
|
itemEditFailed: (message: string) => Env2OpError;
|
|
220
221
|
parseError: (line: number, message: string) => Env2OpError;
|
|
222
|
+
templateNotFound: (path: string) => Env2OpError;
|
|
223
|
+
injectFailed: (message: string) => Env2OpError;
|
|
221
224
|
};
|
|
222
225
|
export { writeTemplate, vaultExists, validateParseResult, signIn, parseEnvFile, itemExists2 as itemExists, generateUsageInstructions, generateTemplateContent, errors, editSecureNote, createVault, createSecureNote, checkSignedIn, checkOpCli, TemplateOptions, ParseResult, ErrorCodes, EnvVariable, EnvLine, Env2OpError, CreateItemResult, CreateItemOptions, ConvertOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,89 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
3
|
+
|
|
4
|
+
// package.json
|
|
5
|
+
var require_package = __commonJS((exports, module) => {
|
|
6
|
+
module.exports = {
|
|
7
|
+
name: "@tolgamorf/env2op-cli",
|
|
8
|
+
version: "0.2.3",
|
|
9
|
+
description: "Convert .env files to 1Password Secure Notes and generate templates for op inject/run",
|
|
10
|
+
type: "module",
|
|
11
|
+
main: "dist/index.js",
|
|
12
|
+
module: "dist/index.js",
|
|
13
|
+
types: "dist/index.d.ts",
|
|
14
|
+
exports: {
|
|
15
|
+
".": {
|
|
16
|
+
import: "./dist/index.js",
|
|
17
|
+
types: "./dist/index.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
bin: {
|
|
21
|
+
env2op: "dist/cli.js",
|
|
22
|
+
op2env: "dist/op2env-cli.js"
|
|
23
|
+
},
|
|
24
|
+
files: [
|
|
25
|
+
"dist",
|
|
26
|
+
"LICENSE",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
scripts: {
|
|
30
|
+
dev: "bun run src/cli.ts",
|
|
31
|
+
build: "bunup",
|
|
32
|
+
test: "bun test",
|
|
33
|
+
"test:watch": "bun test --watch",
|
|
34
|
+
"test:coverage": "bun test --coverage",
|
|
35
|
+
typecheck: "tsc --noEmit",
|
|
36
|
+
lint: "bunx biome check .",
|
|
37
|
+
"lint:fix": "bunx biome check . --write",
|
|
38
|
+
format: "bunx biome format --write .",
|
|
39
|
+
"format:check": "bunx biome format .",
|
|
40
|
+
prepublishOnly: "bun run build",
|
|
41
|
+
release: "bun run scripts/release.ts"
|
|
42
|
+
},
|
|
43
|
+
keywords: [
|
|
44
|
+
"env",
|
|
45
|
+
"1password",
|
|
46
|
+
"op",
|
|
47
|
+
"cli",
|
|
48
|
+
"secrets",
|
|
49
|
+
"environment-variables",
|
|
50
|
+
"dotenv",
|
|
51
|
+
"secure-notes",
|
|
52
|
+
"bun",
|
|
53
|
+
"op-inject",
|
|
54
|
+
"op-run",
|
|
55
|
+
"template"
|
|
56
|
+
],
|
|
57
|
+
author: {
|
|
58
|
+
name: "Tolga O.",
|
|
59
|
+
url: "https://github.com/tolgamorf"
|
|
60
|
+
},
|
|
61
|
+
license: "MIT",
|
|
62
|
+
repository: {
|
|
63
|
+
type: "git",
|
|
64
|
+
url: "git+https://github.com/tolgamorf/env2op-cli.git"
|
|
65
|
+
},
|
|
66
|
+
bugs: {
|
|
67
|
+
url: "https://github.com/tolgamorf/env2op-cli/issues"
|
|
68
|
+
},
|
|
69
|
+
homepage: "https://github.com/tolgamorf/env2op-cli#readme",
|
|
70
|
+
engines: {
|
|
71
|
+
node: ">=18.0.0"
|
|
72
|
+
},
|
|
73
|
+
dependencies: {
|
|
74
|
+
"@clack/prompts": "^0.11.0",
|
|
75
|
+
picocolors: "^1.1.1"
|
|
76
|
+
},
|
|
77
|
+
devDependencies: {
|
|
78
|
+
"@biomejs/biome": "^2.3.10",
|
|
79
|
+
"@tsconfig/bun": "^1.0.10",
|
|
80
|
+
"@types/bun": "^1.3.5",
|
|
81
|
+
bunup: "^0.16.17",
|
|
82
|
+
typescript: "^5.9.3"
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
|
|
1
87
|
// src/core/env-parser.ts
|
|
2
88
|
import { readFile } from "node:fs/promises";
|
|
3
89
|
|
|
@@ -32,16 +118,21 @@ var errors = {
|
|
|
32
118
|
envFileEmpty: (path) => new Env2OpError(`No valid environment variables found in ${path}`, ErrorCodes.ENV_FILE_EMPTY, "Ensure the file contains KEY=value pairs"),
|
|
33
119
|
opCliNotInstalled: () => new Env2OpError("1Password CLI (op) is not installed", ErrorCodes.OP_CLI_NOT_INSTALLED, "Install it from https://1password.com/downloads/command-line/"),
|
|
34
120
|
opNotSignedIn: () => new Env2OpError("Not signed in to 1Password CLI", ErrorCodes.OP_NOT_SIGNED_IN, 'Run "op signin" to authenticate'),
|
|
121
|
+
opSigninFailed: () => new Env2OpError("Failed to sign in to 1Password CLI", ErrorCodes.OP_SIGNIN_FAILED, 'Try running "op signin" manually'),
|
|
35
122
|
vaultNotFound: (vault) => new Env2OpError(`Vault not found: ${vault}`, ErrorCodes.VAULT_NOT_FOUND, 'Run "op vault list" to see available vaults'),
|
|
36
123
|
vaultCreateFailed: (message) => new Env2OpError(`Failed to create vault: ${message}`, ErrorCodes.VAULT_CREATE_FAILED),
|
|
37
124
|
itemExists: (title, vault) => new Env2OpError(`Item "${title}" already exists in vault "${vault}"`, ErrorCodes.ITEM_EXISTS, "Use default behavior (overwrites) or choose a different item name"),
|
|
38
125
|
itemCreateFailed: (message) => new Env2OpError(`Failed to create 1Password item: ${message}`, ErrorCodes.ITEM_CREATE_FAILED),
|
|
39
126
|
itemEditFailed: (message) => new Env2OpError(`Failed to edit 1Password item: ${message}`, ErrorCodes.ITEM_EDIT_FAILED),
|
|
40
|
-
parseError: (line, message) => new Env2OpError(`Parse error at line ${line}: ${message}`, ErrorCodes.PARSE_ERROR)
|
|
127
|
+
parseError: (line, message) => new Env2OpError(`Parse error at line ${line}: ${message}`, ErrorCodes.PARSE_ERROR),
|
|
128
|
+
templateNotFound: (path) => new Env2OpError(`Template file not found: ${path}`, ErrorCodes.TEMPLATE_NOT_FOUND, "Ensure the file exists and the path is correct"),
|
|
129
|
+
injectFailed: (message) => new Env2OpError("Failed to pull secrets from 1Password", ErrorCodes.INJECT_FAILED, message)
|
|
41
130
|
};
|
|
42
131
|
|
|
132
|
+
// src/core/constants.ts
|
|
133
|
+
var HEADER_SEPARATOR = `# ${"=".repeat(75)}`;
|
|
134
|
+
|
|
43
135
|
// src/core/env-parser.ts
|
|
44
|
-
var HEADER_SEPARATOR = "# ===========================================================================";
|
|
45
136
|
function stripHeaders(content) {
|
|
46
137
|
const lines = content.split(`
|
|
47
138
|
`);
|
|
@@ -151,16 +242,8 @@ function quoteArg(arg) {
|
|
|
151
242
|
}
|
|
152
243
|
return arg;
|
|
153
244
|
}
|
|
154
|
-
|
|
155
|
-
const { verbose = false } = options;
|
|
156
|
-
const fullCommand = `${command} ${args.map(quoteArg).join(" ")}`;
|
|
157
|
-
if (verbose) {
|
|
158
|
-
console.log(pc.dim(`$ ${fullCommand}`));
|
|
159
|
-
}
|
|
245
|
+
function collectOutput(proc, verbose) {
|
|
160
246
|
return new Promise((resolve) => {
|
|
161
|
-
const proc = spawn(command, args, {
|
|
162
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
163
|
-
});
|
|
164
247
|
const stdoutChunks = [];
|
|
165
248
|
const stderrChunks = [];
|
|
166
249
|
proc.stdout?.on("data", (data) => {
|
|
@@ -194,48 +277,29 @@ async function exec(command, args = [], options = {}) {
|
|
|
194
277
|
});
|
|
195
278
|
});
|
|
196
279
|
}
|
|
280
|
+
async function exec(command, args = [], options = {}) {
|
|
281
|
+
const { verbose = false } = options;
|
|
282
|
+
const fullCommand = `${command} ${args.map(quoteArg).join(" ")}`;
|
|
283
|
+
if (verbose) {
|
|
284
|
+
console.log(pc.dim(`$ ${fullCommand}`));
|
|
285
|
+
}
|
|
286
|
+
const proc = spawn(command, args, {
|
|
287
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
288
|
+
});
|
|
289
|
+
return collectOutput(proc, verbose);
|
|
290
|
+
}
|
|
197
291
|
async function execWithStdin(command, args = [], options) {
|
|
198
292
|
const { stdin: stdinContent, verbose = false } = options;
|
|
199
293
|
if (verbose) {
|
|
200
294
|
const fullCommand = `${command} ${args.map(quoteArg).join(" ")}`;
|
|
201
295
|
console.log(pc.dim(`$ echo '...' | ${fullCommand}`));
|
|
202
296
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
206
|
-
});
|
|
207
|
-
const stdoutChunks = [];
|
|
208
|
-
const stderrChunks = [];
|
|
209
|
-
proc.stdin?.write(stdinContent);
|
|
210
|
-
proc.stdin?.end();
|
|
211
|
-
proc.stdout?.on("data", (data) => {
|
|
212
|
-
const text = Buffer.isBuffer(data) ? data.toString() : String(data);
|
|
213
|
-
stdoutChunks.push(text);
|
|
214
|
-
if (verbose)
|
|
215
|
-
process.stdout.write(text);
|
|
216
|
-
});
|
|
217
|
-
proc.stderr?.on("data", (data) => {
|
|
218
|
-
const text = Buffer.isBuffer(data) ? data.toString() : String(data);
|
|
219
|
-
stderrChunks.push(text);
|
|
220
|
-
if (verbose)
|
|
221
|
-
process.stderr.write(text);
|
|
222
|
-
});
|
|
223
|
-
proc.on("close", (code) => {
|
|
224
|
-
resolve({
|
|
225
|
-
stdout: stdoutChunks.join(""),
|
|
226
|
-
stderr: stderrChunks.join(""),
|
|
227
|
-
exitCode: code ?? 1
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
proc.on("error", (err) => {
|
|
231
|
-
stderrChunks.push(err.message);
|
|
232
|
-
resolve({
|
|
233
|
-
stdout: stdoutChunks.join(""),
|
|
234
|
-
stderr: stderrChunks.join(""),
|
|
235
|
-
exitCode: 1
|
|
236
|
-
});
|
|
237
|
-
});
|
|
297
|
+
const proc = spawn(command, args, {
|
|
298
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
238
299
|
});
|
|
300
|
+
proc.stdin?.write(stdinContent);
|
|
301
|
+
proc.stdin?.end();
|
|
302
|
+
return collectOutput(proc, verbose);
|
|
239
303
|
}
|
|
240
304
|
|
|
241
305
|
// src/core/onepassword.ts
|
|
@@ -357,90 +421,25 @@ async function editSecureNote(options) {
|
|
|
357
421
|
}
|
|
358
422
|
}
|
|
359
423
|
// src/core/template-generator.ts
|
|
360
|
-
import { writeFileSync } from "node:fs";
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
},
|
|
376
|
-
bin: {
|
|
377
|
-
env2op: "dist/cli.js",
|
|
378
|
-
op2env: "dist/op2env-cli.js"
|
|
379
|
-
},
|
|
380
|
-
files: [
|
|
381
|
-
"dist",
|
|
382
|
-
"LICENSE",
|
|
383
|
-
"README.md"
|
|
384
|
-
],
|
|
385
|
-
scripts: {
|
|
386
|
-
dev: "bun run src/cli.ts",
|
|
387
|
-
build: "bunup",
|
|
388
|
-
test: "bun test",
|
|
389
|
-
"test:watch": "bun test --watch",
|
|
390
|
-
"test:coverage": "bun test --coverage",
|
|
391
|
-
typecheck: "tsc --noEmit",
|
|
392
|
-
lint: "bunx biome check .",
|
|
393
|
-
"lint:fix": "bunx biome check . --write",
|
|
394
|
-
format: "bunx biome format --write .",
|
|
395
|
-
"format:check": "bunx biome format .",
|
|
396
|
-
prepublishOnly: "bun run build",
|
|
397
|
-
release: "bun run scripts/release.ts"
|
|
398
|
-
},
|
|
399
|
-
keywords: [
|
|
400
|
-
"env",
|
|
401
|
-
"1password",
|
|
402
|
-
"op",
|
|
403
|
-
"cli",
|
|
404
|
-
"secrets",
|
|
405
|
-
"environment-variables",
|
|
406
|
-
"dotenv",
|
|
407
|
-
"secure-notes",
|
|
408
|
-
"bun",
|
|
409
|
-
"op-inject",
|
|
410
|
-
"op-run",
|
|
411
|
-
"template"
|
|
412
|
-
],
|
|
413
|
-
author: {
|
|
414
|
-
name: "Tolga O.",
|
|
415
|
-
url: "https://github.com/tolgamorf"
|
|
416
|
-
},
|
|
417
|
-
license: "MIT",
|
|
418
|
-
repository: {
|
|
419
|
-
type: "git",
|
|
420
|
-
url: "git+https://github.com/tolgamorf/env2op-cli.git"
|
|
421
|
-
},
|
|
422
|
-
bugs: {
|
|
423
|
-
url: "https://github.com/tolgamorf/env2op-cli/issues"
|
|
424
|
-
},
|
|
425
|
-
homepage: "https://github.com/tolgamorf/env2op-cli#readme",
|
|
426
|
-
engines: {
|
|
427
|
-
node: ">=18.0.0"
|
|
428
|
-
},
|
|
429
|
-
dependencies: {
|
|
430
|
-
"@clack/prompts": "^0.11.0",
|
|
431
|
-
picocolors: "^1.1.1"
|
|
432
|
-
},
|
|
433
|
-
devDependencies: {
|
|
434
|
-
"@biomejs/biome": "^2.3.10",
|
|
435
|
-
"@tsconfig/bun": "^1.0.10",
|
|
436
|
-
"@types/bun": "^1.3.5",
|
|
437
|
-
bunup: "^0.16.17",
|
|
438
|
-
typescript: "^5.9.3"
|
|
424
|
+
import { writeFileSync as writeFileSync2 } from "node:fs";
|
|
425
|
+
|
|
426
|
+
// src/lib/update.ts
|
|
427
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
428
|
+
import { homedir } from "node:os";
|
|
429
|
+
import { join } from "node:path";
|
|
430
|
+
var CACHE_DIR = join(homedir(), ".env2op");
|
|
431
|
+
var CACHE_FILE = join(CACHE_DIR, "update-check.json");
|
|
432
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
433
|
+
function getCliVersion() {
|
|
434
|
+
try {
|
|
435
|
+
const pkg = require_package();
|
|
436
|
+
return pkg.version ?? "0.0.0";
|
|
437
|
+
} catch {
|
|
438
|
+
return "0.0.0";
|
|
439
439
|
}
|
|
440
|
-
}
|
|
440
|
+
}
|
|
441
441
|
|
|
442
442
|
// src/core/template-generator.ts
|
|
443
|
-
var SEPARATOR = "# ===========================================================================";
|
|
444
443
|
function deriveEnvFileName(templateFileName) {
|
|
445
444
|
if (templateFileName.endsWith(".tpl")) {
|
|
446
445
|
return templateFileName.slice(0, -4);
|
|
@@ -453,7 +452,7 @@ function formatTimestamp() {
|
|
|
453
452
|
function generateTemplateHeader(templateFileName) {
|
|
454
453
|
const envFileName = deriveEnvFileName(templateFileName);
|
|
455
454
|
return [
|
|
456
|
-
|
|
455
|
+
HEADER_SEPARATOR,
|
|
457
456
|
`# ${templateFileName} — 1Password Secret References`,
|
|
458
457
|
"#",
|
|
459
458
|
"# This template contains references to secrets stored in 1Password.",
|
|
@@ -466,9 +465,9 @@ function generateTemplateHeader(templateFileName) {
|
|
|
466
465
|
`# op run --env-file ${templateFileName} -- npm start`,
|
|
467
466
|
"#",
|
|
468
467
|
`# Pushed: ${formatTimestamp()}`,
|
|
469
|
-
`# Generated by env2op v${
|
|
468
|
+
`# Generated by env2op v${getCliVersion()}`,
|
|
470
469
|
"# https://github.com/tolgamorf/env2op-cli",
|
|
471
|
-
|
|
470
|
+
HEADER_SEPARATOR,
|
|
472
471
|
""
|
|
473
472
|
];
|
|
474
473
|
}
|
|
@@ -495,7 +494,7 @@ function generateTemplateContent(options, templateFileName) {
|
|
|
495
494
|
`;
|
|
496
495
|
}
|
|
497
496
|
function writeTemplate(content, outputPath) {
|
|
498
|
-
|
|
497
|
+
writeFileSync2(outputPath, content, "utf-8");
|
|
499
498
|
}
|
|
500
499
|
function generateUsageInstructions(templatePath) {
|
|
501
500
|
return ["Usage:", ` op2env ${templatePath}`, ` op run --env-file ${templatePath} -- npm start`].join(`
|