@knpkv/atlassian-common 1.9.0 → 1.9.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @knpkv/atlassian-common
2
2
 
3
+ ## 1.9.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#579](https://github.com/knpkv/npm/pull/579) [`61c930e`](https://github.com/knpkv/npm/commit/61c930e88f4a9d735522d6c7b052b72d13450a6f) Thanks [@konopkov](https://github.com/konopkov)! - Tests typecheck as part of `check`. `externalizeAdfMetadata` returns the sidecar type `hydrateAdfMetadata` takes.
8
+
3
9
  ## 1.9.0
4
10
 
5
11
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knpkv/atlassian-common",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Shared utilities for Atlassian tools (AST, serializers, auth, config)",
5
5
  "license": "MIT",
6
6
  "author": "knpkv",
@@ -103,6 +103,6 @@
103
103
  "test:watch": "vitest",
104
104
  "lint": "eslint src",
105
105
  "lint:fix": "eslint src --fix",
106
- "check": "tsc --noEmit"
106
+ "check": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit"
107
107
  }
108
108
  }
@@ -45,9 +45,11 @@ const PackageManifest = Schema.Struct({
45
45
 
46
46
  // Public generated subpaths or generated export targets declare the contract;
47
47
  // package names and consumer dependencies do not.
48
+ const isJsonArray = Schema.is(Schema.Array(Schema.Json))
49
+
48
50
  const exposesGeneratedContract = (exports: Schema.Json): boolean => {
49
51
  if (Predicate.isString(exports)) return /(?:^|\/)generated(?:\/|$)/u.test(exports)
50
- if (Array.isArray(exports)) return exports.some(exposesGeneratedContract)
52
+ if (isJsonArray(exports)) return exports.some(exposesGeneratedContract)
51
53
  if (!isRecord(exports)) return false
52
54
  return Object.entries(exports).some(([name, target]) =>
53
55
  /^\.\/generated(?:\/|$)/u.test(name) || exposesGeneratedContract(target)
@@ -178,7 +180,7 @@ const inspectApiUpdateWorkflows = Effect.fn("ApiUpdateWorkflows.inspectApiUpdate
178
180
  }
179
181
  const workflowRoot = path.join(root, ".github/workflows")
180
182
  const diagnostics: Array<string> = []
181
- for (const name of (yield* fileSystem.readDirectory(workflowRoot)).toSorted()) {
183
+ for (const name of [...(yield* fileSystem.readDirectory(workflowRoot))].sort()) {
182
184
  if (!/-api-update\.ya?ml$/u.test(name)) continue
183
185
  const source = yield* fileSystem.readFileString(path.join(workflowRoot, name))
184
186
  for (const diagnostic of patchGuidanceDiagnostics(source, generatedClientNames)) {
@@ -2,10 +2,11 @@ import { describe, expect, it } from "@effect/vitest"
2
2
  import { ConfigProvider, Effect, Layer } from "effect"
3
3
  import * as FileSystem from "effect/FileSystem"
4
4
  import * as Path from "effect/Path"
5
- import { SystemError } from "effect/PlatformError"
5
+ import { PlatformError, SystemError } from "effect/PlatformError"
6
6
  import {
7
7
  deleteProfileBySelector,
8
8
  HomeDirectoryLive,
9
+ type HomeDirectoryTag,
9
10
  loadActiveProfileToken,
10
11
  loadProfiles,
11
12
  type OAuthToken,
@@ -21,7 +22,9 @@ const profilesPath = `${basePath}/profiles.json`
21
22
 
22
23
  const fsError = (method: string) =>
23
24
  Effect.fail(
24
- new SystemError({ _tag: "NotFound", module: "FileSystem", method, description: "mock not found" })
25
+ new PlatformError(
26
+ new SystemError({ _tag: "NotFound", module: "FileSystem", method, description: "mock not found" })
27
+ )
25
28
  )
26
29
 
27
30
  const makeToken = (n: number): OAuthToken => ({
@@ -57,7 +60,7 @@ const makeMockFS = (files: Record<string, string> = {}) => {
57
60
 
58
61
  return {
59
62
  store,
60
- layer: Layer.succeed(FileSystem.FileSystem, FileSystem.FileSystem.of(partial))
63
+ layer: FileSystem.layerNoop(partial)
61
64
  }
62
65
  }
63
66
 
@@ -66,7 +69,7 @@ const ConfigProviderLive = ConfigProvider.layer(
66
69
  )
67
70
 
68
71
  const run = <A>(
69
- effect: Effect.Effect<A, unknown, FileSystem.FileSystem | Path.Path>,
72
+ effect: Effect.Effect<A, unknown, FileSystem.FileSystem | Path.Path | HomeDirectoryTag>,
70
73
  files?: Record<string, string>
71
74
  ) => {
72
75
  const mock = makeMockFS(files)
@@ -6,10 +6,11 @@ import * as Fiber from "effect/Fiber"
6
6
  import * as FileSystem from "effect/FileSystem"
7
7
  import { HttpClient, HttpClientResponse } from "effect/http"
8
8
  import * as Path from "effect/Path"
9
- import { SystemError } from "effect/PlatformError"
9
+ import { PlatformError, SystemError } from "effect/PlatformError"
10
10
  import {
11
11
  type AtlassianToolDefinition,
12
12
  HomeDirectoryLive,
13
+ type HomeDirectoryTag,
13
14
  inspectAllToolProfiles,
14
15
  migrateLegacyProfiles,
15
16
  MissingOAuthConfigError,
@@ -39,7 +40,11 @@ const sharedStoreTools: ReadonlyArray<AtlassianToolDefinition> = [
39
40
  ]
40
41
 
41
42
  const fsError = (method: string) =>
42
- Effect.fail(new SystemError({ _tag: "NotFound", module: "FileSystem", method, description: "mock not found" }))
43
+ Effect.fail(
44
+ new PlatformError(
45
+ new SystemError({ _tag: "NotFound", module: "FileSystem", method, description: "mock not found" })
46
+ )
47
+ )
43
48
 
44
49
  const makeToken = (n: number, scope = "read:me offline_access", expiresAt = Date.now() + 60_000): OAuthToken => ({
45
50
  access_token: `access-${n}`,
@@ -69,13 +74,13 @@ const makeMockFS = () => {
69
74
  }
70
75
  return {
71
76
  store,
72
- layer: Layer.succeed(FileSystem.FileSystem, FileSystem.FileSystem.of(partial))
77
+ layer: FileSystem.layerNoop(partial)
73
78
  }
74
79
  }
75
80
 
76
81
  const ConfigProviderLive = ConfigProvider.layer(ConfigProvider.fromEnv({ env: { HOME: TEST_HOME } }))
77
82
 
78
- const run = async <A>(effect: Effect.Effect<A, unknown, FileSystem.FileSystem | Path.Path>) => {
83
+ const run = async <A>(effect: Effect.Effect<A, unknown, FileSystem.FileSystem | Path.Path | HomeDirectoryTag>) => {
79
84
  const mock = makeMockFS()
80
85
  const layer = Layer.mergeAll(mock.layer, Path.layer, HomeDirectoryLive, ConfigProviderLive)
81
86
  const result = await Effect.runPromise(effect.pipe(Effect.provide(layer)))
@@ -242,7 +247,10 @@ describe("ProfileManager", () => {
242
247
  Effect.gen(function*() {
243
248
  yield* saveProfileToken("tool-a", makeToken(1, "read:me offline_access", Date.now() - 1_000))
244
249
  return yield* refreshActiveProfiles([tools[0]!])
245
- })
250
+ }).pipe(
251
+ // The refresh fails on configuration before any request; a request would be a regression.
252
+ Effect.provideService(HttpClient.HttpClient, HttpClient.make(() => Effect.die("no request expected")))
253
+ )
246
254
  )
247
255
  ).rejects.toBeInstanceOf(MissingOAuthConfigError)
248
256
  })
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it } from "@effect/vitest"
1
2
  import { JIRA_PROPOSAL_SCOPES, JIRA_SCOPES } from "../src/auth/index.js"
2
3
  import { JIRA_PROPOSAL_REQUIRED_SCOPES, JIRA_REQUIRED_SCOPES } from "../src/config/index.js"
3
4
 
@@ -73,7 +73,6 @@ const launchers = (opens: boolean) =>
73
73
  isRunning: Effect.succeed(false),
74
74
  kill: () => Effect.void,
75
75
  pid: ChildProcessSpawner.ProcessId(1),
76
- reref: Effect.void,
77
76
  stderr: Stream.empty,
78
77
  stdin: Sink.drain,
79
78
  stdout: Stream.empty,
@@ -118,7 +118,6 @@ const failingLaunchers = (launched: Deferred.Deferred<string>, attempts: Ref.Ref
118
118
  isRunning: Effect.succeed(false),
119
119
  kill: () => Effect.void,
120
120
  pid: ChildProcessSpawner.ProcessId(1),
121
- reref: Effect.void,
122
121
  stderr: Stream.empty,
123
122
  stdin: Sink.drain,
124
123
  stdout: Stream.empty,
@@ -32,7 +32,6 @@ const launchers = (outcomes: Readonly<Record<string, number>>, attempts: Array<s
32
32
  isRunning: Effect.succeed(false),
33
33
  kill: () => Effect.void,
34
34
  pid: ChildProcessSpawner.ProcessId(1),
35
- reref: Effect.void,
36
35
  stderr: Stream.empty,
37
36
  stdin: Sink.drain,
38
37
  stdout: Stream.empty,
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "composite": false,
6
+ "declaration": false,
7
+ "declarationMap": false,
8
+ "rootDir": "../../..",
9
+ "outDir": null,
10
+ "tsBuildInfoFile": null
11
+ },
12
+ "include": ["../src", "."],
13
+ "exclude": []
14
+ }