@proseql/cli 0.2.4

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +333 -0
  3. package/dist/commands/collections.d.ts +53 -0
  4. package/dist/commands/collections.d.ts.map +1 -0
  5. package/dist/commands/collections.js +145 -0
  6. package/dist/commands/collections.js.map +1 -0
  7. package/dist/commands/convert.d.ts +72 -0
  8. package/dist/commands/convert.d.ts.map +1 -0
  9. package/dist/commands/convert.js +340 -0
  10. package/dist/commands/convert.js.map +1 -0
  11. package/dist/commands/create.d.ts +48 -0
  12. package/dist/commands/create.d.ts.map +1 -0
  13. package/dist/commands/create.js +141 -0
  14. package/dist/commands/create.js.map +1 -0
  15. package/dist/commands/delete.d.ts +51 -0
  16. package/dist/commands/delete.d.ts.map +1 -0
  17. package/dist/commands/delete.js +122 -0
  18. package/dist/commands/delete.js.map +1 -0
  19. package/dist/commands/describe.d.ts +74 -0
  20. package/dist/commands/describe.d.ts.map +1 -0
  21. package/dist/commands/describe.js +206 -0
  22. package/dist/commands/describe.js.map +1 -0
  23. package/dist/commands/init.d.ts +37 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +340 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/migrate.d.ts +65 -0
  28. package/dist/commands/migrate.d.ts.map +1 -0
  29. package/dist/commands/migrate.js +483 -0
  30. package/dist/commands/migrate.js.map +1 -0
  31. package/dist/commands/query.d.ts +56 -0
  32. package/dist/commands/query.d.ts.map +1 -0
  33. package/dist/commands/query.js +159 -0
  34. package/dist/commands/query.js.map +1 -0
  35. package/dist/commands/stats.d.ts +55 -0
  36. package/dist/commands/stats.d.ts.map +1 -0
  37. package/dist/commands/stats.js +188 -0
  38. package/dist/commands/stats.js.map +1 -0
  39. package/dist/commands/update.d.ts +50 -0
  40. package/dist/commands/update.d.ts.map +1 -0
  41. package/dist/commands/update.js +121 -0
  42. package/dist/commands/update.js.map +1 -0
  43. package/dist/config/discovery.d.ts +37 -0
  44. package/dist/config/discovery.d.ts.map +1 -0
  45. package/dist/config/discovery.js +171 -0
  46. package/dist/config/discovery.js.map +1 -0
  47. package/dist/config/loader.d.ts +49 -0
  48. package/dist/config/loader.d.ts.map +1 -0
  49. package/dist/config/loader.js +195 -0
  50. package/dist/config/loader.js.map +1 -0
  51. package/dist/index.d.ts +8 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +7 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/main.d.ts +66 -0
  56. package/dist/main.d.ts.map +1 -0
  57. package/dist/main.js +621 -0
  58. package/dist/main.js.map +1 -0
  59. package/dist/output/csv.d.ts +14 -0
  60. package/dist/output/csv.d.ts.map +1 -0
  61. package/dist/output/csv.js +54 -0
  62. package/dist/output/csv.js.map +1 -0
  63. package/dist/output/formatter.d.ts +18 -0
  64. package/dist/output/formatter.d.ts.map +1 -0
  65. package/dist/output/formatter.js +29 -0
  66. package/dist/output/formatter.js.map +1 -0
  67. package/dist/output/json.d.ts +13 -0
  68. package/dist/output/json.d.ts.map +1 -0
  69. package/dist/output/json.js +15 -0
  70. package/dist/output/json.js.map +1 -0
  71. package/dist/output/table.d.ts +18 -0
  72. package/dist/output/table.d.ts.map +1 -0
  73. package/dist/output/table.js +115 -0
  74. package/dist/output/table.js.map +1 -0
  75. package/dist/output/yaml.d.ts +13 -0
  76. package/dist/output/yaml.d.ts.map +1 -0
  77. package/dist/output/yaml.js +16 -0
  78. package/dist/output/yaml.js.map +1 -0
  79. package/dist/parsers/filter-parser.d.ts +65 -0
  80. package/dist/parsers/filter-parser.d.ts.map +1 -0
  81. package/dist/parsers/filter-parser.js +198 -0
  82. package/dist/parsers/filter-parser.js.map +1 -0
  83. package/dist/parsers/set-parser.d.ts +55 -0
  84. package/dist/parsers/set-parser.d.ts.map +1 -0
  85. package/dist/parsers/set-parser.js +198 -0
  86. package/dist/parsers/set-parser.js.map +1 -0
  87. package/dist/prompt.d.ts +58 -0
  88. package/dist/prompt.d.ts.map +1 -0
  89. package/dist/prompt.js +121 -0
  90. package/dist/prompt.js.map +1 -0
  91. package/package.json +59 -0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Set Parser - Parses CLI --set assignment strings into partial update objects
