@powerduck/workspace-yaml 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Powerduck limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,338 @@
1
+ # @powerduck/workspace-yaml
2
+
3
+ > Initialize workspace.yaml and OpenAPI 3.2 YAML files with confidence.
4
+
5
+ Production-grade YAML workspace initializer with a two-layer architecture:
6
+ - **Core layer** (browser-safe): Pure functions that generate YAML content strings. No filesystem access.
7
+ - **File layer** (Node.js / Electron): Wraps the core layer with atomic writes, file locking, and path normalization — all reused from [`@powerduck/conf-patch`](https://github.com/PowerDuckie/conf-patch).
8
+
9
+ ## Why this library?
10
+
11
+ This library **only initializes files** — the "new file" / "manual creation" scenario. It does **not** reimplement reading, patching, or updating YAML files. For those operations, use `@powerduck/conf-patch` directly.
12
+
13
+ - **No redundant IO**: Atomic writes, file locks, and path handling are delegated to `@powerduck/conf-patch`.
14
+ - **No redundant validation**: OpenAPI validation is delegated to `@powerduck/openapi-parser`.
15
+ - **Browser-safe core**: Generate YAML content in any JavaScript environment.
16
+ - **Transaction-safe**: `createWorkspaceApi` writes both files atomically with rollback on failure.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @powerduck/workspace-yaml
22
+ ```
23
+
24
+ Peer dependencies (automatically installed):
25
+ - `@powerduck/conf-patch` — atomic writes, file locking, path normalization
26
+ - `@powerduck/openapi-parser` — OpenAPI validation and upgrade
27
+ - `yaml` — YAML parsing and serialization
28
+
29
+ ## Quick Start
30
+
31
+ ### Node.js / Electron
32
+
33
+ ```typescript
34
+ import { createWorkspaceApi } from "@powerduck/workspace-yaml";
35
+
36
+ const { workspaceFilePath, openApiFilePath } = await createWorkspaceApi({
37
+ workspaceDirectory: "./my-project",
38
+ oasId: "users-api",
39
+ name: "Users API",
40
+ title: "Users API Documentation",
41
+ version: "1.0.0",
42
+ });
43
+
44
+ console.log("Workspace:", workspaceFilePath);
45
+ console.log("OpenAPI:", openApiFilePath);
46
+ ```
47
+
48
+ ### Browser (no filesystem)
49
+
50
+ ```typescript
51
+ import { createWorkspaceYaml, createOpenApiYaml } from "@powerduck/workspace-yaml/core";
52
+
53
+ // Generate YAML content strings — save to IndexedDB, localStorage, or send to an API
54
+ const workspaceContent = createWorkspaceYaml();
55
+ const openApiContent = createOpenApiYaml({ title: "My API" });
56
+ ```
57
+
58
+ ## Two-Layer Architecture
59
+
60
+ ### Core Layer (`@powerduck/workspace-yaml/core`)
61
+
62
+ Browser-safe pure functions. Zero filesystem dependencies.
63
+
64
+ | Function | Description |
65
+ |---|---|
66
+ | `createWorkspaceYaml(options?)` | Generate a workspace.yaml content string |
67
+ | `createOpenApiYaml(options)` | Generate an OpenAPI 3.2 YAML content string |
68
+ | `createWorkspaceWithApi(options)` | Generate both workspace and OpenAPI content together |
69
+ | `parseWorkspaceYaml(content)` | Parse and validate a workspace.yaml content string |
70
+
71
+ ### File Layer (`@powerduck/workspace-yaml`)
72
+
73
+ Node.js / Electron only. Reuses `@powerduck/conf-patch` for IO.
74
+
75
+ | Function | Description |
76
+ |---|---|
77
+ | `initializeWorkspace(options)` | Create a workspace.yaml file on disk |
78
+ | `initializeOpenApi(options)` | Create an OpenAPI 3.2 YAML file on disk |
79
+ | `createWorkspaceApi(options)` | Create both workspace and OpenAPI files atomically |
80
+
81
+ ## API Reference
82
+
83
+ ### Core Layer
84
+
85
+ #### `createWorkspaceYaml(options?)`
86
+
87
+ Generates a workspace.yaml content string.
88
+
89
+ ```typescript
90
+ import { createWorkspaceYaml } from "@powerduck/workspace-yaml/core";
91
+
92
+ const yaml = createWorkspaceYaml({
93
+ activeOasFileId: "api-v1",
94
+ oasFiles: [
95
+ { id: "api-v1", name: "API v1", file: "oasFiles/api-v1.openapi.yaml" },
96
+ ],
97
+ });
98
+ ```
99
+
100
+ **Options:**
101
+ - `activeOasFileId?: string | null` — Initial active API file id (default: `null`)
102
+ - `oasFiles?: OasFileEntry[]` — Initial API file entries (default: `[]`)
103
+
104
+ **Returns:** `string` — YAML content
105
+
106
+ **Throws:** `WorkspaceYamlError` on invalid input (duplicate ids, activeOasFileId not in oasFiles, invalid paths, etc.)
107
+
108
+ ---
109
+
110
+ #### `createOpenApiYaml(options)`
111
+
112
+ Generates an OpenAPI 3.2 YAML content string.
113
+
114
+ ```typescript
115
+ import { createOpenApiYaml } from "@powerduck/workspace-yaml/core";
116
+
117
+ const yaml = createOpenApiYaml({
118
+ title: "My API",
119
+ version: "2.0.0",
120
+ description: "A production-ready API.",
121
+ contact: { name: "API Team", email: "api@example.com" },
122
+ license: { name: "MIT", url: "https://opensource.org/licenses/MIT" },
123
+ servers: [{ url: "https://api.example.com", description: "Production" }],
124
+ });
125
+ ```
126
+
127
+ **Options:**
128
+ - `title: string` — API title (required)
129
+ - `version?: string` — API version (default: `"1.0.0"`)
130
+ - `description?: string` — API description
131
+ - `contact?: { name?, url?, email? }` — Contact information
132
+ - `license?: { name, url? }` — License information
133
+ - `servers?: Array<{ url, description? }>` — Server list
134
+
135
+ **Returns:** `string` — YAML content
136
+
137
+ **Throws:** `WorkspaceYamlError` on empty title or version
138
+
139
+ ---
140
+
141
+ #### `createWorkspaceWithApi(options)`
142
+
143
+ Generates both workspace and OpenAPI content together. The workspace will contain a single API entry and set it as active.
144
+
145
+ ```typescript
146
+ import { createWorkspaceWithApi } from "@powerduck/workspace-yaml/core";
147
+
148
+ const { workspaceYaml, openApiYaml, openApiRelativePath, workspace } =
149
+ createWorkspaceWithApi({
150
+ oasId: "my-api",
151
+ name: "My API",
152
+ title: "My API Documentation",
153
+ version: "1.0.0",
154
+ description: "Detailed description.",
155
+ });
156
+ ```
157
+
158
+ **Options:**
159
+ - `oasId: string` — Unique API identifier (required)
160
+ - `name: string` — Display name (required)
161
+ - `file?: string` — Workspace-relative path (default: `oasFiles/${oasId}.openapi.yaml`)
162
+ - `title?: string` — API title (default: `name`)
163
+ - `version?: string` — API version (default: `"1.0.0"`)
164
+ - `description?: string` — API description
165
+
166
+ **Returns:** `WorkspaceWithApiResult`
167
+ - `workspaceYaml: string`
168
+ - `openApiYaml: string`
169
+ - `openApiRelativePath: string`
170
+ - `workspace: WorkspaceConfig`
171
+
172
+ ---
173
+
174
+ #### `parseWorkspaceYaml(content)`
175
+
176
+ Parses and validates a workspace.yaml content string.
177
+
178
+ ```typescript
179
+ import { parseWorkspaceYaml } from "@powerduck/workspace-yaml/core";
180
+
181
+ const workspace = parseWorkspaceYaml(yamlContent);
182
+ console.log(workspace.oasFiles);
183
+ ```
184
+
185
+ **Returns:** `WorkspaceConfig`
186
+
187
+ **Throws:** `WorkspaceYamlError` on invalid YAML, wrong version, duplicate ids, etc.
188
+
189
+ ---
190
+
191
+ ### File Layer
192
+
193
+ #### `initializeWorkspace(options)`
194
+
195
+ Creates a workspace.yaml file on disk. Uses `@powerduck/conf-patch` for atomic writes and file locking.
196
+
197
+ ```typescript
198
+ import { initializeWorkspace } from "@powerduck/workspace-yaml";
199
+
200
+ const { filePath, workspace } = await initializeWorkspace({
201
+ directory: "./my-project",
202
+ workspaceFileName: "workspace.yaml", // optional
203
+ overwrite: false, // optional, default: false
204
+ activeOasFileId: null, // optional
205
+ oasFiles: [], // optional
206
+ });
207
+ ```
208
+
209
+ ---
210
+
211
+ #### `initializeOpenApi(options)`
212
+
213
+ Creates an OpenAPI 3.2 YAML file on disk.
214
+
215
+ ```typescript
216
+ import { initializeOpenApi } from "@powerduck/workspace-yaml";
217
+
218
+ const { filePath, title, version } = await initializeOpenApi({
219
+ filePath: "./my-project/oasFiles/my-api.openapi.yaml",
220
+ title: "My API",
221
+ version: "1.0.0",
222
+ description: "Optional description.",
223
+ overwrite: false, // optional, default: false
224
+ });
225
+ ```
226
+
227
+ ---
228
+
229
+ #### `createWorkspaceApi(options)`
230
+
231
+ Creates both workspace and OpenAPI files atomically. If the workspace write fails, the OpenAPI file is rolled back.
232
+
233
+ If a workspace already exists, the new API is added to it.
234
+
235
+ ```typescript
236
+ import { createWorkspaceApi } from "@powerduck/workspace-yaml";
237
+
238
+ const { workspaceFilePath, openApiFilePath, workspace } = await createWorkspaceApi({
239
+ workspaceDirectory: "./my-project",
240
+ oasId: "my-api",
241
+ name: "My API",
242
+ file: "custom/path/api.yaml", // optional
243
+ title: "My API Documentation", // optional, defaults to name
244
+ version: "1.0.0", // optional
245
+ description: "Optional.", // optional
246
+ overwriteOpenApi: false, // optional, default: false
247
+ });
248
+ ```
249
+
250
+ ## Error Handling
251
+
252
+ All errors are instances of `WorkspaceYamlError` with a machine-readable `code`:
253
+
254
+ ```typescript
255
+ import { WorkspaceYamlError } from "@powerduck/workspace-yaml";
256
+
257
+ try {
258
+ await createWorkspaceApi({ /* ... */ });
259
+ } catch (error) {
260
+ if (error instanceof WorkspaceYamlError) {
261
+ console.error(`Error [${error.code}]: ${error.message}`);
262
+ console.error(`File: ${error.filePath}`);
263
+ }
264
+ }
265
+ ```
266
+
267
+ **Error codes:**
268
+ - `INVALID_ARGUMENT` — Invalid input parameter
269
+ - `ALREADY_EXISTS` — File already exists (and overwrite is false)
270
+ - `NOT_FOUND` — File not found
271
+ - `IO_ERROR` — Filesystem operation failed
272
+ - `INVALID_WORKSPACE` — Invalid workspace configuration
273
+ - `INVALID_OPENAPI` — Invalid OpenAPI document
274
+ - `ROLLBACK_FAILED` — Transaction rollback failed
275
+
276
+ ## Reading and Updating Files
277
+
278
+ This library only **initializes** files. To read, patch, or update existing files, use `@powerduck/conf-patch`:
279
+
280
+ ```typescript
281
+ import { readConfigFile, setConfigValue, patchConfigFile } from "@powerduck/conf-patch";
282
+
283
+ // Read
284
+ const workspace = await readConfigFile("./my-project/workspace.yaml");
285
+
286
+ // Update a single value
287
+ await setConfigValue("./my-project/workspace.yaml", "activeOasFileId", "new-api");
288
+
289
+ // Batch patch (RFC 6902)
290
+ await patchConfigFile("./my-project/workspace.yaml", [
291
+ { op: "add", path: "/oasFiles/-", value: { id: "new-api", name: "New API", file: "..." } },
292
+ ]);
293
+ ```
294
+
295
+ ## Testing
296
+
297
+ ```bash
298
+ # Run all tests
299
+ npm test
300
+
301
+ # Run with coverage
302
+ npm run test:coverage
303
+
304
+ # Watch mode
305
+ npm run test:watch
306
+ ```
307
+
308
+ ## Demos
309
+
310
+ ```bash
311
+ # Node.js / Electron demo (file layer)
312
+ npm run demo
313
+
314
+ # Browser-safe demo (core layer only)
315
+ npm run demo:browser
316
+ ```
317
+
318
+ ## Building
319
+
320
+ ```bash
321
+ npm run build
322
+ ```
323
+
324
+ Outputs:
325
+ - `dist/index.js` — ESM build (file layer + core layer)
326
+ - `dist/index.cjs` — CJS build
327
+ - `dist/core.js` — ESM build (core layer only, browser-safe)
328
+ - `dist/core.cjs` — CJS build
329
+ - TypeScript declarations (`.d.ts`)
330
+
331
+ ## License
332
+
333
+ MIT © Powerduck limited
334
+
335
+ ## Related Packages
336
+
337
+ - [`@powerduck/conf-patch`](https://github.com/PowerDuckie/conf-patch) — Two-layer configuration editor with atomic writes and locking
338
+ - [`@powerduck/openapi-parser`](https://github.com/PowerDuckie/openapi-parser) — Upgrade and validate OpenAPI documents to 3.2
@@ -0,0 +1 @@
1
+ function e(e,t){return null!=e?e:t()}Object.defineProperty(exports,"__esModule",{value:!0});var t=class extends Error{constructor(e,t,i,s){super(t),this.name="WorkspaceYamlError",this.code=e,this.filePath=i,this.cause=s}},i=require("yaml"),s={indent:2,lineWidth:0,sortKeys:!1};function o(e,i){if("string"!=typeof e)throw new t("INVALID_ARGUMENT",`${i} must be a string.`);const s=e.trim();if(0===s.length)throw new t("INVALID_ARGUMENT",`${i} must not be empty.`);return s}function r(e,i){if(null===e||"object"!=typeof e)throw new t("INVALID_ARGUMENT",`oasFiles[${i}] must be an object.`);if(o(e.id,`oasFiles[${i}].id`),o(e.name,`oasFiles[${i}].name`),o(e.file,`oasFiles[${i}].file`),e.file.includes("\\"))throw new t("INVALID_ARGUMENT",`oasFiles[${i}].file must use POSIX path separators ("/"), not backslashes.`);if(e.file.startsWith("/"))throw new t("INVALID_ARGUMENT",`oasFiles[${i}].file must be a workspace-relative path, not absolute.`);if(!/\.ya?ml$/i.test(e.file))throw new t("INVALID_ARGUMENT",`oasFiles[${i}].file must have a .yaml or .yml extension.`)}function n(e){if(1!==e.version)throw new t("INVALID_WORKSPACE",`workspace version must be 1, got: ${String(e.version)}.`);if(null!==e.activeOasFileId&&"string"!=typeof e.activeOasFileId)throw new t("INVALID_WORKSPACE","activeOasFileId must be a string or null.");if(!Array.isArray(e.oasFiles))throw new t("INVALID_WORKSPACE","oasFiles must be an array.");const i=new Set;for(let s=0;s<e.oasFiles.length;s++){const o=e.oasFiles[s];if(r(o,s),i.has(o.id))throw new t("INVALID_WORKSPACE",`Duplicate oasFiles id: "${o.id}".`);i.add(o.id)}if(null!==e.activeOasFileId&&!i.has(e.activeOasFileId))throw new t("INVALID_WORKSPACE",`activeOasFileId "${e.activeOasFileId}" does not exist in oasFiles.`)}function a(t){const r=function(t){const i={openapi:"3.2.0",info:{title:o(t.title,"title"),version:o(e(t.version,()=>"1.0.0"),"version")},paths:{}};return void 0!==t.description&&(i.info.description=t.description),void 0!==t.contact&&(i.info.contact=t.contact),void 0!==t.license&&(i.info.license=t.license),void 0!==t.servers&&t.servers.length>0&&(i.servers=t.servers),i}(t);return i.stringify.call(void 0,r,s)}exports.WorkspaceYamlError=t,exports.createWorkspaceYaml=function(t={}){const o=function(t){const i={version:1,activeOasFileId:e(t.activeOasFileId,()=>null),oasFiles:t.oasFiles?[...t.oasFiles]:[]};return n(i),i}(t);return i.stringify.call(void 0,o,s)},exports.createOpenApiYaml=a,exports.createWorkspaceWithApi=function(t){const r=o(t.oasId,"oasId"),l=o(t.name,"name"),c=function(t,i){let s=e(i,()=>`oasFiles/${t}.openapi.yaml`);for(s=s.replace(/\\/g,"/");s.startsWith("/");)s=s.slice(1);return/\.ya?ml$/i.test(s)||(s=`${s}.yaml`),s}(r,t.file),p={version:1,activeOasFileId:r,oasFiles:[{id:r,name:l,file:c}]};n(p);const f=a({title:e(t.title,()=>l),version:e(t.version,()=>"1.0.0"),description:t.description});return{workspaceYaml:i.stringify.call(void 0,p,s),openApiYaml:f,openApiRelativePath:c,workspace:p}},exports.parseWorkspaceYaml=function(e){if("string"!=typeof e||0===e.trim().length)throw new t("INVALID_WORKSPACE","Workspace content must be a non-empty string.");let s;try{const o=i.parseDocument.call(void 0,e,{prettyErrors:!0,strict:!0});if(o.errors.length>0)throw new t("INVALID_WORKSPACE",`Invalid YAML: ${o.errors.map(e=>e.message).join("; ")}`);s=o.toJS({mapAsMap:!1})}catch(e){if(e instanceof t)throw e;throw new t("INVALID_WORKSPACE",`Failed to parse workspace YAML: ${e instanceof Error?e.message:String(e)}`)}if(null===s||"object"!=typeof s||Array.isArray(s))throw new t("INVALID_WORKSPACE","Workspace must be a YAML mapping (object).");const o=s;return n(o),o};
@@ -0,0 +1 @@
1
+ var e=class extends Error{code;filePath;cause;constructor(e,t,i,s){super(t),this.name="WorkspaceYamlError",this.code=e,this.filePath=i,this.cause=s}};import{parseDocument as t,stringify as i}from"yaml";var s={indent:2,lineWidth:0,sortKeys:!1};function o(t,i){if("string"!=typeof t)throw new e("INVALID_ARGUMENT",`${i} must be a string.`);const s=t.trim();if(0===s.length)throw new e("INVALID_ARGUMENT",`${i} must not be empty.`);return s}function n(t,i){if(null===t||"object"!=typeof t)throw new e("INVALID_ARGUMENT",`oasFiles[${i}] must be an object.`);if(o(t.id,`oasFiles[${i}].id`),o(t.name,`oasFiles[${i}].name`),o(t.file,`oasFiles[${i}].file`),t.file.includes("\\"))throw new e("INVALID_ARGUMENT",`oasFiles[${i}].file must use POSIX path separators ("/"), not backslashes.`);if(t.file.startsWith("/"))throw new e("INVALID_ARGUMENT",`oasFiles[${i}].file must be a workspace-relative path, not absolute.`);if(!/\.ya?ml$/i.test(t.file))throw new e("INVALID_ARGUMENT",`oasFiles[${i}].file must have a .yaml or .yml extension.`)}function r(t){if(1!==t.version)throw new e("INVALID_WORKSPACE",`workspace version must be 1, got: ${String(t.version)}.`);if(null!==t.activeOasFileId&&"string"!=typeof t.activeOasFileId)throw new e("INVALID_WORKSPACE","activeOasFileId must be a string or null.");if(!Array.isArray(t.oasFiles))throw new e("INVALID_WORKSPACE","oasFiles must be an array.");const i=new Set;for(let s=0;s<t.oasFiles.length;s++){const o=t.oasFiles[s];if(n(o,s),i.has(o.id))throw new e("INVALID_WORKSPACE",`Duplicate oasFiles id: "${o.id}".`);i.add(o.id)}if(null!==t.activeOasFileId&&!i.has(t.activeOasFileId))throw new e("INVALID_WORKSPACE",`activeOasFileId "${t.activeOasFileId}" does not exist in oasFiles.`)}function a(e={}){const t=function(e){const t={version:1,activeOasFileId:e.activeOasFileId??null,oasFiles:e.oasFiles?[...e.oasFiles]:[]};return r(t),t}(e);return i(t,s)}function l(e){const t=function(e){const t={openapi:"3.2.0",info:{title:o(e.title,"title"),version:o(e.version??"1.0.0","version")},paths:{}};return void 0!==e.description&&(t.info.description=e.description),void 0!==e.contact&&(t.info.contact=e.contact),void 0!==e.license&&(t.info.license=e.license),void 0!==e.servers&&e.servers.length>0&&(t.servers=e.servers),t}(e);return i(t,s)}function c(e){const t=o(e.oasId,"oasId"),n=o(e.name,"name"),a=function(e,t){let i=t??`oasFiles/${e}.openapi.yaml`;for(i=i.replace(/\\/g,"/");i.startsWith("/");)i=i.slice(1);return/\.ya?ml$/i.test(i)||(i=`${i}.yaml`),i}(t,e.file),c={version:1,activeOasFileId:t,oasFiles:[{id:t,name:n,file:a}]};r(c);const f=l({title:e.title??n,version:e.version??"1.0.0",description:e.description});return{workspaceYaml:i(c,s),openApiYaml:f,openApiRelativePath:a,workspace:c}}function f(i){if("string"!=typeof i||0===i.trim().length)throw new e("INVALID_WORKSPACE","Workspace content must be a non-empty string.");let s;try{const o=t(i,{prettyErrors:!0,strict:!0});if(o.errors.length>0)throw new e("INVALID_WORKSPACE",`Invalid YAML: ${o.errors.map(e=>e.message).join("; ")}`);s=o.toJS({mapAsMap:!1})}catch(t){if(t instanceof e)throw t;throw new e("INVALID_WORKSPACE",`Failed to parse workspace YAML: ${t instanceof Error?t.message:String(t)}`)}if(null===s||"object"!=typeof s||Array.isArray(s))throw new e("INVALID_WORKSPACE","Workspace must be a YAML mapping (object).");const o=s;return r(o),o}export{e as WorkspaceYamlError,a as createWorkspaceYaml,l as createOpenApiYaml,c as createWorkspaceWithApi,f as parseWorkspaceYaml};
@@ -0,0 +1,291 @@
1
+ /**
2
+ * @powerduck/workspace-yaml
3
+ *
4
+ * Type definitions for workspace and OpenAPI YAML initialization.
5
+ * This module is browser-safe and contains no filesystem access.
6
+ */
7
+ /**
8
+ * A single OpenAPI file entry in a workspace configuration.
9
+ */
10
+ interface OasFileEntry {
11
+ /** Unique identifier for the API within the workspace. */
12
+ id: string;
13
+ /** Human-readable display name of the API. */
14
+ name: string;
15
+ /** Workspace-relative path to the OpenAPI YAML file (POSIX separators). */
16
+ file: string;
17
+ }
18
+ /**
19
+ * The workspace.yaml document structure.
20
+ */
21
+ interface WorkspaceConfig {
22
+ /** Schema version, currently always 1. */
23
+ version: 1;
24
+ /** The currently active API file id, or null if none is active. */
25
+ activeOasFileId: string | null;
26
+ /** All registered OpenAPI files in this workspace. */
27
+ oasFiles: OasFileEntry[];
28
+ }
29
+ /**
30
+ * Options for creating a workspace.yaml content string.
31
+ */
32
+ interface CreateWorkspaceOptions {
33
+ /** Optional initial active API file id. Defaults to null. */
34
+ activeOasFileId?: string | null;
35
+ /** Optional initial list of API file entries. Defaults to empty array. */
36
+ oasFiles?: OasFileEntry[];
37
+ }
38
+ /**
39
+ * Options for creating an OpenAPI 3.2 YAML content string.
40
+ */
41
+ interface CreateOpenApiOptions {
42
+ /** API title. Required, must be non-empty after trimming. */
43
+ title: string;
44
+ /** API version. Defaults to "1.0.0". */
45
+ version?: string;
46
+ /** Optional API description. */
47
+ description?: string;
48
+ /** Optional contact information. */
49
+ contact?: {
50
+ name?: string;
51
+ url?: string;
52
+ email?: string;
53
+ };
54
+ /** Optional license information. */
55
+ license?: {
56
+ name: string;
57
+ url?: string;
58
+ };
59
+ /** Optional servers list. */
60
+ servers?: Array<{
61
+ url: string;
62
+ description?: string;
63
+ }>;
64
+ }
65
+ /**
66
+ * Options for creating both a workspace and an OpenAPI file together.
67
+ */
68
+ interface CreateWorkspaceWithApiOptions {
69
+ /** Unique identifier for the API. Required. */
70
+ oasId: string;
71
+ /** Display name of the API. Required. */
72
+ name: string;
73
+ /** Workspace-relative path for the OpenAPI file. Defaults to `oasFiles/${oasId}.openapi.yaml`. */
74
+ file?: string;
75
+ /** API title. Defaults to the name. */
76
+ title?: string;
77
+ /** API version. Defaults to "1.0.0". */
78
+ version?: string;
79
+ /** Optional API description. */
80
+ description?: string;
81
+ }
82
+ /**
83
+ * Result of creating a workspace with an API.
84
+ */
85
+ interface WorkspaceWithApiResult {
86
+ /** The generated workspace.yaml content. */
87
+ workspaceYaml: string;
88
+ /** The generated OpenAPI YAML content. */
89
+ openApiYaml: string;
90
+ /** The workspace-relative path of the OpenAPI file. */
91
+ openApiRelativePath: string;
92
+ /** The resolved workspace configuration. */
93
+ workspace: WorkspaceConfig;
94
+ }
95
+ /**
96
+ * Options for initializing a workspace file on disk.
97
+ */
98
+ interface InitializeWorkspaceOptions {
99
+ /** Absolute or relative directory path where workspace.yaml will be created. */
100
+ directory: string;
101
+ /** Optional custom workspace file name. Defaults to "workspace.yaml". */
102
+ workspaceFileName?: string;
103
+ /** Whether to overwrite an existing file. Defaults to false. */
104
+ overwrite?: boolean;
105
+ /** Optional initial active API file id. */
106
+ activeOasFileId?: string | null;
107
+ /** Optional initial list of API file entries. */
108
+ oasFiles?: OasFileEntry[];
109
+ }
110
+ /**
111
+ * Options for initializing an OpenAPI file on disk.
112
+ */
113
+ interface InitializeOpenApiOptions {
114
+ /** Absolute or relative path for the OpenAPI YAML file. */
115
+ filePath: string;
116
+ /** API title. Required. */
117
+ title: string;
118
+ /** API version. Defaults to "1.0.0". */
119
+ version?: string;
120
+ /** Optional API description. */
121
+ description?: string;
122
+ /** Whether to overwrite an existing file. Defaults to false. */
123
+ overwrite?: boolean;
124
+ }
125
+ /**
126
+ * Options for creating a workspace with an API file on disk.
127
+ */
128
+ interface CreateWorkspaceApiOptions {
129
+ /** Absolute or relative path to the workspace directory. */
130
+ workspaceDirectory: string;
131
+ /** Unique identifier for the API. Required. */
132
+ oasId: string;
133
+ /** Display name of the API. Required. */
134
+ name: string;
135
+ /** Workspace-relative path for the OpenAPI file. Defaults to `oasFiles/${oasId}.openapi.yaml`. */
136
+ file?: string;
137
+ /** API title. Defaults to the name. */
138
+ title?: string;
139
+ /** API version. Defaults to "1.0.0". */
140
+ version?: string;
141
+ /** Optional API description. */
142
+ description?: string;
143
+ /** Whether to overwrite an existing OpenAPI file. Defaults to false. */
144
+ overwriteOpenApi?: boolean;
145
+ }
146
+ /**
147
+ * Result of initializing a workspace file.
148
+ */
149
+ interface InitializeWorkspaceResult {
150
+ /** Absolute path to the created workspace.yaml file. */
151
+ filePath: string;
152
+ /** The workspace configuration that was written. */
153
+ workspace: WorkspaceConfig;
154
+ }
155
+ /**
156
+ * Result of initializing an OpenAPI file.
157
+ */
158
+ interface InitializeOpenApiResult {
159
+ /** Absolute path to the created OpenAPI YAML file. */
160
+ filePath: string;
161
+ /** The OpenAPI document title. */
162
+ title: string;
163
+ /** The OpenAPI document version. */
164
+ version: string;
165
+ }
166
+ /**
167
+ * Result of creating a workspace with an API file on disk.
168
+ */
169
+ interface CreateWorkspaceApiResult {
170
+ /** Absolute path to the workspace.yaml file. */
171
+ workspaceFilePath: string;
172
+ /** Absolute path to the OpenAPI YAML file. */
173
+ openApiFilePath: string;
174
+ /** The workspace configuration that was written. */
175
+ workspace: WorkspaceConfig;
176
+ }
177
+ /**
178
+ * Error codes for workspace-yaml operations.
179
+ */
180
+ type WorkspaceYamlErrorCode = "INVALID_ARGUMENT" | "ALREADY_EXISTS" | "NOT_FOUND" | "IO_ERROR" | "INVALID_WORKSPACE" | "INVALID_OPENAPI" | "ROLLBACK_FAILED";
181
+ /**
182
+ * Custom error class for workspace-yaml operations.
183
+ */
184
+ declare class WorkspaceYamlError extends Error {
185
+ readonly code: WorkspaceYamlErrorCode;
186
+ readonly filePath?: string;
187
+ readonly cause?: unknown;
188
+ constructor(code: WorkspaceYamlErrorCode, message: string, filePath?: string, cause?: unknown);
189
+ }
190
+
191
+ /**
192
+ * Core layer — browser-safe pure functions for generating YAML content.
193
+ *
194
+ * This module has zero filesystem dependencies and works in browsers,
195
+ * Node.js, Electron, and any JavaScript environment.
196
+ *
197
+ * It generates:
198
+ * - workspace.yaml content
199
+ * - OpenAPI 3.2 YAML content
200
+ * - Both together (workspace + API)
201
+ */
202
+
203
+ /**
204
+ * Creates a workspace.yaml content string.
205
+ *
206
+ * This is a pure function with no filesystem access.
207
+ * Works in browsers, Node.js, and Electron.
208
+ *
209
+ * @param options - Workspace creation options
210
+ * @returns The workspace.yaml content as a YAML string
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * import { createWorkspaceYaml } from "@powerduck/workspace-yaml/core";
215
+ *
216
+ * const yaml = createWorkspaceYaml({
217
+ * activeOasFileId: "api-v1",
218
+ * oasFiles: [
219
+ * { id: "api-v1", name: "API v1", file: "oasFiles/api-v1.openapi.yaml" },
220
+ * ],
221
+ * });
222
+ * // => "version: 1\nactiveOasFileId: api-v1\noasFiles:\n - ..."
223
+ * ```
224
+ */
225
+ declare function createWorkspaceYaml(options?: CreateWorkspaceOptions): string;
226
+ /**
227
+ * Creates an OpenAPI 3.2 YAML content string.
228
+ *
229
+ * This is a pure function with no filesystem access.
230
+ * Works in browsers, Node.js, and Electron.
231
+ *
232
+ * The generated document is a minimal but valid OpenAPI 3.2 spec
233
+ * with empty paths, ready for the user to add endpoints.
234
+ *
235
+ * @param options - OpenAPI creation options
236
+ * @returns The OpenAPI 3.2 YAML content as a string
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * import { createOpenApiYaml } from "@powerduck/workspace-yaml/core";
241
+ *
242
+ * const yaml = createOpenApiYaml({
243
+ * title: "My API",
244
+ * version: "2.0.0",
245
+ * description: "A sample API",
246
+ * });
247
+ * // => "openapi: 3.2.0\ninfo:\n title: My API\n version: 2.0.0\npaths: {}"
248
+ * ```
249
+ */
250
+ declare function createOpenApiYaml(options: CreateOpenApiOptions): string;
251
+ /**
252
+ * Creates both a workspace.yaml and an OpenAPI 3.2 YAML content string.
253
+ *
254
+ * This is a pure function with no filesystem access.
255
+ * Works in browsers, Node.js, and Electron.
256
+ *
257
+ * The workspace will contain a single API entry pointing to the
258
+ * generated OpenAPI file, and that API will be set as active.
259
+ *
260
+ * @param options - Options for creating workspace + API
261
+ * @returns Object containing both YAML strings and metadata
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * import { createWorkspaceWithApi } from "@powerduck/workspace-yaml/core";
266
+ *
267
+ * const { workspaceYaml, openApiYaml, openApiRelativePath } = createWorkspaceWithApi({
268
+ * oasId: "my-api",
269
+ * name: "My API",
270
+ * title: "My API Documentation",
271
+ * version: "1.0.0",
272
+ * });
273
+ *
274
+ * // Save workspaceYaml to workspace.yaml
275
+ * // Save openApiYaml to oasFiles/my-api.openapi.yaml
276
+ * ```
277
+ */
278
+ declare function createWorkspaceWithApi(options: CreateWorkspaceWithApiOptions): WorkspaceWithApiResult;
279
+ /**
280
+ * Validates a workspace.yaml content string.
281
+ *
282
+ * This is a pure function with no filesystem access.
283
+ * Works in browsers, Node.js, and Electron.
284
+ *
285
+ * @param content - The raw YAML content to validate
286
+ * @returns The parsed and validated workspace config
287
+ * @throws WorkspaceYamlError if the content is invalid
288
+ */
289
+ declare function parseWorkspaceYaml(content: string): WorkspaceConfig;
290
+
291
+ export { type CreateWorkspaceApiOptions as C, type InitializeOpenApiOptions as I, type OasFileEntry as O, type WorkspaceConfig as W, type CreateWorkspaceApiResult as a, type InitializeOpenApiResult as b, type InitializeWorkspaceOptions as c, type InitializeWorkspaceResult as d, type CreateOpenApiOptions as e, type CreateWorkspaceOptions as f, type CreateWorkspaceWithApiOptions as g, type WorkspaceWithApiResult as h, WorkspaceYamlError as i, type WorkspaceYamlErrorCode as j, createOpenApiYaml as k, createWorkspaceWithApi as l, createWorkspaceYaml as m, parseWorkspaceYaml as p };
@@ -0,0 +1,291 @@
1
+ /**
2
+ * @powerduck/workspace-yaml
3
+ *
4
+ * Type definitions for workspace and OpenAPI YAML initialization.
5
+ * This module is browser-safe and contains no filesystem access.
6
+ */
7
+ /**
8
+ * A single OpenAPI file entry in a workspace configuration.
9
+ */
10
+ interface OasFileEntry {
11
+ /** Unique identifier for the API within the workspace. */
12
+ id: string;
13
+ /** Human-readable display name of the API. */
14
+ name: string;
15
+ /** Workspace-relative path to the OpenAPI YAML file (POSIX separators). */
16
+ file: string;
17
+ }
18
+ /**
19
+ * The workspace.yaml document structure.
20
+ */
21
+ interface WorkspaceConfig {
22
+ /** Schema version, currently always 1. */
23
+ version: 1;
24
+ /** The currently active API file id, or null if none is active. */
25
+ activeOasFileId: string | null;
26
+ /** All registered OpenAPI files in this workspace. */
27
+ oasFiles: OasFileEntry[];
28
+ }
29
+ /**
30
+ * Options for creating a workspace.yaml content string.
31
+ */
32
+ interface CreateWorkspaceOptions {
33
+ /** Optional initial active API file id. Defaults to null. */
34
+ activeOasFileId?: string | null;
35
+ /** Optional initial list of API file entries. Defaults to empty array. */
36
+ oasFiles?: OasFileEntry[];
37
+ }
38
+ /**
39
+ * Options for creating an OpenAPI 3.2 YAML content string.
40
+ */
41
+ interface CreateOpenApiOptions {
42
+ /** API title. Required, must be non-empty after trimming. */
43
+ title: string;
44
+ /** API version. Defaults to "1.0.0". */
45
+ version?: string;
46
+ /** Optional API description. */
47
+ description?: string;
48
+ /** Optional contact information. */
49
+ contact?: {
50
+ name?: string;
51
+ url?: string;
52
+ email?: string;
53
+ };
54
+ /** Optional license information. */
55
+ license?: {
56
+ name: string;
57
+ url?: string;
58
+ };
59
+ /** Optional servers list. */
60
+ servers?: Array<{
61
+ url: string;
62
+ description?: string;
63
+ }>;
64
+ }
65
+ /**
66
+ * Options for creating both a workspace and an OpenAPI file together.
67
+ */
68
+ interface CreateWorkspaceWithApiOptions {
69
+ /** Unique identifier for the API. Required. */
70
+ oasId: string;
71
+ /** Display name of the API. Required. */
72
+ name: string;
73
+ /** Workspace-relative path for the OpenAPI file. Defaults to `oasFiles/${oasId}.openapi.yaml`. */
74
+ file?: string;
75
+ /** API title. Defaults to the name. */
76
+ title?: string;
77
+ /** API version. Defaults to "1.0.0". */
78
+ version?: string;
79
+ /** Optional API description. */
80
+ description?: string;
81
+ }
82
+ /**
83
+ * Result of creating a workspace with an API.
84
+ */
85
+ interface WorkspaceWithApiResult {
86
+ /** The generated workspace.yaml content. */
87
+ workspaceYaml: string;
88
+ /** The generated OpenAPI YAML content. */
89
+ openApiYaml: string;
90
+ /** The workspace-relative path of the OpenAPI file. */
91
+ openApiRelativePath: string;
92
+ /** The resolved workspace configuration. */
93
+ workspace: WorkspaceConfig;
94
+ }
95
+ /**
96
+ * Options for initializing a workspace file on disk.
97
+ */
98
+ interface InitializeWorkspaceOptions {
99
+ /** Absolute or relative directory path where workspace.yaml will be created. */
100
+ directory: string;
101
+ /** Optional custom workspace file name. Defaults to "workspace.yaml". */
102
+ workspaceFileName?: string;
103
+ /** Whether to overwrite an existing file. Defaults to false. */
104
+ overwrite?: boolean;
105
+ /** Optional initial active API file id. */
106
+ activeOasFileId?: string | null;
107
+ /** Optional initial list of API file entries. */
108
+ oasFiles?: OasFileEntry[];
109
+ }
110
+ /**
111
+ * Options for initializing an OpenAPI file on disk.
112
+ */
113
+ interface InitializeOpenApiOptions {
114
+ /** Absolute or relative path for the OpenAPI YAML file. */
115
+ filePath: string;
116
+ /** API title. Required. */
117
+ title: string;
118
+ /** API version. Defaults to "1.0.0". */
119
+ version?: string;
120
+ /** Optional API description. */
121
+ description?: string;
122
+ /** Whether to overwrite an existing file. Defaults to false. */
123
+ overwrite?: boolean;
124
+ }
125
+ /**
126
+ * Options for creating a workspace with an API file on disk.
127
+ */
128
+ interface CreateWorkspaceApiOptions {
129
+ /** Absolute or relative path to the workspace directory. */
130
+ workspaceDirectory: string;
131
+ /** Unique identifier for the API. Required. */
132
+ oasId: string;
133
+ /** Display name of the API. Required. */
134
+ name: string;
135
+ /** Workspace-relative path for the OpenAPI file. Defaults to `oasFiles/${oasId}.openapi.yaml`. */
136
+ file?: string;
137
+ /** API title. Defaults to the name. */
138
+ title?: string;
139
+ /** API version. Defaults to "1.0.0". */
140
+ version?: string;
141
+ /** Optional API description. */
142
+ description?: string;
143
+ /** Whether to overwrite an existing OpenAPI file. Defaults to false. */
144
+ overwriteOpenApi?: boolean;
145
+ }
146
+ /**
147
+ * Result of initializing a workspace file.
148
+ */
149
+ interface InitializeWorkspaceResult {
150
+ /** Absolute path to the created workspace.yaml file. */
151
+ filePath: string;
152
+ /** The workspace configuration that was written. */
153
+ workspace: WorkspaceConfig;
154
+ }
155
+ /**
156
+ * Result of initializing an OpenAPI file.
157
+ */
158
+ interface InitializeOpenApiResult {
159
+ /** Absolute path to the created OpenAPI YAML file. */
160
+ filePath: string;
161
+ /** The OpenAPI document title. */
162
+ title: string;
163
+ /** The OpenAPI document version. */
164
+ version: string;
165
+ }
166
+ /**
167
+ * Result of creating a workspace with an API file on disk.
168
+ */
169
+ interface CreateWorkspaceApiResult {
170
+ /** Absolute path to the workspace.yaml file. */
171
+ workspaceFilePath: string;
172
+ /** Absolute path to the OpenAPI YAML file. */
173
+ openApiFilePath: string;
174
+ /** The workspace configuration that was written. */
175
+ workspace: WorkspaceConfig;
176
+ }
177
+ /**
178
+ * Error codes for workspace-yaml operations.
179
+ */
180
+ type WorkspaceYamlErrorCode = "INVALID_ARGUMENT" | "ALREADY_EXISTS" | "NOT_FOUND" | "IO_ERROR" | "INVALID_WORKSPACE" | "INVALID_OPENAPI" | "ROLLBACK_FAILED";
181
+ /**
182
+ * Custom error class for workspace-yaml operations.
183
+ */
184
+ declare class WorkspaceYamlError extends Error {
185
+ readonly code: WorkspaceYamlErrorCode;
186
+ readonly filePath?: string;
187
+ readonly cause?: unknown;
188
+ constructor(code: WorkspaceYamlErrorCode, message: string, filePath?: string, cause?: unknown);
189
+ }
190
+
191
+ /**
192
+ * Core layer — browser-safe pure functions for generating YAML content.
193
+ *
194
+ * This module has zero filesystem dependencies and works in browsers,
195
+ * Node.js, Electron, and any JavaScript environment.
196
+ *
197
+ * It generates:
198
+ * - workspace.yaml content
199
+ * - OpenAPI 3.2 YAML content
200
+ * - Both together (workspace + API)
201
+ */
202
+
203
+ /**
204
+ * Creates a workspace.yaml content string.
205
+ *
206
+ * This is a pure function with no filesystem access.
207
+ * Works in browsers, Node.js, and Electron.
208
+ *
209
+ * @param options - Workspace creation options
210
+ * @returns The workspace.yaml content as a YAML string
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * import { createWorkspaceYaml } from "@powerduck/workspace-yaml/core";
215
+ *
216
+ * const yaml = createWorkspaceYaml({
217
+ * activeOasFileId: "api-v1",
218
+ * oasFiles: [
219
+ * { id: "api-v1", name: "API v1", file: "oasFiles/api-v1.openapi.yaml" },
220
+ * ],
221
+ * });
222
+ * // => "version: 1\nactiveOasFileId: api-v1\noasFiles:\n - ..."
223
+ * ```
224
+ */
225
+ declare function createWorkspaceYaml(options?: CreateWorkspaceOptions): string;
226
+ /**
227
+ * Creates an OpenAPI 3.2 YAML content string.
228
+ *
229
+ * This is a pure function with no filesystem access.
230
+ * Works in browsers, Node.js, and Electron.
231
+ *
232
+ * The generated document is a minimal but valid OpenAPI 3.2 spec
233
+ * with empty paths, ready for the user to add endpoints.
234
+ *
235
+ * @param options - OpenAPI creation options
236
+ * @returns The OpenAPI 3.2 YAML content as a string
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * import { createOpenApiYaml } from "@powerduck/workspace-yaml/core";
241
+ *
242
+ * const yaml = createOpenApiYaml({
243
+ * title: "My API",
244
+ * version: "2.0.0",
245
+ * description: "A sample API",
246
+ * });
247
+ * // => "openapi: 3.2.0\ninfo:\n title: My API\n version: 2.0.0\npaths: {}"
248
+ * ```
249
+ */
250
+ declare function createOpenApiYaml(options: CreateOpenApiOptions): string;
251
+ /**
252
+ * Creates both a workspace.yaml and an OpenAPI 3.2 YAML content string.
253
+ *
254
+ * This is a pure function with no filesystem access.
255
+ * Works in browsers, Node.js, and Electron.
256
+ *
257
+ * The workspace will contain a single API entry pointing to the
258
+ * generated OpenAPI file, and that API will be set as active.
259
+ *
260
+ * @param options - Options for creating workspace + API
261
+ * @returns Object containing both YAML strings and metadata
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * import { createWorkspaceWithApi } from "@powerduck/workspace-yaml/core";
266
+ *
267
+ * const { workspaceYaml, openApiYaml, openApiRelativePath } = createWorkspaceWithApi({
268
+ * oasId: "my-api",
269
+ * name: "My API",
270
+ * title: "My API Documentation",
271
+ * version: "1.0.0",
272
+ * });
273
+ *
274
+ * // Save workspaceYaml to workspace.yaml
275
+ * // Save openApiYaml to oasFiles/my-api.openapi.yaml
276
+ * ```
277
+ */
278
+ declare function createWorkspaceWithApi(options: CreateWorkspaceWithApiOptions): WorkspaceWithApiResult;
279
+ /**
280
+ * Validates a workspace.yaml content string.
281
+ *
282
+ * This is a pure function with no filesystem access.
283
+ * Works in browsers, Node.js, and Electron.
284
+ *
285
+ * @param content - The raw YAML content to validate
286
+ * @returns The parsed and validated workspace config
287
+ * @throws WorkspaceYamlError if the content is invalid
288
+ */
289
+ declare function parseWorkspaceYaml(content: string): WorkspaceConfig;
290
+
291
+ export { type CreateWorkspaceApiOptions as C, type InitializeOpenApiOptions as I, type OasFileEntry as O, type WorkspaceConfig as W, type CreateWorkspaceApiResult as a, type InitializeOpenApiResult as b, type InitializeWorkspaceOptions as c, type InitializeWorkspaceResult as d, type CreateOpenApiOptions as e, type CreateWorkspaceOptions as f, type CreateWorkspaceWithApiOptions as g, type WorkspaceWithApiResult as h, WorkspaceYamlError as i, type WorkspaceYamlErrorCode as j, createOpenApiYaml as k, createWorkspaceWithApi as l, createWorkspaceYaml as m, parseWorkspaceYaml as p };
package/dist/core.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./chunk-6LICMPRI.cjs");exports.WorkspaceYamlError=e.WorkspaceYamlError,exports.createOpenApiYaml=e.createOpenApiYaml,exports.createWorkspaceWithApi=e.createWorkspaceWithApi,exports.createWorkspaceYaml=e.createWorkspaceYaml,exports.parseWorkspaceYaml=e.parseWorkspaceYaml;
@@ -0,0 +1 @@
1
+ export { e as CreateOpenApiOptions, f as CreateWorkspaceOptions, g as CreateWorkspaceWithApiOptions, O as OasFileEntry, W as WorkspaceConfig, h as WorkspaceWithApiResult, i as WorkspaceYamlError, j as WorkspaceYamlErrorCode, k as createOpenApiYaml, l as createWorkspaceWithApi, m as createWorkspaceYaml, p as parseWorkspaceYaml } from './core-DfwH7QX7.cjs';
package/dist/core.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { e as CreateOpenApiOptions, f as CreateWorkspaceOptions, g as CreateWorkspaceWithApiOptions, O as OasFileEntry, W as WorkspaceConfig, h as WorkspaceWithApiResult, i as WorkspaceYamlError, j as WorkspaceYamlErrorCode, k as createOpenApiYaml, l as createWorkspaceWithApi, m as createWorkspaceYaml, p as parseWorkspaceYaml } from './core-DfwH7QX7.js';
package/dist/core.js ADDED
@@ -0,0 +1 @@
1
+ import{WorkspaceYamlError as o,createOpenApiYaml as r,createWorkspaceWithApi as m,createWorkspaceYaml as p,parseWorkspaceYaml as t}from"./chunk-QMIGONFP.js";export{o as WorkspaceYamlError,r as createOpenApiYaml,m as createWorkspaceWithApi,p as createWorkspaceYaml,t as parseWorkspaceYaml};
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ function e(e,a){return null!=e?e:a()}Object.defineProperty(exports,"__esModule",{value:!0});var a,r=require("./chunk-6LICMPRI.cjs"),i=require("fs/promises"),t=require("path"),o=(a=t)&&a.__esModule?a:{default:a},l=require("@powerduck/conf-patch");async function c(e){try{await i.mkdir.call(void 0,e,{recursive:!0})}catch(a){throw new(0,r.WorkspaceYamlError)("IO_ERROR",`Failed to create directory: ${e}`,e,a)}}async function s(e){try{return await l.readConfigFile.call(void 0,e),!0}catch(e){return!1}}exports.WorkspaceYamlError=r.WorkspaceYamlError,exports.createOpenApiYaml=r.createOpenApiYaml,exports.createWorkspaceApi=async function(a){if(null===a||"object"!=typeof a)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","createWorkspaceApi requires an options object.");if("string"!=typeof a.workspaceDirectory||0===a.workspaceDirectory.trim().length)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","workspaceDirectory must be a non-empty string.");if("string"!=typeof a.oasId||0===a.oasId.trim().length)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","oasId must be a non-empty string.");if("string"!=typeof a.name||0===a.name.trim().length)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","name must be a non-empty string.");const t=l.normalizeFilePath.call(void 0,a.workspaceDirectory),n=o.default.join(t,"workspace.yaml"),p=e(a.overwriteOpenApi,()=>!1),{openApiYaml:w,openApiRelativePath:d,workspace:m}=r.createWorkspaceWithApi.call(void 0,{oasId:a.oasId,name:a.name,file:a.file,title:a.title,version:a.version,description:a.description}),f=o.default.join(t,d);await c(t),await c(o.default.dirname(f));const k=[n,f].sort();return await l.withFileLock.call(void 0,k[0],async()=>await l.withFileLock.call(void 0,k[1],async()=>{let t,o,c=null;try{const e=await l.readConfigFile.call(void 0,n);c=r.parseWorkspaceYaml.call(void 0,e)}catch(e){c=null}if(null!==c&&c.oasFiles.some(e=>e.id===a.oasId))throw new(0,r.WorkspaceYamlError)("INVALID_WORKSPACE",`An API with id "${a.oasId}" already exists in workspace.yaml.`,n);if(!p&&await s(f))throw new(0,r.WorkspaceYamlError)("ALREADY_EXISTS",`OpenAPI file already exists: ${f}. Set overwriteOpenApi: true to replace it.`,f);try{t=await l.readConfigFile.call(void 0,f)}catch(e){t=void 0}try{await l.writeConfigFile.call(void 0,f,w,{lock:!1})}catch(e){throw new(0,r.WorkspaceYamlError)("IO_ERROR",`Failed to write OpenAPI file: ${f}`,f,e)}o=null!==c?{...c,activeOasFileId:e(c.activeOasFileId,()=>a.oasId),oasFiles:[...c.oasFiles,{id:a.oasId,name:a.name.trim(),file:d}]}:m;const k=r.createWorkspaceYaml.call(void 0,{activeOasFileId:o.activeOasFileId,oasFiles:o.oasFiles});try{await l.writeConfigFile.call(void 0,n,k,{lock:!1})}catch(e){try{void 0!==t?await l.writeConfigFile.call(void 0,f,t,{lock:!1}):await i.rm.call(void 0,f,{force:!0})}catch(a){throw new(0,r.WorkspaceYamlError)("ROLLBACK_FAILED",`Failed to update workspace and failed to roll back OpenAPI file: ${f}`,n,{workspaceWriteError:e,rollbackError:a})}throw e}return{workspaceFilePath:n,openApiFilePath:f,workspace:o}}))},exports.createWorkspaceWithApi=r.createWorkspaceWithApi,exports.createWorkspaceYaml=r.createWorkspaceYaml,exports.initializeOpenApi=async function(a){if(null===a||"object"!=typeof a)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","initializeOpenApi requires an options object.");if("string"!=typeof a.filePath||0===a.filePath.trim().length)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","filePath must be a non-empty string.");const i=l.normalizeFilePath.call(void 0,a.filePath),t=e(a.overwrite,()=>!1);if(!/\.ya?ml$/i.test(i))throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT",`OpenAPI file must have a .yaml or .yml extension: ${i}`,i);const n=r.createOpenApiYaml.call(void 0,{title:a.title,version:a.version,description:a.description}),p=o.default.dirname(i);return await c(p),await l.withFileLock.call(void 0,i,async()=>{if(!t&&await s(i))throw new(0,r.WorkspaceYamlError)("ALREADY_EXISTS",`OpenAPI file already exists: ${i}. Set overwrite: true to replace it.`,i);try{await l.writeConfigFile.call(void 0,i,n,{lock:!1})}catch(e){throw new(0,r.WorkspaceYamlError)("IO_ERROR",`Failed to write OpenAPI file: ${i}`,i,e)}}),{filePath:i,title:a.title.trim(),version:e(a.version,()=>"1.0.0")}},exports.initializeWorkspace=async function(a){if(null===a||"object"!=typeof a)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","initializeWorkspace requires an options object.");if("string"!=typeof a.directory||0===a.directory.trim().length)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","directory must be a non-empty string.");const i=l.normalizeFilePath.call(void 0,a.directory),t=e(a.workspaceFileName,()=>"workspace.yaml");if(t!==o.default.basename(t)||"."===t||".."===t)throw new(0,r.WorkspaceYamlError)("INVALID_ARGUMENT","workspaceFileName must be a file name only, not a path.");const n=o.default.join(i,t),p=e(a.overwrite,()=>!1),w=r.createWorkspaceYaml.call(void 0,{activeOasFileId:a.activeOasFileId,oasFiles:a.oasFiles});await c(i),await l.withFileLock.call(void 0,n,async()=>{if(!p&&await s(n))throw new(0,r.WorkspaceYamlError)("ALREADY_EXISTS",`Workspace file already exists: ${n}. Set overwrite: true to replace it.`,n);try{await l.writeConfigFile.call(void 0,n,w,{lock:!1})}catch(e){throw new(0,r.WorkspaceYamlError)("IO_ERROR",`Failed to write workspace file: ${n}`,n,e)}});const d={version:1,activeOasFileId:e(a.activeOasFileId,()=>null),oasFiles:a.oasFiles?[...a.oasFiles]:[]};return{filePath:n,workspace:d}},exports.parseWorkspaceYaml=r.parseWorkspaceYaml;
@@ -0,0 +1,100 @@
1
+ import { C as CreateWorkspaceApiOptions, a as CreateWorkspaceApiResult, I as InitializeOpenApiOptions, b as InitializeOpenApiResult, c as InitializeWorkspaceOptions, d as InitializeWorkspaceResult } from './core-DfwH7QX7.cjs';
2
+ export { e as CreateOpenApiOptions, f as CreateWorkspaceOptions, g as CreateWorkspaceWithApiOptions, O as OasFileEntry, W as WorkspaceConfig, h as WorkspaceWithApiResult, i as WorkspaceYamlError, j as WorkspaceYamlErrorCode, k as createOpenApiYaml, l as createWorkspaceWithApi, m as createWorkspaceYaml, p as parseWorkspaceYaml } from './core-DfwH7QX7.cjs';
3
+
4
+ /**
5
+ * File layer — Node.js / Electron only.
6
+ *
7
+ * This module wraps the core layer's pure functions with filesystem IO.
8
+ * It reuses @powerduck/conf-patch for atomic writes, file locking,
9
+ * and path normalization — no redundant IO implementations.
10
+ *
11
+ * Do not import this module in browser environments.
12
+ * Use `@powerduck/workspace-yaml/core` instead.
13
+ */
14
+
15
+ /**
16
+ * Initializes a workspace.yaml file on disk.
17
+ *
18
+ * Generates the workspace content using the core layer, then writes it
19
+ * atomically using conf-patch's writeConfigFile (which handles locking
20
+ * and crash-safe temp-file+rename).
21
+ *
22
+ * This function only works in Node.js / Electron environments.
23
+ * For browser usage, use `createWorkspaceYaml` from the core layer.
24
+ *
25
+ * @param options - Workspace initialization options
26
+ * @returns The absolute file path and the workspace config that was written
27
+ * @throws WorkspaceYamlError if the file already exists and overwrite is false
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * import { initializeWorkspace } from "@powerduck/workspace-yaml";
32
+ *
33
+ * const { filePath, workspace } = await initializeWorkspace({
34
+ * directory: "./my-project",
35
+ * overwrite: false,
36
+ * });
37
+ * console.log("Created workspace at:", filePath);
38
+ * ```
39
+ */
40
+ declare function initializeWorkspace(options: InitializeWorkspaceOptions): Promise<InitializeWorkspaceResult>;
41
+ /**
42
+ * Initializes an OpenAPI 3.2 YAML file on disk.
43
+ *
44
+ * Generates the OpenAPI content using the core layer, then writes it
45
+ * atomically using conf-patch's writeConfigFile.
46
+ *
47
+ * This function only works in Node.js / Electron environments.
48
+ * For browser usage, use `createOpenApiYaml` from the core layer.
49
+ *
50
+ * @param options - OpenAPI initialization options
51
+ * @returns The absolute file path, title, and version
52
+ * @throws WorkspaceYamlError if the file already exists and overwrite is false
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import { initializeOpenApi } from "@powerduck/workspace-yaml";
57
+ *
58
+ * const { filePath } = await initializeOpenApi({
59
+ * filePath: "./my-project/oasFiles/my-api.openapi.yaml",
60
+ * title: "My API",
61
+ * version: "1.0.0",
62
+ * });
63
+ * ```
64
+ */
65
+ declare function initializeOpenApi(options: InitializeOpenApiOptions): Promise<InitializeOpenApiResult>;
66
+ /**
67
+ * Creates a workspace with an API file on disk, atomically.
68
+ *
69
+ * This is a transactional operation:
70
+ * 1. Generate both workspace.yaml and OpenAPI YAML content (core layer)
71
+ * 2. Acquire locks on both files
72
+ * 3. Write OpenAPI file first
73
+ * 4. Write workspace file (referencing the OpenAPI file)
74
+ * 5. If workspace write fails, roll back the OpenAPI file
75
+ *
76
+ * Reuses conf-patch's withFileLock for multi-file locking and
77
+ * writeConfigFile for atomic writes.
78
+ *
79
+ * This function only works in Node.js / Electron environments.
80
+ *
81
+ * @param options - Options for creating workspace + API
82
+ * @returns Paths to both files and the workspace config
83
+ * @throws WorkspaceYamlError if either file already exists (unless overwriteOpenApi is true)
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * import { createWorkspaceApi } from "@powerduck/workspace-yaml";
88
+ *
89
+ * const { workspaceFilePath, openApiFilePath } = await createWorkspaceApi({
90
+ * workspaceDirectory: "./my-project",
91
+ * oasId: "my-api",
92
+ * name: "My API",
93
+ * title: "My API Documentation",
94
+ * version: "1.0.0",
95
+ * });
96
+ * ```
97
+ */
98
+ declare function createWorkspaceApi(options: CreateWorkspaceApiOptions): Promise<CreateWorkspaceApiResult>;
99
+
100
+ export { CreateWorkspaceApiOptions, CreateWorkspaceApiResult, InitializeOpenApiOptions, InitializeOpenApiResult, InitializeWorkspaceOptions, InitializeWorkspaceResult, createWorkspaceApi, initializeOpenApi, initializeWorkspace };
@@ -0,0 +1,100 @@
1
+ import { C as CreateWorkspaceApiOptions, a as CreateWorkspaceApiResult, I as InitializeOpenApiOptions, b as InitializeOpenApiResult, c as InitializeWorkspaceOptions, d as InitializeWorkspaceResult } from './core-DfwH7QX7.js';
2
+ export { e as CreateOpenApiOptions, f as CreateWorkspaceOptions, g as CreateWorkspaceWithApiOptions, O as OasFileEntry, W as WorkspaceConfig, h as WorkspaceWithApiResult, i as WorkspaceYamlError, j as WorkspaceYamlErrorCode, k as createOpenApiYaml, l as createWorkspaceWithApi, m as createWorkspaceYaml, p as parseWorkspaceYaml } from './core-DfwH7QX7.js';
3
+
4
+ /**
5
+ * File layer — Node.js / Electron only.
6
+ *
7
+ * This module wraps the core layer's pure functions with filesystem IO.
8
+ * It reuses @powerduck/conf-patch for atomic writes, file locking,
9
+ * and path normalization — no redundant IO implementations.
10
+ *
11
+ * Do not import this module in browser environments.
12
+ * Use `@powerduck/workspace-yaml/core` instead.
13
+ */
14
+
15
+ /**
16
+ * Initializes a workspace.yaml file on disk.
17
+ *
18
+ * Generates the workspace content using the core layer, then writes it
19
+ * atomically using conf-patch's writeConfigFile (which handles locking
20
+ * and crash-safe temp-file+rename).
21
+ *
22
+ * This function only works in Node.js / Electron environments.
23
+ * For browser usage, use `createWorkspaceYaml` from the core layer.
24
+ *
25
+ * @param options - Workspace initialization options
26
+ * @returns The absolute file path and the workspace config that was written
27
+ * @throws WorkspaceYamlError if the file already exists and overwrite is false
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * import { initializeWorkspace } from "@powerduck/workspace-yaml";
32
+ *
33
+ * const { filePath, workspace } = await initializeWorkspace({
34
+ * directory: "./my-project",
35
+ * overwrite: false,
36
+ * });
37
+ * console.log("Created workspace at:", filePath);
38
+ * ```
39
+ */
40
+ declare function initializeWorkspace(options: InitializeWorkspaceOptions): Promise<InitializeWorkspaceResult>;
41
+ /**
42
+ * Initializes an OpenAPI 3.2 YAML file on disk.
43
+ *
44
+ * Generates the OpenAPI content using the core layer, then writes it
45
+ * atomically using conf-patch's writeConfigFile.
46
+ *
47
+ * This function only works in Node.js / Electron environments.
48
+ * For browser usage, use `createOpenApiYaml` from the core layer.
49
+ *
50
+ * @param options - OpenAPI initialization options
51
+ * @returns The absolute file path, title, and version
52
+ * @throws WorkspaceYamlError if the file already exists and overwrite is false
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import { initializeOpenApi } from "@powerduck/workspace-yaml";
57
+ *
58
+ * const { filePath } = await initializeOpenApi({
59
+ * filePath: "./my-project/oasFiles/my-api.openapi.yaml",
60
+ * title: "My API",
61
+ * version: "1.0.0",
62
+ * });
63
+ * ```
64
+ */
65
+ declare function initializeOpenApi(options: InitializeOpenApiOptions): Promise<InitializeOpenApiResult>;
66
+ /**
67
+ * Creates a workspace with an API file on disk, atomically.
68
+ *
69
+ * This is a transactional operation:
70
+ * 1. Generate both workspace.yaml and OpenAPI YAML content (core layer)
71
+ * 2. Acquire locks on both files
72
+ * 3. Write OpenAPI file first
73
+ * 4. Write workspace file (referencing the OpenAPI file)
74
+ * 5. If workspace write fails, roll back the OpenAPI file
75
+ *
76
+ * Reuses conf-patch's withFileLock for multi-file locking and
77
+ * writeConfigFile for atomic writes.
78
+ *
79
+ * This function only works in Node.js / Electron environments.
80
+ *
81
+ * @param options - Options for creating workspace + API
82
+ * @returns Paths to both files and the workspace config
83
+ * @throws WorkspaceYamlError if either file already exists (unless overwriteOpenApi is true)
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * import { createWorkspaceApi } from "@powerduck/workspace-yaml";
88
+ *
89
+ * const { workspaceFilePath, openApiFilePath } = await createWorkspaceApi({
90
+ * workspaceDirectory: "./my-project",
91
+ * oasId: "my-api",
92
+ * name: "My API",
93
+ * title: "My API Documentation",
94
+ * version: "1.0.0",
95
+ * });
96
+ * ```
97
+ */
98
+ declare function createWorkspaceApi(options: CreateWorkspaceApiOptions): Promise<CreateWorkspaceApiResult>;
99
+
100
+ export { CreateWorkspaceApiOptions, CreateWorkspaceApiResult, InitializeOpenApiOptions, InitializeOpenApiResult, InitializeWorkspaceOptions, InitializeWorkspaceResult, createWorkspaceApi, initializeOpenApi, initializeWorkspace };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{WorkspaceYamlError as e,createOpenApiYaml as t,createWorkspaceWithApi as i,createWorkspaceYaml as a,parseWorkspaceYaml as o}from"./chunk-QMIGONFP.js";import{mkdir as r,rm as n}from"fs/promises";import s from"path";import{normalizeFilePath as c,readConfigFile as l,writeConfigFile as w,withFileLock as p}from"@powerduck/conf-patch";async function I(t){try{await r(t,{recursive:!0})}catch(i){throw new e("IO_ERROR",`Failed to create directory: ${t}`,t,i)}}async function f(e){try{return await l(e),!0}catch{return!1}}async function y(t){if(null===t||"object"!=typeof t)throw new e("INVALID_ARGUMENT","initializeWorkspace requires an options object.");if("string"!=typeof t.directory||0===t.directory.trim().length)throw new e("INVALID_ARGUMENT","directory must be a non-empty string.");const i=c(t.directory),o=t.workspaceFileName??"workspace.yaml";if(o!==s.basename(o)||"."===o||".."===o)throw new e("INVALID_ARGUMENT","workspaceFileName must be a file name only, not a path.");const r=s.join(i,o),n=t.overwrite??!1,l=a({activeOasFileId:t.activeOasFileId,oasFiles:t.oasFiles});await I(i),await p(r,async()=>{if(!n&&await f(r))throw new e("ALREADY_EXISTS",`Workspace file already exists: ${r}. Set overwrite: true to replace it.`,r);try{await w(r,l,{lock:!1})}catch(t){throw new e("IO_ERROR",`Failed to write workspace file: ${r}`,r,t)}});const y={version:1,activeOasFileId:t.activeOasFileId??null,oasFiles:t.oasFiles?[...t.oasFiles]:[]};return{filePath:r,workspace:y}}async function h(i){if(null===i||"object"!=typeof i)throw new e("INVALID_ARGUMENT","initializeOpenApi requires an options object.");if("string"!=typeof i.filePath||0===i.filePath.trim().length)throw new e("INVALID_ARGUMENT","filePath must be a non-empty string.");const a=c(i.filePath),o=i.overwrite??!1;if(!/\.ya?ml$/i.test(a))throw new e("INVALID_ARGUMENT",`OpenAPI file must have a .yaml or .yml extension: ${a}`,a);const r=t({title:i.title,version:i.version,description:i.description}),n=s.dirname(a);return await I(n),await p(a,async()=>{if(!o&&await f(a))throw new e("ALREADY_EXISTS",`OpenAPI file already exists: ${a}. Set overwrite: true to replace it.`,a);try{await w(a,r,{lock:!1})}catch(t){throw new e("IO_ERROR",`Failed to write OpenAPI file: ${a}`,a,t)}}),{filePath:a,title:i.title.trim(),version:i.version??"1.0.0"}}async function m(t){if(null===t||"object"!=typeof t)throw new e("INVALID_ARGUMENT","createWorkspaceApi requires an options object.");if("string"!=typeof t.workspaceDirectory||0===t.workspaceDirectory.trim().length)throw new e("INVALID_ARGUMENT","workspaceDirectory must be a non-empty string.");if("string"!=typeof t.oasId||0===t.oasId.trim().length)throw new e("INVALID_ARGUMENT","oasId must be a non-empty string.");if("string"!=typeof t.name||0===t.name.trim().length)throw new e("INVALID_ARGUMENT","name must be a non-empty string.");const r=c(t.workspaceDirectory),y=s.join(r,"workspace.yaml"),h=t.overwriteOpenApi??!1,{openApiYaml:m,openApiRelativePath:d,workspace:A}=i({oasId:t.oasId,name:t.name,file:t.file,title:t.title,version:t.version,description:t.description}),u=s.join(r,d);await I(r),await I(s.dirname(u));const F=[y,u].sort();return await p(F[0],async()=>await p(F[1],async()=>{let i,r,s=null;try{const e=await l(y);s=o(e)}catch{s=null}if(null!==s&&s.oasFiles.some(e=>e.id===t.oasId))throw new e("INVALID_WORKSPACE",`An API with id "${t.oasId}" already exists in workspace.yaml.`,y);if(!h&&await f(u))throw new e("ALREADY_EXISTS",`OpenAPI file already exists: ${u}. Set overwriteOpenApi: true to replace it.`,u);try{i=await l(u)}catch{i=void 0}try{await w(u,m,{lock:!1})}catch(t){throw new e("IO_ERROR",`Failed to write OpenAPI file: ${u}`,u,t)}r=null!==s?{...s,activeOasFileId:s.activeOasFileId??t.oasId,oasFiles:[...s.oasFiles,{id:t.oasId,name:t.name.trim(),file:d}]}:A;const c=a({activeOasFileId:r.activeOasFileId,oasFiles:r.oasFiles});try{await w(y,c,{lock:!1})}catch(t){try{void 0!==i?await w(u,i,{lock:!1}):await n(u,{force:!0})}catch(i){throw new e("ROLLBACK_FAILED",`Failed to update workspace and failed to roll back OpenAPI file: ${u}`,y,{workspaceWriteError:t,rollbackError:i})}throw t}return{workspaceFilePath:y,openApiFilePath:u,workspace:r}}))}export{e as WorkspaceYamlError,t as createOpenApiYaml,m as createWorkspaceApi,i as createWorkspaceWithApi,a as createWorkspaceYaml,h as initializeOpenApi,y as initializeWorkspace,o as parseWorkspaceYaml};
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@powerduck/workspace-yaml",
3
+ "version": "0.2.0",
4
+ "description": "Initialize workspace.yaml and OpenAPI 3.2 YAML files with confidence. Two-layer architecture: browser-safe core for generating YAML content, plus Node.js/Electron file layer that reuses @powerduck/conf-patch for atomic writes and locking.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./core": {
16
+ "types": "./dist/core.d.ts",
17
+ "import": "./dist/core.js",
18
+ "require": "./dist/core.cjs"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "sideEffects": false,
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "scripts": {
32
+ "clean": "rm -rf dist coverage",
33
+ "build": "tsc --noEmit && tsup",
34
+ "typecheck": "tsc --noEmit",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest",
37
+ "test:coverage": "vitest run --coverage",
38
+ "demo": "tsx demo/demo.ts",
39
+ "demo:browser": "tsx demo/browser-demo.ts",
40
+ "prepublishOnly": "npm run build"
41
+ },
42
+ "keywords": [
43
+ "yaml",
44
+ "workspace",
45
+ "openapi",
46
+ "openapi-3.2",
47
+ "initializer",
48
+ "scaffold",
49
+ "electron",
50
+ "browser-safe",
51
+ "atomic-write",
52
+ "file-lock",
53
+ "conf-patch",
54
+ "powerduck"
55
+ ],
56
+ "license": "MIT",
57
+ "author": "Powerduck limited",
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "https://github.com/PowerDuckie/workspace-yaml.git"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/PowerDuckie/workspace-yaml/issues"
64
+ },
65
+ "homepage": "https://github.com/PowerDuckie/workspace-yaml#readme",
66
+ "dependencies": {
67
+ "@powerduck/conf-patch": "^0.3.2",
68
+ "@powerduck/openapi-parser": "^0.3.3",
69
+ "yaml": "^2.9.0"
70
+ },
71
+ "devDependencies": {
72
+ "@types/node": "^20.19.43",
73
+ "terser": "^5.51.2",
74
+ "tsup": "^8.1.0",
75
+ "tsx": "^4.23.12",
76
+ "typescript": "^5.5.0",
77
+ "vitest": "^2.0.0"
78
+ }
79
+ }