@skmtc/core 0.28.6 → 0.29.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/esm/context/GenerateContext.js +16 -16
- package/esm/context/RenderContext.d.ts +7 -7
- package/esm/context/RenderContext.js +17 -12
- package/esm/deps/jsr.io/@std/path/1.1.6/posix/is_absolute.d.ts +16 -0
- package/esm/deps/jsr.io/@std/path/1.1.6/posix/is_absolute.js +23 -0
- package/esm/deps/jsr.io/@std/path/1.1.6/windows/is_absolute.d.ts +16 -0
- package/esm/deps/jsr.io/@std/path/1.1.6/windows/is_absolute.js +38 -0
- package/esm/dsl/model/ModelDriver.js +4 -3
- package/esm/dsl/operation/gql/GqlOperationDriver.js +4 -3
- package/esm/dsl/operation/oas/OasOperationDriver.js +4 -3
- package/esm/dsl/webhook/WebhookDriver.js +4 -3
- package/esm/helpers/applyGeneratedSuffix.js +1 -1
- package/esm/helpers/isImported.d.ts +10 -74
- package/esm/helpers/isImported.js +12 -76
- package/esm/helpers/normalizeWorkspacePath.d.ts +64 -0
- package/esm/helpers/normalizeWorkspacePath.js +98 -0
- package/esm/helpers/toResolvedArtifactPath.d.ts +8 -5
- package/esm/helpers/toResolvedArtifactPath.js +11 -7
- package/esm/helpers/toWorkspacePath.d.ts +3 -3
- package/esm/helpers/toWorkspacePath.js +5 -5
- package/esm/mod.d.ts +1 -0
- package/esm/mod.js +1 -0
- package/esm/types/Settings.js +6 -8
- package/package.json +1 -1
- package/script/context/GenerateContext.js +16 -16
- package/script/context/RenderContext.d.ts +7 -7
- package/script/context/RenderContext.js +17 -12
- package/script/deps/jsr.io/@std/path/1.1.6/posix/is_absolute.d.ts +16 -0
- package/script/deps/jsr.io/@std/path/1.1.6/posix/is_absolute.js +26 -0
- package/script/deps/jsr.io/@std/path/1.1.6/windows/is_absolute.d.ts +16 -0
- package/script/deps/jsr.io/@std/path/1.1.6/windows/is_absolute.js +41 -0
- package/script/dsl/model/ModelDriver.js +4 -3
- package/script/dsl/operation/gql/GqlOperationDriver.js +4 -3
- package/script/dsl/operation/oas/OasOperationDriver.js +4 -3
- package/script/dsl/webhook/WebhookDriver.js +4 -3
- package/script/helpers/applyGeneratedSuffix.js +1 -1
- package/script/helpers/isImported.d.ts +10 -74
- package/script/helpers/isImported.js +12 -76
- package/script/helpers/normalizeWorkspacePath.d.ts +64 -0
- package/script/helpers/normalizeWorkspacePath.js +107 -0
- package/script/helpers/toResolvedArtifactPath.d.ts +8 -5
- package/script/helpers/toResolvedArtifactPath.js +11 -7
- package/script/helpers/toWorkspacePath.d.ts +3 -3
- package/script/helpers/toWorkspacePath.js +5 -5
- package/script/mod.d.ts +1 -0
- package/script/mod.js +1 -0
- package/script/types/Settings.js +7 -9
- package/esm/deps/jsr.io/@std/path/1.1.6/extname.d.ts +0 -24
- package/esm/deps/jsr.io/@std/path/1.1.6/extname.js +0 -31
- package/esm/deps/jsr.io/@std/path/1.1.6/normalize.d.ts +0 -25
- package/esm/deps/jsr.io/@std/path/1.1.6/normalize.js +0 -32
- package/esm/deps/jsr.io/@std/path/1.1.6/windows/extname.d.ts +0 -17
- package/esm/deps/jsr.io/@std/path/1.1.6/windows/extname.js +0 -83
- package/script/deps/jsr.io/@std/path/1.1.6/extname.d.ts +0 -24
- package/script/deps/jsr.io/@std/path/1.1.6/extname.js +0 -34
- package/script/deps/jsr.io/@std/path/1.1.6/normalize.d.ts +0 -25
- package/script/deps/jsr.io/@std/path/1.1.6/normalize.js +0 -35
- package/script/deps/jsr.io/@std/path/1.1.6/windows/extname.d.ts +0 -17
- package/script/deps/jsr.io/@std/path/1.1.6/windows/extname.js +0 -86
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link normalizeWorkspacePath} and {@link toNormalizedWorkspacePath}.
|
|
3
|
+
*/
|
|
4
|
+
export type NormalizeWorkspacePathOptions = {
|
|
5
|
+
/** Names the generator in the error when the path is rejected. */
|
|
6
|
+
generatorId?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Whether a path contains a `..` parent-reference segment. `..` is a parent
|
|
10
|
+
* reference only as a whole segment — a directory name that merely contains
|
|
11
|
+
* dots is not flagged.
|
|
12
|
+
*/
|
|
13
|
+
export declare const hasParentSegment: (path: string) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Whether a path is absolute on either host: a POSIX root, a Windows drive
|
|
16
|
+
* (`C:\`, `C:/`) or a UNC share. Checked on every host, so a client.json
|
|
17
|
+
* written on Windows is rejected the same way on Linux.
|
|
18
|
+
*/
|
|
19
|
+
export declare const isAbsolutePath: (path: string) => boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether `path` is spelled from the workspace root — `@/`, `./`, a bare
|
|
22
|
+
* leading `/`, or their Windows forms. An artifact path, never a bare
|
|
23
|
+
* module specifier such as `zod` or `@tanstack/query`.
|
|
24
|
+
*/
|
|
25
|
+
export declare const hasWorkspaceAnchor: (path: string) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Whether `path` can name a file below `basePath`: not a Windows drive or
|
|
28
|
+
* UNC path, no `..` segment, and not `basePath` itself. The non-throwing
|
|
29
|
+
* form of {@link normalizeWorkspacePath}'s checks, for schema validation
|
|
30
|
+
* and for comparing a module specifier against a file path.
|
|
31
|
+
*/
|
|
32
|
+
export declare const isValidWorkspacePath: (path: string) => boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The path relative to `basePath`, normalized and with no anchor:
|
|
35
|
+
* what {@link normalizeWorkspacePath} writes after `@/`, and what
|
|
36
|
+
* {@link toResolvedArtifactPath} joins onto `basePath`.
|
|
37
|
+
*
|
|
38
|
+
* Throws when the path cannot name a file below `basePath`: a Windows
|
|
39
|
+
* drive or UNC path, a `..` segment (checked as a whole segment before
|
|
40
|
+
* normalization, so it is never resolved), or a path naming `basePath`
|
|
41
|
+
* itself (`@/`, `@`, `./`, `.`, `/`, ``).
|
|
42
|
+
*/
|
|
43
|
+
export declare const toNormalizedWorkspacePath: (path: string, { generatorId }?: NormalizeWorkspacePathOptions) => string;
|
|
44
|
+
/**
|
|
45
|
+
* The one spelling of a workspace path — an export path or a destination
|
|
46
|
+
* path: `@/` followed by a POSIX path relative to `basePath`.
|
|
47
|
+
*
|
|
48
|
+
* A workspace path is a logical path inside the workspace, never a
|
|
49
|
+
* filesystem path, so it reads the same on every host. A generator may
|
|
50
|
+
* return one as `@/types/User.ts`, `./types/User.ts`, `/types/User.ts`,
|
|
51
|
+
* `types/User.ts`, or with Windows separators; the engine stores this form
|
|
52
|
+
* and nothing else, so file-map keys, import modules and the ejected lookup
|
|
53
|
+
* always agree. The result is a fixed point.
|
|
54
|
+
*
|
|
55
|
+
* Throws in the cases {@link toNormalizedWorkspacePath} throws.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* normalizeWorkspacePath('@\\types\\User.ts') // '@/types/User.ts'
|
|
60
|
+
* normalizeWorkspacePath('./types/User.ts') // '@/types/User.ts'
|
|
61
|
+
* normalizeWorkspacePath('../User.ts') // throws
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const normalizeWorkspacePath: (path: string, options?: NormalizeWorkspacePathOptions) => string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { normalize } from '../deps/jsr.io/@std/path/1.1.6/posix/normalize.js';
|
|
2
|
+
import { isAbsolute as isPosixAbsolute } from '../deps/jsr.io/@std/path/1.1.6/posix/is_absolute.js';
|
|
3
|
+
import { isAbsolute as isWindowsAbsolute } from '../deps/jsr.io/@std/path/1.1.6/windows/is_absolute.js';
|
|
4
|
+
import { toWorkspacePath } from './toWorkspacePath.js';
|
|
5
|
+
/**
|
|
6
|
+
* Whether a path contains a `..` parent-reference segment. `..` is a parent
|
|
7
|
+
* reference only as a whole segment — a directory name that merely contains
|
|
8
|
+
* dots is not flagged.
|
|
9
|
+
*/
|
|
10
|
+
export const hasParentSegment = (path) => path.split(/[/\\]/).some(segment => segment === '..');
|
|
11
|
+
/**
|
|
12
|
+
* Whether a path is absolute on either host: a POSIX root, a Windows drive
|
|
13
|
+
* (`C:\`, `C:/`) or a UNC share. Checked on every host, so a client.json
|
|
14
|
+
* written on Windows is rejected the same way on Linux.
|
|
15
|
+
*/
|
|
16
|
+
export const isAbsolutePath = (path) => isPosixAbsolute(path.replaceAll('\\', '/')) || isWindowsAbsolute(path);
|
|
17
|
+
/**
|
|
18
|
+
* A Windows drive path (`C:\`, `C:/`) or a UNC path (`\\server\share`):
|
|
19
|
+
* the two absolute forms that can never be relative to `basePath`. A bare
|
|
20
|
+
* leading `/` is not one — it is an anchor spelling of the workspace root.
|
|
21
|
+
*/
|
|
22
|
+
const isDriveOrUncPath = (path) => /^[A-Za-z]:[\\/]/.test(path) || path.startsWith('\\\\');
|
|
23
|
+
/**
|
|
24
|
+
* Whether `path` is spelled from the workspace root — `@/`, `./`, a bare
|
|
25
|
+
* leading `/`, or their Windows forms. An artifact path, never a bare
|
|
26
|
+
* module specifier such as `zod` or `@tanstack/query`.
|
|
27
|
+
*/
|
|
28
|
+
export const hasWorkspaceAnchor = (path) => /^(@[\\/]|\.[\\/]|[\\/])/.test(path);
|
|
29
|
+
/**
|
|
30
|
+
* Whether `path` can name a file below `basePath`: not a Windows drive or
|
|
31
|
+
* UNC path, no `..` segment, and not `basePath` itself. The non-throwing
|
|
32
|
+
* form of {@link normalizeWorkspacePath}'s checks, for schema validation
|
|
33
|
+
* and for comparing a module specifier against a file path.
|
|
34
|
+
*/
|
|
35
|
+
export const isValidWorkspacePath = (path) => !isDriveOrUncPath(path) && !hasParentSegment(path) && toBody(path) !== '';
|
|
36
|
+
/**
|
|
37
|
+
* The path relative to `basePath`, normalized and with no anchor:
|
|
38
|
+
* what {@link normalizeWorkspacePath} writes after `@/`, and what
|
|
39
|
+
* {@link toResolvedArtifactPath} joins onto `basePath`.
|
|
40
|
+
*
|
|
41
|
+
* Throws when the path cannot name a file below `basePath`: a Windows
|
|
42
|
+
* drive or UNC path, a `..` segment (checked as a whole segment before
|
|
43
|
+
* normalization, so it is never resolved), or a path naming `basePath`
|
|
44
|
+
* itself (`@/`, `@`, `./`, `.`, `/`, ``).
|
|
45
|
+
*/
|
|
46
|
+
export const toNormalizedWorkspacePath = (path, { generatorId } = {}) => {
|
|
47
|
+
const reject = (reason) => {
|
|
48
|
+
const source = generatorId ? ` returned by generator '${generatorId}'` : '';
|
|
49
|
+
throw new Error(`Path '${path}'${source} ${reason}`);
|
|
50
|
+
};
|
|
51
|
+
if (isDriveOrUncPath(path)) {
|
|
52
|
+
return reject('is a Windows drive or UNC path; a workspace path is relative to basePath');
|
|
53
|
+
}
|
|
54
|
+
if (hasParentSegment(path)) {
|
|
55
|
+
return reject('contains a ".." segment; a workspace path is a forward path below basePath');
|
|
56
|
+
}
|
|
57
|
+
const body = toBody(path);
|
|
58
|
+
if (body === '') {
|
|
59
|
+
return reject('names basePath itself; a workspace path names a file below it');
|
|
60
|
+
}
|
|
61
|
+
return body;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The one spelling of a workspace path — an export path or a destination
|
|
65
|
+
* path: `@/` followed by a POSIX path relative to `basePath`.
|
|
66
|
+
*
|
|
67
|
+
* A workspace path is a logical path inside the workspace, never a
|
|
68
|
+
* filesystem path, so it reads the same on every host. A generator may
|
|
69
|
+
* return one as `@/types/User.ts`, `./types/User.ts`, `/types/User.ts`,
|
|
70
|
+
* `types/User.ts`, or with Windows separators; the engine stores this form
|
|
71
|
+
* and nothing else, so file-map keys, import modules and the ejected lookup
|
|
72
|
+
* always agree. The result is a fixed point.
|
|
73
|
+
*
|
|
74
|
+
* Throws in the cases {@link toNormalizedWorkspacePath} throws.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* normalizeWorkspacePath('@\\types\\User.ts') // '@/types/User.ts'
|
|
79
|
+
* normalizeWorkspacePath('./types/User.ts') // '@/types/User.ts'
|
|
80
|
+
* normalizeWorkspacePath('../User.ts') // throws
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export const normalizeWorkspacePath = (path, options = {}) => `@/${toNormalizedWorkspacePath(path, options)}`;
|
|
84
|
+
/**
|
|
85
|
+
* Separator swap, then every anchor spelling goes (`@/`, `./`, a leading
|
|
86
|
+
* `/` — {@link toWorkspacePath}), then POSIX normalize of what is left so
|
|
87
|
+
* `@//x` and `@/./x` collapse. The anchor goes first so normalize can
|
|
88
|
+
* never fold it into a name (`@/.` is the root, not a file called `@`).
|
|
89
|
+
* The root in any spelling is the empty string.
|
|
90
|
+
*/
|
|
91
|
+
const toBody = (path) => {
|
|
92
|
+
const stripped = toWorkspacePath(path.replaceAll('\\', '/'));
|
|
93
|
+
if (stripped === '') {
|
|
94
|
+
return '';
|
|
95
|
+
}
|
|
96
|
+
const normalized = normalize(stripped);
|
|
97
|
+
return normalized === '.' ? '' : normalized;
|
|
98
|
+
};
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* Resolves an artifact's destination path onto `basePath`.
|
|
3
3
|
*
|
|
4
4
|
* `destinationPath` is a workspace path in any spelling
|
|
5
|
-
* ({@link
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* ({@link toNormalizedWorkspacePath}) — `@/models/User.ts` as a generator
|
|
6
|
+
* wrote it, `./models/User.ts`, or with Windows separators — and is always
|
|
7
|
+
* joined onto `basePath` with forward slashes, so the artifact key reads
|
|
8
|
+
* the same on every host. A `..` segment or an absolute path is refused:
|
|
9
|
+
* every artifact lands below `basePath`, whoever writes it.
|
|
8
10
|
*
|
|
9
11
|
* @module toResolvedArtifactPath
|
|
10
12
|
*/
|
|
@@ -22,8 +24,9 @@ type ToResolvedArtifactPathArgs = {
|
|
|
22
24
|
destinationPath: string;
|
|
23
25
|
};
|
|
24
26
|
/**
|
|
25
|
-
* Joins `destinationPath` (canonicalized) onto `basePath`, or onto
|
|
26
|
-
* `basePath` is undefined.
|
|
27
|
+
* Joins `destinationPath` (canonicalized) onto `basePath`, or onto the
|
|
28
|
+
* workspace root when `basePath` is undefined. Throws when
|
|
29
|
+
* `destinationPath` cannot name a file below `basePath`.
|
|
27
30
|
*
|
|
28
31
|
* @example
|
|
29
32
|
* ```typescript
|
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
* Resolves an artifact's destination path onto `basePath`.
|
|
3
3
|
*
|
|
4
4
|
* `destinationPath` is a workspace path in any spelling
|
|
5
|
-
* ({@link
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* ({@link toNormalizedWorkspacePath}) — `@/models/User.ts` as a generator
|
|
6
|
+
* wrote it, `./models/User.ts`, or with Windows separators — and is always
|
|
7
|
+
* joined onto `basePath` with forward slashes, so the artifact key reads
|
|
8
|
+
* the same on every host. A `..` segment or an absolute path is refused:
|
|
9
|
+
* every artifact lands below `basePath`, whoever writes it.
|
|
8
10
|
*
|
|
9
11
|
* @module toResolvedArtifactPath
|
|
10
12
|
*/
|
|
11
13
|
import "../_dnt.polyfills.js";
|
|
12
|
-
import { join } from '../deps/jsr.io/@std/path/1.1.6/join.js';
|
|
14
|
+
import { join } from '../deps/jsr.io/@std/path/1.1.6/posix/join.js';
|
|
15
|
+
import { toNormalizedWorkspacePath } from './normalizeWorkspacePath.js';
|
|
13
16
|
import { toWorkspacePath } from './toWorkspacePath.js';
|
|
14
17
|
/**
|
|
15
|
-
* Joins `destinationPath` (canonicalized) onto `basePath`, or onto
|
|
16
|
-
* `basePath` is undefined.
|
|
18
|
+
* Joins `destinationPath` (canonicalized) onto `basePath`, or onto the
|
|
19
|
+
* workspace root when `basePath` is undefined. Throws when
|
|
20
|
+
* `destinationPath` cannot name a file below `basePath`.
|
|
17
21
|
*
|
|
18
22
|
* @example
|
|
19
23
|
* ```typescript
|
|
@@ -24,5 +28,5 @@ import { toWorkspacePath } from './toWorkspacePath.js';
|
|
|
24
28
|
* ```
|
|
25
29
|
*/
|
|
26
30
|
export const toResolvedArtifactPath = ({ basePath, destinationPath }) => {
|
|
27
|
-
return join(basePath ?? '
|
|
31
|
+
return join(toWorkspacePath(basePath ?? ''), toNormalizedWorkspacePath(destinationPath));
|
|
28
32
|
};
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* config and examples write it as `./`, and std `normalize` — applied to
|
|
8
8
|
* `File.path` by the drivers — strips `./` but leaves `@/` alone. Anything
|
|
9
9
|
* that compares paths from more than one of those sources (package matching,
|
|
10
|
-
* on-disk resolution) must see all spellings as equal: every leading
|
|
11
|
-
* `./` goes, a trailing `/` goes, a Windows `\` is a `/`, and the
|
|
12
|
-
* root itself (`@/`, `./`, `.`, ``) is the empty string. The result is a fixed
|
|
10
|
+
* on-disk resolution) must see all spellings as equal: every leading `@/`,
|
|
11
|
+
* `./` or bare `/` goes, a trailing `/` goes, a Windows `\` is a `/`, and the
|
|
12
|
+
* workspace root itself (`@/`, `@`, `./`, `.`, `/`, ``) is the empty string. The result is a fixed
|
|
13
13
|
* point: canonicalizing it again changes nothing.
|
|
14
14
|
*
|
|
15
15
|
* The `@/` stripped here is Skmtc's **workspace root** — the prefix
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* config and examples write it as `./`, and std `normalize` — applied to
|
|
8
8
|
* `File.path` by the drivers — strips `./` but leaves `@/` alone. Anything
|
|
9
9
|
* that compares paths from more than one of those sources (package matching,
|
|
10
|
-
* on-disk resolution) must see all spellings as equal: every leading
|
|
11
|
-
* `./` goes, a trailing `/` goes, a Windows `\` is a `/`, and the
|
|
12
|
-
* root itself (`@/`, `./`, `.`, ``) is the empty string. The result is a fixed
|
|
10
|
+
* on-disk resolution) must see all spellings as equal: every leading `@/`,
|
|
11
|
+
* `./` or bare `/` goes, a trailing `/` goes, a Windows `\` is a `/`, and the
|
|
12
|
+
* workspace root itself (`@/`, `@`, `./`, `.`, `/`, ``) is the empty string. The result is a fixed
|
|
13
13
|
* point: canonicalizing it again changes nothing.
|
|
14
14
|
*
|
|
15
15
|
* The `@/` stripped here is Skmtc's **workspace root** — the prefix
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
export const toWorkspacePath = (path) => {
|
|
30
30
|
const withoutAnchor = path
|
|
31
31
|
.replaceAll('\\', '/')
|
|
32
|
-
.replace(/^(
|
|
32
|
+
.replace(/^(?:@\/|\.\/|\/)+/, '')
|
|
33
33
|
.replace(/\/+$/, '');
|
|
34
|
-
return withoutAnchor === '.' ? '' : withoutAnchor;
|
|
34
|
+
return withoutAnchor === '.' || withoutAnchor === '@' ? '' : withoutAnchor;
|
|
35
35
|
};
|
|
36
36
|
/**
|
|
37
37
|
* `path` is `rootPath` itself or a file or folder below it. A root is a
|
package/esm/mod.d.ts
CHANGED
|
@@ -118,6 +118,7 @@ export * from './helpers/strings.js';
|
|
|
118
118
|
export * from './helpers/parseModuleName.js';
|
|
119
119
|
export * from './helpers/toResolvedArtifactPath.js';
|
|
120
120
|
export * from './helpers/toWorkspacePath.js';
|
|
121
|
+
export * from './helpers/normalizeWorkspacePath.js';
|
|
121
122
|
export * from './helpers/matchPackage.js';
|
|
122
123
|
export * from './helpers/withVariant.js';
|
|
123
124
|
export * from './helpers/toVariantList.js';
|
package/esm/mod.js
CHANGED
|
@@ -118,6 +118,7 @@ export * from './helpers/strings.js';
|
|
|
118
118
|
export * from './helpers/parseModuleName.js';
|
|
119
119
|
export * from './helpers/toResolvedArtifactPath.js';
|
|
120
120
|
export * from './helpers/toWorkspacePath.js';
|
|
121
|
+
export * from './helpers/normalizeWorkspacePath.js';
|
|
121
122
|
export * from './helpers/matchPackage.js';
|
|
122
123
|
export * from './helpers/withVariant.js';
|
|
123
124
|
export * from './helpers/toVariantList.js';
|
package/esm/types/Settings.js
CHANGED
|
@@ -52,13 +52,8 @@ import "../_dnt.polyfills.js";
|
|
|
52
52
|
import { generatorEnrichments } from './Enrichments.js';
|
|
53
53
|
import * as v from 'valibot';
|
|
54
54
|
import { method } from './Method.js';
|
|
55
|
+
import { hasParentSegment, isAbsolutePath, isValidWorkspacePath } from '../helpers/normalizeWorkspacePath.js';
|
|
55
56
|
import { toWorkspacePath } from '../helpers/toWorkspacePath.js';
|
|
56
|
-
/**
|
|
57
|
-
* Whether a relative path contains a `..` parent-reference segment.
|
|
58
|
-
* `..` is a parent reference only as a whole path segment — a
|
|
59
|
-
* directory name that merely contains dots is not flagged.
|
|
60
|
-
*/
|
|
61
|
-
const hasParentSegment = (path) => path.split(/[/\\]/).some(segment => segment === '..');
|
|
62
57
|
/**
|
|
63
58
|
* Valibot schema for {@link ModulePackage}.
|
|
64
59
|
*
|
|
@@ -175,7 +170,9 @@ export const anchorsSettings = v.object({
|
|
|
175
170
|
out: v.optional(v.string())
|
|
176
171
|
});
|
|
177
172
|
export const clientSettings = v.object({
|
|
178
|
-
basePath: v.optional(v.string()),
|
|
173
|
+
basePath: v.optional(v.pipe(v.string(), v.check(basePath => !isAbsolutePath(basePath), 'basePath must be relative to the SKMTC root (the directory containing .skmtc/); ' +
|
|
174
|
+
'absolute paths are not supported because generated output is always written under it'), v.check(basePath => !hasParentSegment(basePath), 'basePath must be a forward path with no ".." segments — it is the on-disk anchor ' +
|
|
175
|
+
'every generated file sits below'))),
|
|
179
176
|
schemaSource: v.optional(v.string()),
|
|
180
177
|
packages: v.optional(modulePackages),
|
|
181
178
|
enrichments: v.optional(generatorEnrichments),
|
|
@@ -185,7 +182,8 @@ export const clientSettings = v.object({
|
|
|
185
182
|
inputDirs: v.optional(v.array(v.string())),
|
|
186
183
|
formatter: v.optional(v.string()),
|
|
187
184
|
generatedSuffix: v.optional(v.string()),
|
|
188
|
-
ejected: v.optional(v.array(v.string()
|
|
185
|
+
ejected: v.optional(v.array(v.pipe(v.string(), v.check(isValidWorkspacePath, 'settings.ejected entries are export paths: a forward path below basePath, ' +
|
|
186
|
+
'with no ".." segment and not a Windows drive or UNC path'))))
|
|
189
187
|
});
|
|
190
188
|
/**
|
|
191
189
|
* Valibot schema for validating SKMTC client configuration.
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
16
16
|
var _GenerateContext_instances, _GenerateContext_files, _GenerateContext_previews, _GenerateContext_captureChannel, _GenerateContext_enrichmentAudit, _GenerateContext_reportSkippedEnrichment, _GenerateContext_schemaRefNames, _GenerateContext_subjectDefaults, _GenerateContext_runOasOperationGenerator, _GenerateContext_runWebhookGenerator, _GenerateContext_runGqlOperationGenerator, _GenerateContext_runModelGenerator, _GenerateContext_addPreview, _GenerateContext_toContentSettingsExportPath, _GenerateContext_ejectedBySuffixedPath_get, _GenerateContext_ejectedBySuffixedPathCache, _GenerateContext_findContainer, _GenerateContext_toContainer;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.toModelSource = exports.toGqlOperationSource = exports.toWebhookSource = exports.toOasOperationSource = exports.GenerateContext = void 0;
|
|
19
|
-
const
|
|
19
|
+
const normalizeWorkspacePath_js_1 = require("../helpers/normalizeWorkspacePath.js");
|
|
20
20
|
const applyGeneratedSuffix_js_1 = require("../helpers/applyGeneratedSuffix.js");
|
|
21
21
|
const OasOperationDriver_js_1 = require("../dsl/operation/oas/OasOperationDriver.js");
|
|
22
22
|
const WebhookDriver_js_1 = require("../dsl/webhook/WebhookDriver.js");
|
|
@@ -449,7 +449,7 @@ class GenerateContext {
|
|
|
449
449
|
* language-constructed file, use {@link addFile}.
|
|
450
450
|
*/
|
|
451
451
|
getFile(filePath) {
|
|
452
|
-
return __classPrivateFieldGet(this, _GenerateContext_files, "f").get((0,
|
|
452
|
+
return __classPrivateFieldGet(this, _GenerateContext_files, "f").get((0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(filePath));
|
|
453
453
|
}
|
|
454
454
|
/**
|
|
455
455
|
* Read-only view of every file generated so far, keyed by (normalized)
|
|
@@ -473,7 +473,7 @@ class GenerateContext {
|
|
|
473
473
|
* (`context.getFile(path) ?? context.addFile(new KtFile({ … }))`).
|
|
474
474
|
*/
|
|
475
475
|
addFile(file) {
|
|
476
|
-
const normalizedPath = (0,
|
|
476
|
+
const normalizedPath = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(file.path);
|
|
477
477
|
if (__classPrivateFieldGet(this, _GenerateContext_files, "f").has(normalizedPath)) {
|
|
478
478
|
throw new Error(`File already exists: ${normalizedPath}`);
|
|
479
479
|
}
|
|
@@ -487,7 +487,7 @@ class GenerateContext {
|
|
|
487
487
|
* @param args - Registration arguments with destination path and JSON content
|
|
488
488
|
*/
|
|
489
489
|
registerJson({ destinationPath, json }) {
|
|
490
|
-
const normalizedPath = (0,
|
|
490
|
+
const normalizedPath = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(destinationPath);
|
|
491
491
|
let currentFile = this.getFile(normalizedPath);
|
|
492
492
|
if (!currentFile) {
|
|
493
493
|
currentFile = new JsonFile_js_1.JsonFile({ path: normalizedPath, content: {} });
|
|
@@ -506,7 +506,7 @@ class GenerateContext {
|
|
|
506
506
|
* @experimental This method is experimental and may change in future versions
|
|
507
507
|
*/
|
|
508
508
|
registerMarkdown({ destinationPath, markdown }) {
|
|
509
|
-
const normalizedPath = (0,
|
|
509
|
+
const normalizedPath = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(destinationPath);
|
|
510
510
|
let currentFile = this.getFile(normalizedPath);
|
|
511
511
|
if (!currentFile) {
|
|
512
512
|
currentFile = new MarkdownFile_js_1.MarkdownFile({ path: normalizedPath, content: '' });
|
|
@@ -527,7 +527,7 @@ class GenerateContext {
|
|
|
527
527
|
* @mutates this.files
|
|
528
528
|
*/
|
|
529
529
|
register({ imports = [], reExports = [], definitions, custom, destinationPath, into }) {
|
|
530
|
-
const normalizedPath = (0,
|
|
530
|
+
const normalizedPath = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(destinationPath);
|
|
531
531
|
const currentFile = this.getFile(normalizedPath);
|
|
532
532
|
// `register` never creates files — it speaks pure data and the engine
|
|
533
533
|
// never names a file class. Callers pre-create the destination file
|
|
@@ -635,7 +635,7 @@ class GenerateContext {
|
|
|
635
635
|
// the use site (same ephemeral read the Drivers make) — pre-creates
|
|
636
636
|
// the destination file caller-side, and stores via the pure-data
|
|
637
637
|
// `register`.
|
|
638
|
-
const normalizedPath = (0,
|
|
638
|
+
const normalizedPath = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(destinationPath);
|
|
639
639
|
if (!this.getFile(normalizedPath)) {
|
|
640
640
|
this.addFile(projection.lang.createFile({ path: normalizedPath, settings: this.settings }));
|
|
641
641
|
}
|
|
@@ -702,7 +702,7 @@ class GenerateContext {
|
|
|
702
702
|
enrichments,
|
|
703
703
|
variant,
|
|
704
704
|
options
|
|
705
|
-
})),
|
|
705
|
+
}), args.projection.id),
|
|
706
706
|
enrichments,
|
|
707
707
|
variant
|
|
708
708
|
});
|
|
@@ -730,7 +730,7 @@ class GenerateContext {
|
|
|
730
730
|
enrichments,
|
|
731
731
|
variant,
|
|
732
732
|
options
|
|
733
|
-
})),
|
|
733
|
+
}), args.projection.id),
|
|
734
734
|
enrichments,
|
|
735
735
|
variant
|
|
736
736
|
});
|
|
@@ -763,7 +763,7 @@ class GenerateContext {
|
|
|
763
763
|
enrichments,
|
|
764
764
|
variant,
|
|
765
765
|
options
|
|
766
|
-
})),
|
|
766
|
+
}), args.projection.id),
|
|
767
767
|
enrichments,
|
|
768
768
|
variant
|
|
769
769
|
});
|
|
@@ -785,7 +785,7 @@ class GenerateContext {
|
|
|
785
785
|
name: projection.toIdentifierName({ refName, enrichments, variant, options }),
|
|
786
786
|
...projection.toIdentifierType(refName, this)
|
|
787
787
|
}),
|
|
788
|
-
exportPath: __classPrivateFieldGet(this, _GenerateContext_instances, "m", _GenerateContext_toContentSettingsExportPath).call(this, projection.toExportPath({ refName, enrichments, variant, options })),
|
|
788
|
+
exportPath: __classPrivateFieldGet(this, _GenerateContext_instances, "m", _GenerateContext_toContentSettingsExportPath).call(this, projection.toExportPath({ refName, enrichments, variant, options }), projection.id),
|
|
789
789
|
enrichments,
|
|
790
790
|
variant
|
|
791
791
|
});
|
|
@@ -1172,15 +1172,15 @@ _GenerateContext_files = new WeakMap(), _GenerateContext_previews = new WeakMap(
|
|
|
1172
1172
|
module: { ...module, exportPath: __classPrivateFieldGet(this, _GenerateContext_instances, "m", _GenerateContext_toContentSettingsExportPath).call(this, module.exportPath) },
|
|
1173
1173
|
source
|
|
1174
1174
|
};
|
|
1175
|
-
}, _GenerateContext_toContentSettingsExportPath = function _GenerateContext_toContentSettingsExportPath(exportPath) {
|
|
1176
|
-
const suffixed = (0, applyGeneratedSuffix_js_1.applyGeneratedSuffix)(exportPath, this.settings?.generatedSuffix ?? applyGeneratedSuffix_js_1.DEFAULT_GENERATED_SUFFIX);
|
|
1177
|
-
return __classPrivateFieldGet(this, _GenerateContext_instances, "a", _GenerateContext_ejectedBySuffixedPath_get).get(
|
|
1175
|
+
}, _GenerateContext_toContentSettingsExportPath = function _GenerateContext_toContentSettingsExportPath(exportPath, generatorId) {
|
|
1176
|
+
const suffixed = (0, applyGeneratedSuffix_js_1.applyGeneratedSuffix)((0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(exportPath, { generatorId }), this.settings?.generatedSuffix ?? applyGeneratedSuffix_js_1.DEFAULT_GENERATED_SUFFIX);
|
|
1177
|
+
return __classPrivateFieldGet(this, _GenerateContext_instances, "a", _GenerateContext_ejectedBySuffixedPath_get).get(suffixed) ?? suffixed;
|
|
1178
1178
|
}, _GenerateContext_ejectedBySuffixedPath_get = function _GenerateContext_ejectedBySuffixedPath_get() {
|
|
1179
1179
|
if (__classPrivateFieldGet(this, _GenerateContext_ejectedBySuffixedPathCache, "f") === undefined) {
|
|
1180
1180
|
const suffix = this.settings?.generatedSuffix ?? applyGeneratedSuffix_js_1.DEFAULT_GENERATED_SUFFIX;
|
|
1181
1181
|
__classPrivateFieldSet(this, _GenerateContext_ejectedBySuffixedPathCache, new Map((this.settings?.ejected ?? []).map(ejectedPath => {
|
|
1182
|
-
const normalized = (0,
|
|
1183
|
-
return [(0,
|
|
1182
|
+
const normalized = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(ejectedPath);
|
|
1183
|
+
return [(0, applyGeneratedSuffix_js_1.applyGeneratedSuffix)(normalized, suffix), normalized];
|
|
1184
1184
|
})), "f");
|
|
1185
1185
|
}
|
|
1186
1186
|
return __classPrivateFieldGet(this, _GenerateContext_ejectedBySuffixedPathCache, "f");
|
|
@@ -130,13 +130,13 @@ export declare class RenderContext {
|
|
|
130
130
|
*/
|
|
131
131
|
collate(stackTrail: StackTrail): FilesRenderResult;
|
|
132
132
|
/**
|
|
133
|
-
* Retrieves a file from the context by its
|
|
133
|
+
* Retrieves a file from the context by its export path.
|
|
134
134
|
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* exists
|
|
135
|
+
* The path is canonicalized first ({@link normalizeWorkspacePath}), so any
|
|
136
|
+
* spelling of the same export path finds the same file. Throws when no
|
|
137
|
+
* file exists at that path.
|
|
138
138
|
*
|
|
139
|
-
* @param filePath - The
|
|
139
|
+
* @param filePath - The export path to retrieve, in any spelling
|
|
140
140
|
* @returns The File or JsonFile instance
|
|
141
141
|
* @throws {Error} When the file is not found in the context
|
|
142
142
|
*
|
|
@@ -145,9 +145,9 @@ export declare class RenderContext {
|
|
|
145
145
|
* const file = renderContext.getFile('./src/models/User.ts');
|
|
146
146
|
* console.log(file.toString()); // Access file content
|
|
147
147
|
*
|
|
148
|
-
* //
|
|
148
|
+
* // Every spelling of the same export path finds the same file
|
|
149
149
|
* const sameFile = renderContext.getFile('src/models/User.ts');
|
|
150
|
-
* const alsoSameFile = renderContext.getFile('
|
|
150
|
+
* const alsoSameFile = renderContext.getFile('@/src/models/User.ts');
|
|
151
151
|
* ```
|
|
152
152
|
*/
|
|
153
153
|
getFile(filePath: string): FileBase;
|
|
@@ -17,7 +17,7 @@ var _RenderContext_captureChannel, _RenderContext_sink, _RenderContext_captures;
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.RenderContext = void 0;
|
|
19
19
|
const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
|
|
20
|
-
const
|
|
20
|
+
const normalizeWorkspacePath_js_1 = require("../helpers/normalizeWorkspacePath.js");
|
|
21
21
|
const toResolvedArtifactPath_js_1 = require("../helpers/toResolvedArtifactPath.js");
|
|
22
22
|
const CodeFileBase_js_1 = require("../dsl/CodeFileBase.js");
|
|
23
23
|
const CaptureSink_js_1 = require("../anchors/CaptureSink.js");
|
|
@@ -174,8 +174,9 @@ class RenderContext {
|
|
|
174
174
|
__classPrivateFieldSet(this, _RenderContext_sink, undefined, "f");
|
|
175
175
|
}
|
|
176
176
|
// Build one sidecar per captured File from the spans the sink
|
|
177
|
-
// resolved (no re-render, no `toString`). Keyed by
|
|
178
|
-
// matching the
|
|
177
|
+
// resolved (no re-render, no `toString`). Keyed by the resolved artifact
|
|
178
|
+
// path, matching `artifacts` and the manifest, so a sidecar sits at
|
|
179
|
+
// `<outDir>/<artifact key>.skm.json` where doctor looks for it.
|
|
179
180
|
const { parser, schemaSrc, generatorMeta } = postPassConfig;
|
|
180
181
|
const sidecars = {};
|
|
181
182
|
const generationMap = [];
|
|
@@ -188,7 +189,11 @@ class RenderContext {
|
|
|
188
189
|
parser,
|
|
189
190
|
generatorMeta
|
|
190
191
|
});
|
|
191
|
-
|
|
192
|
+
const artifactPath = (0, toResolvedArtifactPath_js_1.toResolvedArtifactPath)({
|
|
193
|
+
basePath: this.basePath,
|
|
194
|
+
destinationPath: capture.destinationPath
|
|
195
|
+
});
|
|
196
|
+
sidecars[artifactPath] = sidecar;
|
|
192
197
|
generationMap.push(...(0, generationMap_js_1.entriesForSidecar)(sidecar));
|
|
193
198
|
}
|
|
194
199
|
__classPrivateFieldSet(this, _RenderContext_captures, [], "f");
|
|
@@ -276,13 +281,13 @@ class RenderContext {
|
|
|
276
281
|
return output;
|
|
277
282
|
}
|
|
278
283
|
/**
|
|
279
|
-
* Retrieves a file from the context by its
|
|
284
|
+
* Retrieves a file from the context by its export path.
|
|
280
285
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* exists
|
|
286
|
+
* The path is canonicalized first ({@link normalizeWorkspacePath}), so any
|
|
287
|
+
* spelling of the same export path finds the same file. Throws when no
|
|
288
|
+
* file exists at that path.
|
|
284
289
|
*
|
|
285
|
-
* @param filePath - The
|
|
290
|
+
* @param filePath - The export path to retrieve, in any spelling
|
|
286
291
|
* @returns The File or JsonFile instance
|
|
287
292
|
* @throws {Error} When the file is not found in the context
|
|
288
293
|
*
|
|
@@ -291,13 +296,13 @@ class RenderContext {
|
|
|
291
296
|
* const file = renderContext.getFile('./src/models/User.ts');
|
|
292
297
|
* console.log(file.toString()); // Access file content
|
|
293
298
|
*
|
|
294
|
-
* //
|
|
299
|
+
* // Every spelling of the same export path finds the same file
|
|
295
300
|
* const sameFile = renderContext.getFile('src/models/User.ts');
|
|
296
|
-
* const alsoSameFile = renderContext.getFile('
|
|
301
|
+
* const alsoSameFile = renderContext.getFile('@/src/models/User.ts');
|
|
297
302
|
* ```
|
|
298
303
|
*/
|
|
299
304
|
getFile(filePath) {
|
|
300
|
-
const normalizedPath = (0,
|
|
305
|
+
const normalizedPath = (0, normalizeWorkspacePath_js_1.normalizeWorkspacePath)(filePath);
|
|
301
306
|
const currentFile = this.files.get(normalizedPath);
|
|
302
307
|
(0, tiny_invariant_1.default)(currentFile, `File not found during render phase: ${normalizedPath}`);
|
|
303
308
|
return currentFile;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verifies whether provided path is absolute.
|
|
3
|
+
*
|
|
4
|
+
* @example Usage
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { isAbsolute } from "@std/path/posix/is-absolute";
|
|
7
|
+
* import { assert, assertFalse } from "@std/assert";
|
|
8
|
+
*
|
|
9
|
+
* assert(isAbsolute("/home/user/Documents/"));
|
|
10
|
+
* assertFalse(isAbsolute("home/user/Documents/"));
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @param path The path to verify.
|
|
14
|
+
* @returns Whether the path is absolute.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isAbsolute(path: string): boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
3
|
+
// This module is browser compatible.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.isAbsolute = isAbsolute;
|
|
6
|
+
const assert_path_js_1 = require("../_common/assert_path.js");
|
|
7
|
+
const _util_js_1 = require("./_util.js");
|
|
8
|
+
/**
|
|
9
|
+
* Verifies whether provided path is absolute.
|
|
10
|
+
*
|
|
11
|
+
* @example Usage
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { isAbsolute } from "@std/path/posix/is-absolute";
|
|
14
|
+
* import { assert, assertFalse } from "@std/assert";
|
|
15
|
+
*
|
|
16
|
+
* assert(isAbsolute("/home/user/Documents/"));
|
|
17
|
+
* assertFalse(isAbsolute("home/user/Documents/"));
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @param path The path to verify.
|
|
21
|
+
* @returns Whether the path is absolute.
|
|
22
|
+
*/
|
|
23
|
+
function isAbsolute(path) {
|
|
24
|
+
(0, assert_path_js_1.assertPath)(path);
|
|
25
|
+
return path.length > 0 && (0, _util_js_1.isPosixPathSeparator)(path.charCodeAt(0));
|
|
26
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verifies whether provided path is absolute.
|
|
3
|
+
*
|
|
4
|
+
* @example Usage
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { isAbsolute } from "@std/path/windows/is-absolute";
|
|
7
|
+
* import { assert, assertFalse } from "@std/assert";
|
|
8
|
+
*
|
|
9
|
+
* assert(isAbsolute("C:\\foo\\bar"));
|
|
10
|
+
* assertFalse(isAbsolute("..\\baz"));
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @param path The path to verify.
|
|
14
|
+
* @returns `true` if the path is absolute, `false` otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isAbsolute(path: string): boolean;
|