3
+ *
4
+ * Parses key=value pairs separated by commas.
5
+ * Auto-detects value types: numbers, booleans, strings
6
+ *
7
+ * Examples:
8
+ * "year=2025" -> { year: 2025 }
9
+ * "title=New Title" -> { title: "New Title" }
10
+ * "active=true" -> { active: true }
11
+ * "year=2025,title=New Title" -> { year: 2025, title: "New Title" }
12
+ * "url=https://example.com/a=b" -> { url: "https://example.com/a=b" }
13
+ */
14
+ import { Effect } from "effect";
15
+ declare const SetParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
16
+ readonly _tag: "SetParseError";
17
+ } & Readonly<A>;
18
+ /**
19
+ * Error thrown when a set expression cannot be parsed
20
+ */
21
+ export declare class SetParseError extends SetParseError_base<{
22
+ readonly expression: string;
23
+ readonly reason: string;
24
+ }> {
25
+ get message(): string;
26
+ }
27
+ /**
28
+ * Update object type - record of field to value
29
+ */
30
+ export type UpdateObject = Record<string, string | number | boolean>;
31
+ /**
32
+ * Parse a single assignment string into an update object
33
+ *
34
+ * @param assignment - Assignment string (e.g., "year=2025")
35
+ * @returns Effect containing the update object or a SetParseError
36
+ */
37
+ export declare function parseSet(assignment: string): Effect.Effect<UpdateObject, SetParseError>;
38
+ /**
39
+ * Parse a comma-separated assignment string into an update object
40
+ * Multiple assignments are merged into a single object
41
+ *
42
+ * @param input - Comma-separated assignment string (e.g., "year=2025,title=New Title")
43
+ * @returns Effect containing the combined update object or a SetParseError
44
+ */
45
+ export declare function parseSets(input: string): Effect.Effect<UpdateObject, SetParseError>;
46
+ /**
47
+ * Parse multiple comma-separated assignment strings into an update object
48
+ * Useful when --set is passed multiple times
49
+ *
50
+ * @param inputs - Array of comma-separated assignment strings
51
+ * @returns Effect containing the combined update object or a SetParseError
52
+ */
53
+ export declare function parseMultipleSets(inputs: readonly string[]): Effect.Effect<UpdateObject, SetParseError>;
54
+ export {};
55
+ //# sourceMappingURL=set-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/set-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAQ,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;AAEtC;;GAEG;AACH,qBAAa,aAAc,SAAQ,mBAAkC;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,CAAC;IACD,IAAI,OAAO,IAAI,MAAM,CAEpB;CACD;AA4ID;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,QAAQ,CACvB,UAAU,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAO5C;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAqC5C;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAkB5C"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Set Parser - Parses CLI --set assignment strings into partial update objects
3
+ *
4
+ * Parses key=value pairs separated by commas.
5
+ * Auto-detects value types: numbers, booleans, strings
6
+ *
7
+ * Examples:
8
+ * "year=2025" -> { year: 2025 }
9
+ * "title=New Title" -> { title: "New Title" }
10
+ * "active=true" -> { active: true }
11
+ * "year=2025,title=New Title" -> { year: 2025, title: "New Title" }
12
+ * "url=https://example.com/a=b" -> { url: "https://example.com/a=b" }
13
+ */
14
+ import { Data, Effect } from "effect";
15
+ /**
16
+ * Error thrown when a set expression cannot be parsed
17
+ */
18
+ export class SetParseError extends Data.TaggedError("SetParseError") {
19
+ get message() {
20
+ return `Failed to parse set expression "${this.expression}": ${this.reason}`;
21
+ }
22
+ }
23
+ /**
24
+ * Parse a string value into the appropriate type (number, boolean, or string)
25
+ */
26
+ function parseValue(value) {
27
+ const trimmed = value.trim();
28
+ // Check for boolean
29
+ if (trimmed.toLowerCase() === "true") {
30
+ return true;
31
+ }
32
+ if (trimmed.toLowerCase() === "false") {
33
+ return false;
34
+ }
35
+ // Check for number
36
+ const num = Number(trimmed);
37
+ if (!Number.isNaN(num) && trimmed !== "") {
38
+ return num;
39
+ }
40
+ // Default to string - strip quotes if present
41
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
42
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
43
+ return trimmed.slice(1, -1);
44
+ }
45
+ return trimmed;
46
+ }
47
+ /**
48
+ * Parse a single key=value assignment
49
+ * Handles values containing '=' by only splitting on the first '='
50
+ */
51
+ function parseAssignment(assignment) {
52
+ return Effect.gen(function* () {
53
+ const trimmed = assignment.trim();
54
+ if (!trimmed) {
55
+ return yield* Effect.fail(new SetParseError({
56
+ expression: assignment,
57
+ reason: "Empty assignment",
58
+ }));
59
+ }
60
+ // Find the first '=' to split key and value
61
+ const eqIndex = trimmed.indexOf("=");
62
+ if (eqIndex === -1) {
63
+ return yield* Effect.fail(new SetParseError({
64
+ expression: assignment,
65
+ reason: "Missing '=' operator. Expected format: key=value",
66
+ }));
67
+ }
68
+ if (eqIndex === 0) {
69
+ return yield* Effect.fail(new SetParseError({
70
+ expression: assignment,
71
+ reason: "Missing key before '='",
72
+ }));
73
+ }
74
+ const key = trimmed.slice(0, eqIndex).trim();
75
+ const valueStr = trimmed.slice(eqIndex + 1);
76
+ // Validate key is a valid identifier
77
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
78
+ return yield* Effect.fail(new SetParseError({
79
+ expression: assignment,
80
+ reason: `Invalid key "${key}". Keys must be valid identifiers (start with letter or underscore, contain only letters, numbers, and underscores)`,
81
+ }));
82
+ }
83
+ return {
84
+ key,
85
+ value: parseValue(valueStr),
86
+ };
87
+ });
88
+ }
89
+ /**
90
+ * Split assignment string by commas, respecting quoted values
91
+ * This handles cases where values might contain commas inside quotes
92
+ */
93
+ function splitAssignments(input) {
94
+ const assignments = [];
95
+ let current = "";
96
+ let inQuotes = false;
97
+ let quoteChar = "";
98
+ for (let i = 0; i < input.length; i++) {
99
+ const char = input[i];
100
+ if (!inQuotes && (char === '"' || char === "'")) {
101
+ inQuotes = true;
102
+ quoteChar = char;
103
+ current += char;
104
+ }
105
+ else if (inQuotes && char === quoteChar) {
106
+ inQuotes = false;
107
+ quoteChar = "";
108
+ current += char;
109
+ }
110
+ else if (!inQuotes && char === ",") {
111
+ if (current.trim()) {
112
+ assignments.push(current.trim());
113
+ }
114
+ current = "";
115
+ }
116
+ else {
117
+ current += char;
118
+ }
119
+ }
120
+ // Don't forget the last assignment
121
+ if (current.trim()) {
122
+ assignments.push(current.trim());
123
+ }
124
+ return assignments;
125
+ }
126
+ /**
127
+ * Parse a single assignment string into an update object
128
+ *
129
+ * @param assignment - Assignment string (e.g., "year=2025")
130
+ * @returns Effect containing the update object or a SetParseError
131
+ */
132
+ export function parseSet(assignment) {
133
+ return Effect.gen(function* () {
134
+ const parsed = yield* parseAssignment(assignment);
135
+ return {
136
+ [parsed.key]: parsed.value,
137
+ };
138
+ });
139
+ }
140
+ /**
141
+ * Parse a comma-separated assignment string into an update object
142
+ * Multiple assignments are merged into a single object
143
+ *
144
+ * @param input - Comma-separated assignment string (e.g., "year=2025,title=New Title")
145
+ * @returns Effect containing the combined update object or a SetParseError
146
+ */
147
+ export function parseSets(input) {
148
+ return Effect.gen(function* () {
149
+ const trimmed = input.trim();
150
+ if (!trimmed) {
151
+ return yield* Effect.fail(new SetParseError({
152
+ expression: input,
153
+ reason: "Empty input",
154
+ }));
155
+ }
156
+ const assignments = splitAssignments(trimmed);
157
+ if (assignments.length === 0) {
158
+ return yield* Effect.fail(new SetParseError({
159
+ expression: input,
160
+ reason: "No valid assignments found",
161
+ }));
162
+ }
163
+ const parsedAssignments = yield* Effect.all(assignments.map(parseSet));
164
+ // Merge all assignments into a single object
165
+ // Later assignments override earlier ones for the same key
166
+ const combined = {};
167
+ for (const assignment of parsedAssignments) {
168
+ for (const [key, value] of Object.entries(assignment)) {
169
+ combined[key] = value;
170
+ }
171
+ }
172
+ return combined;
173
+ });
174
+ }
175
+ /**
176
+ * Parse multiple comma-separated assignment strings into an update object
177
+ * Useful when --set is passed multiple times
178
+ *
179
+ * @param inputs - Array of comma-separated assignment strings
180
+ * @returns Effect containing the combined update object or a SetParseError
181
+ */
182
+ export function parseMultipleSets(inputs) {
183
+ return Effect.gen(function* () {
184
+ if (inputs.length === 0) {
185
+ return {};
186
+ }
187
+ const parsedInputs = yield* Effect.all(inputs.map(parseSets));
188
+ // Merge all into a single object
189
+ const combined = {};
190
+ for (const input of parsedInputs) {
191
+ for (const [key, value] of Object.entries(input)) {
192
+ combined[key] = value;
193
+ }
194
+ }
195
+ return combined;
196
+ });
197
+ }
198
+ //# sourceMappingURL=set-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-parser.js","sourceRoot":"","sources":["../../src/parsers/set-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * ProseQL CLI - Confirmation Prompt
3
+ *
4
+ * Provides a y/n confirmation prompt for destructive operations.
5
+ * Skipped when --force is passed or stdin is not a TTY (non-interactive mode).
6
+ */
7
+ /**
8
+ * Options for the confirmation prompt.
9
+ */
10
+ export interface ConfirmOptions {
11
+ /** The message to display to the user */
12
+ readonly message: string;
13
+ /** Whether to skip the prompt (e.g., --force flag was passed) */
14
+ readonly force?: boolean;
15
+ /** Default answer if the user just presses Enter (defaults to false) */
16
+ readonly defaultAnswer?: boolean;
17
+ }
18
+ /**
19
+ * Result of the confirmation prompt.
20
+ */
21
+ export interface ConfirmResult {
22
+ /** Whether the user confirmed the action */
23
+ readonly confirmed: boolean;
24
+ /** Whether the prompt was skipped (force flag or non-TTY) */
25
+ readonly skipped: boolean;
26
+ /** Reason why the prompt was skipped, if applicable */
27
+ readonly skipReason?: "force" | "non-tty";
28
+ }
29
+ /**
30
+ * Prompt the user for confirmation with a y/n question.
31
+ *
32
+ * The prompt is skipped in these cases:
33
+ * - `force` option is true (returns confirmed: true)
34
+ * - stdin is not a TTY (returns confirmed: true, matching common CLI conventions)
35
+ *
36
+ * @param options - Confirmation prompt options
37
+ * @returns Promise resolving to the confirmation result
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const result = await confirm({
42
+ * message: "Delete entity 'abc123'?",
43
+ * force: flags.force,
44
+ * })
45
+ *
46
+ * if (!result.confirmed) {
47
+ * console.log("Aborted.")
48
+ * return
49
+ * }
50
+ * ```
51
+ */
52
+ export declare function confirm(options: ConfirmOptions): Promise<ConfirmResult>;
53
+ /**
54
+ * Synchronous version of isTTY check.
55
+ * Exported for testing purposes.
56
+ */
57
+ export declare function isInteractive(): boolean;
58
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,wEAAwE;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1C;AAuDD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAwC7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
package/dist/prompt.js ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * ProseQL CLI - Confirmation Prompt
3
+ *
4
+ * Provides a y/n confirmation prompt for destructive operations.
5
+ * Skipped when --force is passed or stdin is not a TTY (non-interactive mode).
6
+ */
7
+ import * as readline from "node:readline";
8
+ /**
9
+ * Check if stdin is a TTY (interactive terminal).
10
+ */
11
+ function isTTY() {
12
+ return process.stdin.isTTY === true;
13
+ }
14
+ /**
15
+ * Read a single line from stdin.
16
+ * Returns a promise that resolves to the trimmed input.
17
+ */
18
+ function readLine(prompt) {
19
+ return new Promise((resolve) => {
20
+ const rl = readline.createInterface({
21
+ input: process.stdin,
22
+ output: process.stdout,
23
+ });
24
+ rl.question(prompt, (answer) => {
25
+ rl.close();
26
+ resolve(answer.trim().toLowerCase());
27
+ });
28
+ });
29
+ }
30
+ /**
31
+ * Parse a y/n answer string into a boolean.
32
+ * Accepts: y, yes, n, no (case-insensitive)
33
+ * Empty string returns the default answer.
34
+ * Invalid input returns null.
35
+ */
36
+ function parseAnswer(answer, defaultAnswer) {
37
+ if (answer === "") {
38
+ return defaultAnswer;
39
+ }
40
+ if (answer === "y" || answer === "yes") {
41
+ return true;
42
+ }
43
+ if (answer === "n" || answer === "no") {
44
+ return false;
45
+ }
46
+ return null;
47
+ }
48
+ /**
49
+ * Format the prompt string with y/n indicator.
50
+ * Shows the default option in uppercase.
51
+ */
52
+ function formatPrompt(message, defaultAnswer) {
53
+ const yesNo = defaultAnswer ? "[Y/n]" : "[y/N]";
54
+ return `${message} ${yesNo} `;
55
+ }
56
+ /**
57
+ * Prompt the user for confirmation with a y/n question.
58
+ *
59
+ * The prompt is skipped in these cases:
60
+ * - `force` option is true (returns confirmed: true)
61
+ * - stdin is not a TTY (returns confirmed: true, matching common CLI conventions)
62
+ *
63
+ * @param options - Confirmation prompt options
64
+ * @returns Promise resolving to the confirmation result
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const result = await confirm({
69
+ * message: "Delete entity 'abc123'?",
70
+ * force: flags.force,
71
+ * })
72
+ *
73
+ * if (!result.confirmed) {
74
+ * console.log("Aborted.")
75
+ * return
76
+ * }
77
+ * ```
78
+ */
79
+ export async function confirm(options) {
80
+ const { message, force = false, defaultAnswer = false } = options;
81
+ // Skip if --force flag is passed
82
+ if (force) {
83
+ return {
84
+ confirmed: true,
85
+ skipped: true,
86
+ skipReason: "force",
87
+ };
88
+ }
89
+ // Skip if stdin is not a TTY (non-interactive mode like CI or piped input)
90
+ // In non-interactive mode, proceed as if confirmed (matching common CLI conventions)
91
+ if (!isTTY()) {
92
+ return {
93
+ confirmed: true,
94
+ skipped: true,
95
+ skipReason: "non-tty",
96
+ };
97
+ }
98
+ // Interactive prompt
99
+ const prompt = formatPrompt(message, defaultAnswer);
100
+ // Keep prompting until we get a valid answer
101
+ while (true) {
102
+ const answer = await readLine(prompt);
103
+ const parsed = parseAnswer(answer, defaultAnswer);
104
+ if (parsed !== null) {
105
+ return {
106
+ confirmed: parsed,
107
+ skipped: false,
108
+ };
109
+ }
110
+ // Invalid input - show hint and ask again
111
+ console.log("Please answer 'y' or 'n'.");
112
+ }
113
+ }
114
+ /**
115
+ * Synchronous version of isTTY check.
116
+ * Exported for testing purposes.
117
+ */
118
+ export function isInteractive() {
119
+ return isTTY();
120
+ }
121
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AA0B1C;;GAEG;AACH,SAAS,KAAK;IACb,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,MAAc;IAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YACnC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACtB,CAAC,CAAC;QAEH,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,MAAc,EAAE,aAAsB;IAC1D,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,aAAa,CAAC;IACtB,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,OAAe,EAAE,aAAsB;IAC5D,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,OAAO,GAAG,OAAO,IAAI,KAAK,GAAG,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACpD,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAElE,iCAAiC;IACjC,IAAI,KAAK,EAAE,CAAC;QACX,OAAO;YACN,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,OAAO;SACnB,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,qFAAqF;IACrF,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACd,OAAO;YACN,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,SAAS;SACrB,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAEpD,6CAA6C;IAC7C,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAElD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO;gBACN,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,KAAK;aACd,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC1C,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC5B,OAAO,KAAK,EAAE,CAAC;AAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@proseql/cli",
3
+ "version": "0.2.4",
4
+ "description": "Command-line interface for ProseQL databases. Query, create, update, and manage plain text database files from the terminal.",
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "bunx tsc --build",
8
+ "clean": "rm -rf dist *.tsbuildinfo",
9
+ "prepublishOnly": "bun run build && bun test"
10
+ },
11
+ "bin": {
12
+ "proseql": "./dist/main.js"
13
+ },
14
+ "main": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "LICENSE",
25
+ "README.md"
26
+ ],
27
+ "license": "MIT",
28
+ "author": "Simon W. Jackson",
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/simonwjackson/proseql.git",
35
+ "directory": "packages/cli"
36
+ },
37
+ "keywords": [
38
+ "database",
39
+ "typescript",
40
+ "effect",
41
+ "cli",
42
+ "command-line",
43
+ "plain-text",
44
+ "yaml",
45
+ "json",
46
+ "toml"
47
+ ],
48
+ "engines": {
49
+ "node": ">=18"
50
+ },
51
+ "sideEffects": false,
52
+ "dependencies": {
53
+ "@proseql/core": "workspace:*",
54
+ "@proseql/node": "workspace:*"
55
+ },
56
+ "peerDependencies": {
57
+ "effect": "^3.15.2"
58
+ }
59
+ }