@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 +6 -0
- package/package.json +2 -2
- package/test/ApiUpdateWorkflows.test.ts +4 -2
- package/test/AuthProfiles.test.ts +7 -4
- package/test/ProfileManager.test.ts +13 -5
- package/test/PublicExports.test.ts +1 -0
- package/test/cliAuth.authCommand.test.ts +0 -1
- package/test/cliAuth.login.test.ts +0 -1
- package/test/cliAuth.openBrowser.test.ts +0 -1
- package/test/tsconfig.json +14 -0
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.
|
|
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 (
|
|
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)).
|
|
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
|
|
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:
|
|
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(
|
|
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:
|
|
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
|
})
|
|
@@ -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
|
+
}
|