@knpkv/atlassian-common 0.2.0 → 0.3.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/CHANGELOG.md +19 -0
- package/dist/Brand.d.ts +15 -15
- package/dist/Brand.d.ts.map +1 -1
- package/dist/Brand.js +5 -5
- package/dist/Brand.js.map +1 -1
- package/dist/Hash.d.ts +12 -14
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +18 -24
- package/dist/Hash.js.map +1 -1
- package/dist/ast/BlockNode.d.ts +120 -177
- package/dist/ast/BlockNode.d.ts.map +1 -1
- package/dist/ast/BlockNode.js +28 -8
- package/dist/ast/BlockNode.js.map +1 -1
- package/dist/ast/Document.d.ts +114 -156
- package/dist/ast/Document.d.ts.map +1 -1
- package/dist/ast/Document.js +1 -1
- package/dist/ast/Document.js.map +1 -1
- package/dist/ast/InlineNode.d.ts +59 -247
- package/dist/ast/InlineNode.d.ts.map +1 -1
- package/dist/ast/InlineNode.js +28 -3
- package/dist/ast/InlineNode.js.map +1 -1
- package/dist/ast/MacroNode.d.ts +62 -102
- package/dist/ast/MacroNode.d.ts.map +1 -1
- package/dist/ast/MacroNode.js +12 -5
- package/dist/ast/MacroNode.js.map +1 -1
- package/dist/auth/OAuthOperations.d.ts +1 -1
- package/dist/auth/OAuthOperations.d.ts.map +1 -1
- package/dist/auth/OAuthOperations.js +5 -6
- package/dist/auth/OAuthOperations.js.map +1 -1
- package/dist/auth/OAuthResponseSchemas.d.ts +13 -13
- package/dist/config/ConfigPaths.d.ts +6 -26
- package/dist/config/ConfigPaths.d.ts.map +1 -1
- package/dist/config/ConfigPaths.js +23 -3
- package/dist/config/ConfigPaths.js.map +1 -1
- package/dist/config/OAuthSchemas.d.ts +24 -24
- package/dist/config/TokenStorage.d.ts +5 -24
- package/dist/config/TokenStorage.d.ts.map +1 -1
- package/dist/config/TokenStorage.js +35 -22
- package/dist/config/TokenStorage.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -9
- package/src/Brand.ts +5 -17
- package/src/Hash.ts +27 -27
- package/src/ast/BlockNode.ts +13 -13
- package/src/ast/Document.ts +1 -1
- package/src/ast/InlineNode.ts +5 -5
- package/src/ast/MacroNode.ts +7 -6
- package/src/auth/OAuthOperations.ts +5 -6
- package/src/config/ConfigPaths.ts +7 -7
- package/src/config/TokenStorage.ts +23 -27
- package/src/index.ts +1 -1
- package/test/Hash.test.ts +52 -0
- package/test/OAuthOperations.test.ts +2 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -19,11 +19,11 @@ import * as Schema from "effect/Schema";
|
|
|
19
19
|
*/
|
|
20
20
|
export declare const OAuthUserSchema: Schema.Struct<{
|
|
21
21
|
/** Atlassian account ID */
|
|
22
|
-
account_id:
|
|
22
|
+
readonly account_id: Schema.String;
|
|
23
23
|
/** Display name */
|
|
24
|
-
name:
|
|
24
|
+
readonly name: Schema.String;
|
|
25
25
|
/** Email address */
|
|
26
|
-
email:
|
|
26
|
+
readonly email: Schema.String;
|
|
27
27
|
}>;
|
|
28
28
|
/**
|
|
29
29
|
* Type for OAuth user info.
|
|
@@ -53,25 +53,25 @@ export type OAuthUser = Schema.Schema.Type<typeof OAuthUserSchema>;
|
|
|
53
53
|
*/
|
|
54
54
|
export declare const OAuthTokenSchema: Schema.Struct<{
|
|
55
55
|
/** OAuth access token */
|
|
56
|
-
access_token:
|
|
56
|
+
readonly access_token: Schema.String;
|
|
57
57
|
/** OAuth refresh token */
|
|
58
|
-
refresh_token:
|
|
58
|
+
readonly refresh_token: Schema.String;
|
|
59
59
|
/** Token expiration timestamp (Unix ms) */
|
|
60
|
-
expires_at:
|
|
60
|
+
readonly expires_at: Schema.Number;
|
|
61
61
|
/** Granted scopes */
|
|
62
|
-
scope:
|
|
62
|
+
readonly scope: Schema.String;
|
|
63
63
|
/** Atlassian Cloud site ID */
|
|
64
|
-
cloud_id:
|
|
64
|
+
readonly cloud_id: Schema.String;
|
|
65
65
|
/** Site URL */
|
|
66
|
-
site_url:
|
|
66
|
+
readonly site_url: Schema.String;
|
|
67
67
|
/** Cached user info */
|
|
68
|
-
user: Schema.optional<Schema.Struct<{
|
|
68
|
+
readonly user: Schema.optional<Schema.Struct<{
|
|
69
69
|
/** Atlassian account ID */
|
|
70
|
-
account_id:
|
|
70
|
+
readonly account_id: Schema.String;
|
|
71
71
|
/** Display name */
|
|
72
|
-
name:
|
|
72
|
+
readonly name: Schema.String;
|
|
73
73
|
/** Email address */
|
|
74
|
-
email:
|
|
74
|
+
readonly email: Schema.String;
|
|
75
75
|
}>>;
|
|
76
76
|
}>;
|
|
77
77
|
/**
|
|
@@ -87,9 +87,9 @@ export type OAuthToken = Schema.Schema.Type<typeof OAuthTokenSchema>;
|
|
|
87
87
|
*/
|
|
88
88
|
export declare const OAuthConfigSchema: Schema.Struct<{
|
|
89
89
|
/** OAuth client ID from Atlassian Developer Console */
|
|
90
|
-
clientId:
|
|
90
|
+
readonly clientId: Schema.String;
|
|
91
91
|
/** OAuth client secret */
|
|
92
|
-
clientSecret:
|
|
92
|
+
readonly clientSecret: Schema.String;
|
|
93
93
|
}>;
|
|
94
94
|
/**
|
|
95
95
|
* Type for OAuth client configuration.
|
|
@@ -104,15 +104,15 @@ export type OAuthConfig = Schema.Schema.Type<typeof OAuthConfigSchema>;
|
|
|
104
104
|
*/
|
|
105
105
|
export declare const AtlassianSiteSchema: Schema.Struct<{
|
|
106
106
|
/** Cloud ID */
|
|
107
|
-
id:
|
|
107
|
+
readonly id: Schema.String;
|
|
108
108
|
/** Site name */
|
|
109
|
-
name:
|
|
109
|
+
readonly name: Schema.String;
|
|
110
110
|
/** Site URL */
|
|
111
|
-
url:
|
|
111
|
+
readonly url: Schema.String;
|
|
112
112
|
/** Available scopes */
|
|
113
|
-
scopes: Schema
|
|
113
|
+
readonly scopes: Schema.$Array<Schema.String>;
|
|
114
114
|
/** Avatar URL */
|
|
115
|
-
avatarUrl: Schema.optional<
|
|
115
|
+
readonly avatarUrl: Schema.optional<Schema.String>;
|
|
116
116
|
}>;
|
|
117
117
|
/**
|
|
118
118
|
* Type for Atlassian Cloud site.
|
|
@@ -127,13 +127,13 @@ export type AtlassianSite = Schema.Schema.Type<typeof AtlassianSiteSchema>;
|
|
|
127
127
|
*/
|
|
128
128
|
export declare const AtlassianUserSchema: Schema.Struct<{
|
|
129
129
|
/** Atlassian account ID */
|
|
130
|
-
accountId:
|
|
130
|
+
readonly accountId: Schema.String;
|
|
131
131
|
/** Display name */
|
|
132
|
-
displayName:
|
|
132
|
+
readonly displayName: Schema.String;
|
|
133
133
|
/** Email address (may be empty for privacy) */
|
|
134
|
-
email: Schema.optional<
|
|
134
|
+
readonly email: Schema.optional<Schema.String>;
|
|
135
135
|
/** Public name */
|
|
136
|
-
publicName: Schema.optional<
|
|
136
|
+
readonly publicName: Schema.optional<Schema.String>;
|
|
137
137
|
}>;
|
|
138
138
|
/**
|
|
139
139
|
* Type for Atlassian user profile.
|
|
@@ -1,26 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Persistent token and OAuth config storage with schema validation and secure file I/O.
|
|
3
|
-
*
|
|
4
|
-
* **Mental model**
|
|
5
|
-
*
|
|
6
|
-
* - **Load returns null, not error**: {@link loadToken} and {@link loadOAuthConfig} return
|
|
7
|
-
* `null` for missing/corrupt files — callers decide whether absence is an error.
|
|
8
|
-
* - **Save is atomic**: Writes go through {@link writeSecureFile} with `0o600` permissions.
|
|
9
|
-
* - **Schema-gated reads**: JSON is parsed then validated via `Schema.decodeUnknown` —
|
|
10
|
-
* corrupt data is treated as absent rather than crashing.
|
|
11
|
-
*
|
|
12
|
-
* **Common tasks**
|
|
13
|
-
*
|
|
14
|
-
* - Load stored token: {@link loadToken}
|
|
15
|
-
* - Persist after refresh: {@link saveToken}
|
|
16
|
-
* - Check expiration: {@link isTokenExpired}
|
|
17
|
-
*
|
|
18
|
-
* @module
|
|
19
|
-
*/
|
|
20
|
-
import type * as Error from "@effect/platform/Error";
|
|
21
|
-
import * as FileSystem from "@effect/platform/FileSystem";
|
|
22
|
-
import type * as Path from "@effect/platform/Path";
|
|
23
1
|
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as FileSystem from "effect/FileSystem";
|
|
3
|
+
import type * as Path from "effect/Path";
|
|
4
|
+
import type * as PlatformError from "effect/PlatformError";
|
|
24
5
|
import { type HomeDirectoryError, type HomeDirectoryTag } from "./ConfigPaths.js";
|
|
25
6
|
import { type OAuthConfig, type OAuthToken } from "./OAuthSchemas.js";
|
|
26
7
|
declare const FileSystemError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
@@ -55,7 +36,7 @@ export declare const loadToken: (toolName: string) => Effect.Effect<OAuthToken |
|
|
|
55
36
|
*
|
|
56
37
|
* @category Token Storage
|
|
57
38
|
*/
|
|
58
|
-
export declare const saveToken: (toolName: string, token: OAuthToken) => Effect.Effect<void, FileSystemError | HomeDirectoryError |
|
|
39
|
+
export declare const saveToken: (toolName: string, token: OAuthToken) => Effect.Effect<void, FileSystemError | HomeDirectoryError | PlatformError.PlatformError, FileSystem.FileSystem | Path.Path | HomeDirectoryTag>;
|
|
59
40
|
/**
|
|
60
41
|
* Delete stored OAuth token.
|
|
61
42
|
*
|
|
@@ -81,7 +62,7 @@ export declare const loadOAuthConfig: (toolName: string) => Effect.Effect<OAuthC
|
|
|
81
62
|
*
|
|
82
63
|
* @category OAuth Config
|
|
83
64
|
*/
|
|
84
|
-
export declare const saveOAuthConfig: (toolName: string, config: OAuthConfig) => Effect.Effect<void, FileSystemError | HomeDirectoryError |
|
|
65
|
+
export declare const saveOAuthConfig: (toolName: string, config: OAuthConfig) => Effect.Effect<void, FileSystemError | HomeDirectoryError | PlatformError.PlatformError, FileSystem.FileSystem | Path.Path | HomeDirectoryTag>;
|
|
85
66
|
/**
|
|
86
67
|
* Check if token is expired or about to expire.
|
|
87
68
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenStorage.d.ts","sourceRoot":"","sources":["../../src/config/TokenStorage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TokenStorage.d.ts","sourceRoot":"","sources":["../../src/config/TokenStorage.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,KAAK,aAAa,MAAM,sBAAsB,CAAA;AAE1D,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEjF,OAAO,EAAE,KAAK,WAAW,EAAqB,KAAK,UAAU,EAAoB,MAAM,mBAAmB,CAAA;;;;AAU1G;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,qBAAoC;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAE7B;CACF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GACpB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CACd,UAAU,GAAG,IAAI,EACjB,eAAe,GAAG,kBAAkB,EACpC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,gBAAgB,CA8BlD,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GACpB,UAAU,MAAM,EAChB,OAAO,UAAU,KAChB,MAAM,CAAC,MAAM,CACd,IAAI,EACJ,eAAe,GAAG,kBAAkB,GAAG,aAAa,CAAC,aAAa,EAClE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAUlD,CAAA;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAQ7G,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CACd,WAAW,GAAG,IAAI,EAClB,eAAe,GAAG,kBAAkB,EACpC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,gBAAgB,CA8BlD,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,QAAQ,WAAW,KAClB,MAAM,CAAC,MAAM,CACd,IAAI,EACJ,eAAe,GAAG,kBAAkB,GAAG,aAAa,CAAC,aAAa,EAClE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAUlD,CAAA;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,EAAE,WAAU,MAAsB,KAAG,OAC1C,CAAA"}
|
|
@@ -1,10 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Persistent token and OAuth config storage with schema validation and secure file I/O.
|
|
3
|
+
*
|
|
4
|
+
* **Mental model**
|
|
5
|
+
*
|
|
6
|
+
* - **Load returns null, not error**: {@link loadToken} and {@link loadOAuthConfig} return
|
|
7
|
+
* `null` for missing/corrupt files — callers decide whether absence is an error.
|
|
8
|
+
* - **Save is atomic**: Writes go through {@link writeSecureFile} with `0o600` permissions.
|
|
9
|
+
* - **Schema-gated reads**: JSON is parsed then validated via `Schema.decodeUnknownEffect` —
|
|
10
|
+
* corrupt data is treated as absent rather than crashing.
|
|
11
|
+
*
|
|
12
|
+
* **Common tasks**
|
|
13
|
+
*
|
|
14
|
+
* - Load stored token: {@link loadToken}
|
|
15
|
+
* - Persist after refresh: {@link saveToken}
|
|
16
|
+
* - Check expiration: {@link isTokenExpired}
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
2
20
|
import * as Data from "effect/Data";
|
|
3
21
|
import * as Effect from "effect/Effect";
|
|
22
|
+
import * as FileSystem from "effect/FileSystem";
|
|
4
23
|
import * as Schema from "effect/Schema";
|
|
5
24
|
import {} from "./ConfigPaths.js";
|
|
6
25
|
import { ensureConfigDir, getAuthPath, getOAuthConfigPath, writeSecureFile } from "./ConfigPaths.js";
|
|
7
26
|
import { OAuthConfigSchema, OAuthTokenSchema } from "./OAuthSchemas.js";
|
|
27
|
+
const parseJsonOrNull = (content) => {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(content);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
8
35
|
/**
|
|
9
36
|
* Error during file system operations.
|
|
10
37
|
*
|
|
@@ -26,24 +53,17 @@ export class FileSystemError extends Data.TaggedError("FileSystemError") {
|
|
|
26
53
|
export const loadToken = (toolName) => Effect.gen(function* () {
|
|
27
54
|
const fs = yield* FileSystem.FileSystem;
|
|
28
55
|
const tokenPath = yield* getAuthPath(toolName);
|
|
29
|
-
const exists = yield* fs.exists(tokenPath).pipe(Effect.
|
|
56
|
+
const exists = yield* fs.exists(tokenPath).pipe(Effect.catchCause(() => Effect.succeed(false)));
|
|
30
57
|
if (!exists) {
|
|
31
58
|
return null;
|
|
32
59
|
}
|
|
33
60
|
const content = yield* fs.readFileString(tokenPath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "read", path: tokenPath, cause })));
|
|
34
|
-
const parsed = yield* Effect.sync(() =>
|
|
35
|
-
try {
|
|
36
|
-
return JSON.parse(content);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
61
|
+
const parsed = yield* Effect.sync(() => parseJsonOrNull(content));
|
|
42
62
|
if (parsed === null) {
|
|
43
63
|
yield* Effect.logWarning(`Corrupted auth.json at ${tokenPath} — could not parse JSON`);
|
|
44
64
|
return null;
|
|
45
65
|
}
|
|
46
|
-
return yield* Schema.
|
|
66
|
+
return yield* Schema.decodeUnknownEffect(OAuthTokenSchema)(parsed).pipe(Effect.catchCause((e) => Effect.logWarning(`Invalid token schema in ${tokenPath}: ${e}`).pipe(Effect.map(() => null))));
|
|
47
67
|
});
|
|
48
68
|
/**
|
|
49
69
|
* Save OAuth token to disk with secure permissions.
|
|
@@ -69,7 +89,7 @@ export const saveToken = (toolName, token) => Effect.gen(function* () {
|
|
|
69
89
|
export const deleteToken = (toolName) => Effect.gen(function* () {
|
|
70
90
|
const fs = yield* FileSystem.FileSystem;
|
|
71
91
|
const tokenPath = yield* getAuthPath(toolName);
|
|
72
|
-
yield* fs.remove(tokenPath).pipe(Effect.
|
|
92
|
+
yield* fs.remove(tokenPath).pipe(Effect.catchCause(() => Effect.void));
|
|
73
93
|
});
|
|
74
94
|
/**
|
|
75
95
|
* Load OAuth client configuration from disk.
|
|
@@ -82,24 +102,17 @@ export const deleteToken = (toolName) => Effect.gen(function* () {
|
|
|
82
102
|
export const loadOAuthConfig = (toolName) => Effect.gen(function* () {
|
|
83
103
|
const fs = yield* FileSystem.FileSystem;
|
|
84
104
|
const configPath = yield* getOAuthConfigPath(toolName);
|
|
85
|
-
const exists = yield* fs.exists(configPath).pipe(Effect.
|
|
105
|
+
const exists = yield* fs.exists(configPath).pipe(Effect.catchCause(() => Effect.succeed(false)));
|
|
86
106
|
if (!exists) {
|
|
87
107
|
return null;
|
|
88
108
|
}
|
|
89
109
|
const content = yield* fs.readFileString(configPath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "read", path: configPath, cause })));
|
|
90
|
-
const parsed = yield* Effect.sync(() =>
|
|
91
|
-
try {
|
|
92
|
-
return JSON.parse(content);
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
});
|
|
110
|
+
const parsed = yield* Effect.sync(() => parseJsonOrNull(content));
|
|
98
111
|
if (parsed === null) {
|
|
99
112
|
yield* Effect.logWarning(`Corrupted oauth config at ${configPath} — could not parse JSON`);
|
|
100
113
|
return null;
|
|
101
114
|
}
|
|
102
|
-
return yield* Schema.
|
|
115
|
+
return yield* Schema.decodeUnknownEffect(OAuthConfigSchema)(parsed).pipe(Effect.catchCause((e) => Effect.logWarning(`Invalid OAuth config schema in ${configPath}: ${e}`).pipe(Effect.map(() => null))));
|
|
103
116
|
});
|
|
104
117
|
/**
|
|
105
118
|
* Save OAuth client configuration to disk with secure permissions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenStorage.js","sourceRoot":"","sources":["../../src/config/TokenStorage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TokenStorage.js","sourceRoot":"","sources":["../../src/config/TokenStorage.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export * from "./ast/index.js";
|
|
7
7
|
export { ContentHash, IssueKey, makeBrandedNonEmptyString, makeBrandedString, PageId, ProjectKey, SpaceKey } from "./Brand.js";
|
|
8
|
-
export { hashBuffer, hashContent,
|
|
8
|
+
export { hashBuffer, hashContent, hashEquals } from "./Hash.js";
|
|
9
9
|
export { ParseError, SerializeError } from "./SerializeError.js";
|
|
10
10
|
export { serializeInlineNodes, type SerializeOptions, serializeToMarkdown } from "./serializers/index.js";
|
|
11
11
|
export * from "./config/index.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,gBAAgB,CAAA;AAG9B,OAAO,EACL,WAAW,EACX,QAAQ,EACR,yBAAyB,EACzB,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,QAAQ,EACT,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,gBAAgB,CAAA;AAG9B,OAAO,EACL,WAAW,EACX,QAAQ,EACR,yBAAyB,EACzB,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,QAAQ,EACT,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAG/D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGhE,OAAO,EAAE,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAGzG,cAAc,mBAAmB,CAAA;AAGjC,cAAc,iBAAiB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export * from "./ast/index.js";
|
|
|
8
8
|
// Brand utilities
|
|
9
9
|
export { ContentHash, IssueKey, makeBrandedNonEmptyString, makeBrandedString, PageId, ProjectKey, SpaceKey } from "./Brand.js";
|
|
10
10
|
// Hash utilities
|
|
11
|
-
export { hashBuffer, hashContent,
|
|
11
|
+
export { hashBuffer, hashContent, hashEquals } from "./Hash.js";
|
|
12
12
|
// Error types
|
|
13
13
|
export { ParseError, SerializeError } from "./SerializeError.js";
|
|
14
14
|
// Serializers
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY;AACZ,cAAc,gBAAgB,CAAA;AAE9B,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,yBAAyB,EACzB,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,QAAQ,EACT,MAAM,YAAY,CAAA;AAEnB,iBAAiB;AACjB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY;AACZ,cAAc,gBAAgB,CAAA;AAE9B,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,yBAAyB,EACzB,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,QAAQ,EACT,MAAM,YAAY,CAAA;AAEnB,iBAAiB;AACjB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE/D,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEhE,cAAc;AACd,OAAO,EAAE,oBAAoB,EAAyB,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEzG,mBAAmB;AACnB,cAAc,mBAAmB,CAAA;AAEjC,iBAAiB;AACjB,cAAc,iBAAiB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knpkv/atlassian-common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared utilities for Atlassian tools (AST, serializers, auth, config)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "knpkv",
|
|
@@ -47,8 +47,7 @@
|
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"
|
|
51
|
-
"effect": ">=3.19.3"
|
|
50
|
+
"effect": "4.0.0-beta.87"
|
|
52
51
|
},
|
|
53
52
|
"dependencies": {
|
|
54
53
|
"remark-gfm": "^4.0.1",
|
|
@@ -57,13 +56,12 @@
|
|
|
57
56
|
"unified": "^11.0.5"
|
|
58
57
|
},
|
|
59
58
|
"devDependencies": {
|
|
60
|
-
"@effect/platform": "
|
|
61
|
-
"@effect/
|
|
62
|
-
"@effect/vitest": "latest",
|
|
59
|
+
"@effect/platform-node": "4.0.0-beta.87",
|
|
60
|
+
"@effect/vitest": "4.0.0-beta.87",
|
|
63
61
|
"@types/node": "latest",
|
|
64
|
-
"effect": "
|
|
65
|
-
"typescript": "~
|
|
66
|
-
"vitest": "^4.
|
|
62
|
+
"effect": "4.0.0-beta.87",
|
|
63
|
+
"typescript": "~6.0.3",
|
|
64
|
+
"vitest": "^4.1.9"
|
|
67
65
|
},
|
|
68
66
|
"keywords": [
|
|
69
67
|
"effect",
|
package/src/Brand.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* **Mental model**
|
|
5
5
|
*
|
|
6
6
|
* - **Brand = runtime validation + compile-time narrowing**: Each brand combines
|
|
7
|
-
* an Effect `Brand.
|
|
7
|
+
* an Effect `Brand.make` (throws on invalid values) with an Effect `Schema`
|
|
8
8
|
* (composable validation). The `Type` property exposes the branded type for use
|
|
9
9
|
* in type annotations.
|
|
10
10
|
* - **Pattern-guarded strings**: `SpaceKey`, `IssueKey`, `ProjectKey` are regex-branded;
|
|
@@ -48,15 +48,9 @@ export const makeBrandedString = <B extends string>(
|
|
|
48
48
|
) => {
|
|
49
49
|
type BrandedType = string & Brand.Brand<B>
|
|
50
50
|
|
|
51
|
-
const brand = Brand.
|
|
52
|
-
(s) => pattern.test(s),
|
|
53
|
-
(s) => Brand.error(`Invalid ${name}: ${s} does not match ${pattern}`)
|
|
54
|
-
)
|
|
51
|
+
const brand = Brand.make<BrandedType>((s) => pattern.test(s) || `Invalid ${name}: ${s} does not match ${pattern}`)
|
|
55
52
|
|
|
56
|
-
const schema = Schema.String.pipe(
|
|
57
|
-
Schema.pattern(pattern),
|
|
58
|
-
Schema.brand(name)
|
|
59
|
-
)
|
|
53
|
+
const schema = Schema.String.check(Schema.isPattern(pattern)).pipe(Schema.brand(name))
|
|
60
54
|
|
|
61
55
|
return Object.assign(brand, {
|
|
62
56
|
schema,
|
|
@@ -83,15 +77,9 @@ export const makeBrandedString = <B extends string>(
|
|
|
83
77
|
export const makeBrandedNonEmptyString = <B extends string>(name: B) => {
|
|
84
78
|
type BrandedType = string & Brand.Brand<B>
|
|
85
79
|
|
|
86
|
-
const brand = Brand.
|
|
87
|
-
(s) => s.length > 0,
|
|
88
|
-
(_s) => Brand.error(`${name} cannot be empty`)
|
|
89
|
-
)
|
|
80
|
+
const brand = Brand.make<BrandedType>((s) => s.length > 0 || `${name} cannot be empty`)
|
|
90
81
|
|
|
91
|
-
const schema = Schema.
|
|
92
|
-
Schema.nonEmptyString(),
|
|
93
|
-
Schema.brand(name)
|
|
94
|
-
)
|
|
82
|
+
const schema = Schema.NonEmptyString.pipe(Schema.brand(name))
|
|
95
83
|
|
|
96
84
|
return Object.assign(brand, {
|
|
97
85
|
schema,
|
package/src/Hash.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SHA256 content hashing via
|
|
2
|
+
* SHA256 content hashing via Effect's platform `Crypto` service, returning branded {@link ContentHash} values.
|
|
3
3
|
*
|
|
4
4
|
* **Mental model**
|
|
5
5
|
*
|
|
6
|
-
* - **
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
6
|
+
* - **Service-backed crypto**: {@link hashContent} and {@link hashBuffer} use
|
|
7
|
+
* the `Crypto` service from Effect context, so applications provide the
|
|
8
|
+
* platform implementation at the runtime edge.
|
|
9
9
|
*
|
|
10
10
|
* **Common tasks**
|
|
11
11
|
*
|
|
@@ -15,40 +15,50 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @module
|
|
17
17
|
*/
|
|
18
|
+
import * as Crypto from "effect/Crypto"
|
|
18
19
|
import * as Effect from "effect/Effect"
|
|
19
|
-
import * as
|
|
20
|
+
import * as Encoding from "effect/Encoding"
|
|
21
|
+
import type * as PlatformError from "effect/PlatformError"
|
|
20
22
|
import { ContentHash } from "./Brand.js"
|
|
21
23
|
|
|
24
|
+
const textEncoder = new TextEncoder()
|
|
25
|
+
|
|
26
|
+
const digestSha256 = (
|
|
27
|
+
bytes: Uint8Array
|
|
28
|
+
): Effect.Effect<ContentHash, PlatformError.PlatformError, Crypto.Crypto> =>
|
|
29
|
+
Effect.gen(function*() {
|
|
30
|
+
const crypto = yield* Crypto.Crypto
|
|
31
|
+
const digest = yield* crypto.digest("SHA-256", bytes)
|
|
32
|
+
return ContentHash(Encoding.encodeHex(digest))
|
|
33
|
+
})
|
|
34
|
+
|
|
22
35
|
/**
|
|
23
36
|
* Compute SHA256 hash of a string.
|
|
24
37
|
*
|
|
25
38
|
* @example
|
|
26
39
|
* ```typescript
|
|
27
|
-
* import
|
|
40
|
+
* import * as Crypto from "effect/Crypto"
|
|
28
41
|
* import * as Effect from "effect/Effect"
|
|
42
|
+
* import { hashContent } from "@knpkv/atlassian-common"
|
|
29
43
|
*
|
|
30
|
-
* const
|
|
44
|
+
* declare const crypto: Crypto.Crypto
|
|
45
|
+
* const hash = Effect.runSync(hashContent("hello world").pipe(Effect.provideService(Crypto.Crypto, crypto)))
|
|
31
46
|
* // => "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
|
|
32
47
|
* ```
|
|
33
48
|
*
|
|
34
49
|
* @category Hash
|
|
35
50
|
*/
|
|
36
|
-
export const hashContent = (content: string): Effect.Effect<ContentHash> =>
|
|
37
|
-
|
|
38
|
-
const hash = crypto.createHash("sha256").update(content, "utf8").digest("hex")
|
|
39
|
-
return ContentHash(hash)
|
|
40
|
-
})
|
|
51
|
+
export const hashContent = (content: string): Effect.Effect<ContentHash, PlatformError.PlatformError, Crypto.Crypto> =>
|
|
52
|
+
digestSha256(textEncoder.encode(content))
|
|
41
53
|
|
|
42
54
|
/**
|
|
43
55
|
* Compute SHA256 hash of a buffer.
|
|
44
56
|
*
|
|
45
57
|
* @category Hash
|
|
46
58
|
*/
|
|
47
|
-
export const hashBuffer = (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return ContentHash(hash)
|
|
51
|
-
})
|
|
59
|
+
export const hashBuffer = (
|
|
60
|
+
buffer: Uint8Array
|
|
61
|
+
): Effect.Effect<ContentHash, PlatformError.PlatformError, Crypto.Crypto> => digestSha256(buffer)
|
|
52
62
|
|
|
53
63
|
/**
|
|
54
64
|
* Check if two hashes are equal.
|
|
@@ -56,13 +66,3 @@ export const hashBuffer = (buffer: Buffer | Uint8Array): Effect.Effect<ContentHa
|
|
|
56
66
|
* @category Hash
|
|
57
67
|
*/
|
|
58
68
|
export const hashEquals = (a: ContentHash, b: ContentHash): boolean => a === b
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Synchronous version of hashContent for simple use cases.
|
|
62
|
-
*
|
|
63
|
-
* @category Hash
|
|
64
|
-
*/
|
|
65
|
-
export const hashContentSync = (content: string): ContentHash => {
|
|
66
|
-
const hash = crypto.createHash("sha256").update(content, "utf8").digest("hex")
|
|
67
|
-
return ContentHash(hash)
|
|
68
|
-
}
|
package/src/ast/BlockNode.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
|
+
import * as Effect from "effect/Effect"
|
|
14
15
|
import * as Schema from "effect/Schema"
|
|
15
16
|
import { InlineNode, type InlineNode as InlineNodeType } from "./InlineNode.js"
|
|
16
17
|
|
|
@@ -19,10 +20,9 @@ import { InlineNode, type InlineNode as InlineNodeType } from "./InlineNode.js"
|
|
|
19
20
|
*
|
|
20
21
|
* @category Version
|
|
21
22
|
*/
|
|
22
|
-
export const SchemaVersion = Schema.
|
|
23
|
-
Schema.
|
|
24
|
-
Schema.
|
|
25
|
-
Schema.optionalWith({ default: () => 1 })
|
|
23
|
+
export const SchemaVersion = Schema.Int.pipe(
|
|
24
|
+
Schema.check(Schema.isGreaterThan(0)),
|
|
25
|
+
Schema.withConstructorDefault(Effect.succeed(1))
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -49,7 +49,7 @@ export const RawSource = Schema.optional(Schema.String)
|
|
|
49
49
|
*/
|
|
50
50
|
export class Heading extends Schema.TaggedClass<Heading>()("Heading", {
|
|
51
51
|
version: SchemaVersion,
|
|
52
|
-
level: Schema.
|
|
52
|
+
level: Schema.Literals([1, 2, 3, 4, 5, 6]),
|
|
53
53
|
children: Schema.Array(InlineNode),
|
|
54
54
|
rawSource: RawSource
|
|
55
55
|
}) {}
|
|
@@ -59,7 +59,7 @@ export class Heading extends Schema.TaggedClass<Heading>()("Heading", {
|
|
|
59
59
|
*
|
|
60
60
|
* @category BlockNode
|
|
61
61
|
*/
|
|
62
|
-
export const TextAlignment = Schema.
|
|
62
|
+
export const TextAlignment = Schema.Literals(["left", "center", "right"])
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
65
|
* Type for TextAlignment.
|
|
@@ -187,7 +187,7 @@ export class Image extends Schema.TaggedClass<Image>()("Image", {
|
|
|
187
187
|
* @category BlockNode
|
|
188
188
|
*/
|
|
189
189
|
export class TableCell extends Schema.TaggedClass<TableCell>()("TableCell", {
|
|
190
|
-
isHeader: Schema.
|
|
190
|
+
isHeader: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
|
|
191
191
|
children: Schema.Array(InlineNode),
|
|
192
192
|
rawSource: RawSource
|
|
193
193
|
}) {}
|
|
@@ -223,11 +223,11 @@ export class UnsupportedBlock extends Schema.TaggedClass<UnsupportedBlock>()("Un
|
|
|
223
223
|
rawHtml: Schema.optional(Schema.String),
|
|
224
224
|
rawMarkdown: Schema.optional(Schema.String),
|
|
225
225
|
rawAdf: Schema.optional(Schema.String),
|
|
226
|
-
source: Schema.
|
|
226
|
+
source: Schema.Literals(["confluence", "markdown", "adf"])
|
|
227
227
|
}) {}
|
|
228
228
|
|
|
229
229
|
// Non-recursive block nodes
|
|
230
|
-
const SimpleBlockNode = Schema.Union(
|
|
230
|
+
const SimpleBlockNode = Schema.Union([
|
|
231
231
|
Heading,
|
|
232
232
|
Paragraph,
|
|
233
233
|
CodeBlock,
|
|
@@ -235,7 +235,7 @@ const SimpleBlockNode = Schema.Union(
|
|
|
235
235
|
Image,
|
|
236
236
|
Table,
|
|
237
237
|
UnsupportedBlock
|
|
238
|
-
)
|
|
238
|
+
])
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
241
|
* Block quote element with nested block content.
|
|
@@ -305,7 +305,7 @@ export const TaskItem = Schema.Struct({
|
|
|
305
305
|
_tag: Schema.Literal("TaskItem"),
|
|
306
306
|
id: Schema.String,
|
|
307
307
|
uuid: Schema.String,
|
|
308
|
-
status: Schema.
|
|
308
|
+
status: Schema.Literals(["incomplete", "complete"]),
|
|
309
309
|
body: Schema.Array(InlineNode),
|
|
310
310
|
rawSource: RawSource
|
|
311
311
|
})
|
|
@@ -341,7 +341,7 @@ export type TaskList = Schema.Schema.Type<typeof TaskList>
|
|
|
341
341
|
*
|
|
342
342
|
* @category BlockNode
|
|
343
343
|
*/
|
|
344
|
-
export const BlockNode = Schema.Union(
|
|
344
|
+
export const BlockNode = Schema.Union([
|
|
345
345
|
Heading,
|
|
346
346
|
Paragraph,
|
|
347
347
|
CodeBlock,
|
|
@@ -352,7 +352,7 @@ export const BlockNode = Schema.Union(
|
|
|
352
352
|
List,
|
|
353
353
|
TaskList,
|
|
354
354
|
UnsupportedBlock
|
|
355
|
-
)
|
|
355
|
+
])
|
|
356
356
|
|
|
357
357
|
/**
|
|
358
358
|
* Type for block nodes.
|
package/src/ast/Document.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { MacroNode, type MacroNode as MacroNodeType } from "./MacroNode.js"
|
|
|
23
23
|
*
|
|
24
24
|
* @category Document
|
|
25
25
|
*/
|
|
26
|
-
export const DocumentNode = Schema.Union(BlockNode, MacroNode)
|
|
26
|
+
export const DocumentNode = Schema.Union([BlockNode, MacroNode])
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Type for document nodes.
|
package/src/ast/InlineNode.ts
CHANGED
|
@@ -82,7 +82,7 @@ export class LineBreak extends Schema.TaggedClass<LineBreak>()("LineBreak", {})
|
|
|
82
82
|
*/
|
|
83
83
|
export class UnsupportedInline extends Schema.TaggedClass<UnsupportedInline>()("UnsupportedInline", {
|
|
84
84
|
raw: Schema.String,
|
|
85
|
-
source: Schema.
|
|
85
|
+
source: Schema.Literals(["confluence", "markdown", "adf"])
|
|
86
86
|
}) {}
|
|
87
87
|
|
|
88
88
|
/**
|
|
@@ -199,7 +199,7 @@ export class Highlight extends Schema.TaggedClass<Highlight>()("Highlight", {
|
|
|
199
199
|
}) {}
|
|
200
200
|
|
|
201
201
|
// Forward declaration for recursive types
|
|
202
|
-
const InlineNodeBase = Schema.Union(
|
|
202
|
+
const InlineNodeBase = Schema.Union([
|
|
203
203
|
Text,
|
|
204
204
|
InlineCode,
|
|
205
205
|
LineBreak,
|
|
@@ -207,7 +207,7 @@ const InlineNodeBase = Schema.Union(
|
|
|
207
207
|
UserMention,
|
|
208
208
|
DateTime,
|
|
209
209
|
UnsupportedInline
|
|
210
|
-
)
|
|
210
|
+
])
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
213
|
* Inline node children schema - use this for recursive inline content.
|
|
@@ -278,7 +278,7 @@ export class Link extends Schema.TaggedClass<Link>()("Link", {
|
|
|
278
278
|
*
|
|
279
279
|
* @category InlineNode
|
|
280
280
|
*/
|
|
281
|
-
export const InlineNode = Schema.Union(
|
|
281
|
+
export const InlineNode = Schema.Union([
|
|
282
282
|
Text,
|
|
283
283
|
Strong,
|
|
284
284
|
Emphasis,
|
|
@@ -295,7 +295,7 @@ export const InlineNode = Schema.Union(
|
|
|
295
295
|
ColoredText,
|
|
296
296
|
Highlight,
|
|
297
297
|
UnsupportedInline
|
|
298
|
-
)
|
|
298
|
+
])
|
|
299
299
|
|
|
300
300
|
/**
|
|
301
301
|
* Type for inline nodes.
|