@arc-e-tect/api-only-publisher 0.7.0 → 0.8.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/src/pipeline.js CHANGED
@@ -9,7 +9,7 @@ const YAML = require("yaml");
9
9
 
10
10
  const { substituteFile } = require("./placeholders");
11
11
  const { stampFile } = require("./version");
12
- const { generateAsyncApi, isAggregate } = require("./aggregate");
12
+ const { generateAsyncApi, generateOpenApi, openapiPushDown, isAggregate } = require("./aggregate");
13
13
  const { stampFiles, componentPaths, strayPaths, fragmentStamps, unresolvedStamps, FragmentPathError, KEY } = require("./fragment-paths");
14
14
 
15
15
  class BuildError extends Error {}
@@ -85,7 +85,7 @@ function substituteTree(config, kind, log) {
85
85
  }
86
86
 
87
87
  function bundle(config, target, kind, outFile, log, { stagingRoot } = {}) {
88
- const source = config.bundlePath(target, kind, stagingRoot);
88
+ const source = config.bundleRootPath(target, kind, stagingRoot);
89
89
  if (!fs.existsSync(source)) {
90
90
  throw new BuildError(`target '${target}': bundle root not found at ${source}`);
91
91
  }
@@ -130,7 +130,7 @@ function bundleWithFragmentPaths(config, target, kind, outFile, log) {
130
130
  return YAML.parse(fs.readFileSync(file, "utf8"));
131
131
  };
132
132
 
133
- log(`-- Bundling ${path.basename(config.bundlePath(target, kind))} with ${KEY}`);
133
+ log(`-- Bundling ${path.basename(config.bundleRootPath(target, kind))} with ${KEY}`);
134
134
  const discovered = componentPaths(pass("discover", null));
135
135
  const fragments = new Set([...discovered.values()].filter(Boolean));
136
136
  const document = pass("stamp", fragments);
@@ -169,7 +169,7 @@ function bundleInlinedWithFragmentPaths(config, target, kind, outFile, log) {
169
169
  const root = path.join(scratch, "stamp");
170
170
  fs.cpSync(config.stagingRoot(kind), root, { recursive: true });
171
171
 
172
- const bundleRoot = path.relative(root, config.bundlePath(target, kind, root)).split(path.sep).join("/");
172
+ const bundleRoot = path.relative(root, config.bundleRootPath(target, kind, root)).split(path.sep).join("/");
173
173
  try {
174
174
  stampFiles(root, { except: new Set([bundleRoot]) });
175
175
  } catch (error) {
@@ -177,7 +177,7 @@ function bundleInlinedWithFragmentPaths(config, target, kind, outFile, log) {
177
177
  throw error;
178
178
  }
179
179
 
180
- log(`-- Bundling ${path.basename(config.bundlePath(target, kind))} with ${KEY}`);
180
+ log(`-- Bundling ${path.basename(config.bundleRootPath(target, kind))} with ${KEY}`);
181
181
  const file = path.join(scratch, "stamp.yaml");
182
182
  bundle(config, target, kind, file, () => {}, { stagingRoot: root });
183
183
  const document = YAML.parse(fs.readFileSync(file, "utf8"));
@@ -240,8 +240,11 @@ function prepare(config, { kinds = ["openapi", "asyncapi"], log = () => {} } = {
240
240
  stage(config, kind, log);
241
241
  substituteTree(config, kind, log);
242
242
  for (const target of targets) {
243
- if (isAggregate(config, target, kind) && kind === "asyncapi") {
243
+ if (!isAggregate(config, target, kind)) continue;
244
+ if (kind === "asyncapi") {
244
245
  generateAsyncApi(config, target, { log });
246
+ } else {
247
+ generateOpenApi(config, target, { log });
245
248
  }
246
249
  }
247
250
  }
@@ -269,14 +272,13 @@ function build(config, { targets, versionOf = () => null, kinds = ["openapi", "a
269
272
  log(`\n=== ${target} (${kind}) ===`);
270
273
  // An aggregate has no hand-written bundle root; it is synthesised from
271
274
  // its members into the staged tree, so it can never fall behind them.
275
+ let openapiOwners = null;
272
276
  if (isAggregate(config, target, kind)) {
273
- if (kind !== "asyncapi") {
274
- throw new BuildError(
275
- `target '${target}': aggregate is only supported for asyncapi; ` +
276
- `an OpenAPI portfolio is a hand-written table of contents of $refs`
277
- );
277
+ if (kind === "asyncapi") {
278
+ generateAsyncApi(config, target, { log });
279
+ } else {
280
+ openapiOwners = generateOpenApi(config, target, { log }).owners;
278
281
  }
279
- generateAsyncApi(config, target, { log });
280
282
  }
281
283
  const outFile = path.join(config.distDir(target), config.outputName(kind));
282
284
  if (config.fragmentPaths(kind)) {
@@ -284,6 +286,18 @@ function build(config, { targets, versionOf = () => null, kinds = ["openapi", "a
284
286
  } else {
285
287
  bundle(config, target, kind, outFile, log);
286
288
  }
289
+ if (openapiOwners) {
290
+ // Pass 2: only once bundling has resolved every $ref does an
291
+ // operation's id, or whether it already sets its own security,
292
+ // become visible at all.
293
+ const { text, reconciled } = openapiPushDown(fs.readFileSync(outFile, "utf8"), openapiOwners, {
294
+ operationIdStrategy: config.portfolioOperationIdStrategy(),
295
+ });
296
+ fs.writeFileSync(outFile, text);
297
+ for (const r of reconciled) {
298
+ log(`-- Reconciled tag '${r.key}': two members describe it differently; kept the first's`);
299
+ }
300
+ }
287
301
  const version = versionOf(target);
288
302
  if (version) {
289
303
  log(`-- Stamping version '${version}'`);
package/src/split.js CHANGED
@@ -111,7 +111,7 @@ function split(config, { by = "kind", outDir, log = () => {} } = {}) {
111
111
  // Union of every member's closure.
112
112
  const files = new Set();
113
113
  for (const { target, kind } of members) {
114
- const entry = config.bundlePath(target, kind);
114
+ const entry = config.bundleRootPath(target, kind);
115
115
  if (!fs.existsSync(entry)) {
116
116
  throw new SplitError(
117
117
  `target '${target}': ${kind} bundle root not found at ${entry}; build first so the tree is staged`