@williamthorsen/release-kit 10.8.0 → 10.9.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/.meta/changelog.json +43 -3
- package/.readyup/kits/default.js +3 -3
- package/.readyup/kits/npm-auto-publish.js +1 -1
- package/.readyup/manifest.json +9 -9
- package/CHANGELOG.md +34 -3
- package/README.md +25 -9
- package/dist/esm/bin/release-kit.js +20 -102
- package/dist/esm/createGithubReleaseCommand.d.ts +2 -1
- package/dist/esm/createGithubReleaseCommand.js +4 -2
- package/dist/esm/createTags.d.ts +2 -0
- package/dist/esm/createTags.js +5 -4
- package/dist/esm/format.d.ts +5 -5
- package/dist/esm/format.js +5 -4
- package/dist/esm/glyphs.d.ts +3 -0
- package/dist/esm/glyphs.js +6 -0
- package/dist/esm/init/initCommand.d.ts +3 -1
- package/dist/esm/init/initCommand.js +15 -15
- package/dist/esm/loadValidatedConfig.d.ts +2 -1
- package/dist/esm/loadValidatedConfig.js +3 -3
- package/dist/esm/prepareCommand.d.ts +2 -1
- package/dist/esm/prepareCommand.js +17 -16
- package/dist/esm/publishCommand.d.ts +2 -1
- package/dist/esm/publishCommand.js +2 -2
- package/dist/esm/reportPrepare.d.ts +2 -0
- package/dist/esm/reportPrepare.js +44 -38
- package/dist/esm/resolveReleaseNotesConfig.d.ts +2 -1
- package/dist/esm/resolveReleaseNotesConfig.js +4 -4
- package/dist/esm/resolveStylesOrExit.d.ts +10 -0
- package/dist/esm/resolveStylesOrExit.js +10 -0
- package/dist/esm/showTagPrefixesCommand.d.ts +2 -1
- package/dist/esm/showTagPrefixesCommand.js +16 -10
- package/dist/esm/sync-labels/generateCommand.d.ts +4 -2
- package/dist/esm/sync-labels/generateCommand.js +4 -4
- package/dist/esm/sync-labels/initCommand.d.ts +3 -1
- package/dist/esm/sync-labels/initCommand.js +7 -7
- package/dist/esm/tagCommand.d.ts +2 -1
- package/dist/esm/tagCommand.js +2 -2
- package/dist/esm/validateOverridesCommand.d.ts +4 -4
- package/dist/esm/validateOverridesCommand.js +6 -6
- package/docs/configuration.md +23 -1
- package/docs/work-types.md +11 -8
- package/package.json +11 -11
- package/presets/labels/common.yaml +2 -2
- package/dist/esm/checkWorkTypesDrift.d.ts +0 -35
- package/dist/esm/checkWorkTypesDrift.js +0 -117
- package/dist/esm/syncWorkTypes.d.ts +0 -28
- package/dist/esm/syncWorkTypes.js +0 -94
- package/dist/esm/work-types.json +0 -149
- package/dist/esm/work-types.schema.json +0 -110
- package/dist/esm/workTypesUtils.d.ts +0 -22
- package/dist/esm/workTypesUtils.js +0 -16
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { dirname, resolve } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { formatErrorLine } from '@williamthorsen/nmr-core';
|
|
5
|
-
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
6
|
-
import { UPSTREAM_WORK_TYPES_URL } from "./checkWorkTypesDrift.js";
|
|
7
|
-
import { isRecord } from "./typeGuards.js";
|
|
8
|
-
import { buildFetchInit, hasExpectedTopLevelShape } from "./workTypesUtils.js";
|
|
9
|
-
function resolveDefaultLocalPath() {
|
|
10
|
-
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
11
|
-
return resolve(moduleDir, 'work-types.json');
|
|
12
|
-
}
|
|
13
|
-
function extractLocalSchemaUrl(content) {
|
|
14
|
-
let parsed;
|
|
15
|
-
try {
|
|
16
|
-
parsed = JSON.parse(content);
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
if (!isRecord(parsed)) {
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
const schema = parsed['$schema'];
|
|
25
|
-
return typeof schema === 'string' ? schema : undefined;
|
|
26
|
-
}
|
|
27
|
-
export async function syncWorkTypes(dependencies = {}) {
|
|
28
|
-
const localPath = dependencies.localPath ?? resolveDefaultLocalPath();
|
|
29
|
-
const fetcher = dependencies.fetch ?? globalThis.fetch;
|
|
30
|
-
const url = dependencies.upstreamUrl ?? UPSTREAM_WORK_TYPES_URL;
|
|
31
|
-
const fetchInit = buildFetchInit();
|
|
32
|
-
let response;
|
|
33
|
-
try {
|
|
34
|
-
response = fetchInit === undefined ? await fetcher(url) : await fetcher(url, fetchInit);
|
|
35
|
-
}
|
|
36
|
-
catch (error) {
|
|
37
|
-
return {
|
|
38
|
-
exitCode: 2,
|
|
39
|
-
message: formatErrorLine(`Failed to fetch upstream work-types.json: ${describeError(error)}`),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
if (!response.ok) {
|
|
43
|
-
return {
|
|
44
|
-
exitCode: 2,
|
|
45
|
-
message: formatErrorLine(`Failed to fetch upstream work-types.json: HTTP ${response.status} ${response.statusText}`),
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
const upstreamText = await response.text();
|
|
49
|
-
let upstreamJson;
|
|
50
|
-
try {
|
|
51
|
-
upstreamJson = JSON.parse(upstreamText);
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
return {
|
|
55
|
-
exitCode: 3,
|
|
56
|
-
message: `Upstream work-types.json is not valid JSON: ${describeError(error)}`,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
if (!hasExpectedTopLevelShape(upstreamJson)) {
|
|
60
|
-
return {
|
|
61
|
-
exitCode: 3,
|
|
62
|
-
message: 'Upstream work-types.json does not match the expected schema shape (missing `tiers` or `types`).',
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
let priorContent;
|
|
66
|
-
try {
|
|
67
|
-
priorContent = readFileSync(localPath, 'utf8');
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
priorContent = undefined;
|
|
71
|
-
}
|
|
72
|
-
const localSchemaUrl = priorContent !== undefined ? extractLocalSchemaUrl(priorContent) : undefined;
|
|
73
|
-
const outputJson = localSchemaUrl !== undefined ? { $schema: localSchemaUrl, ...upstreamJson } : upstreamJson;
|
|
74
|
-
const formatted = `${JSON.stringify(outputJson, null, 2)}\n`;
|
|
75
|
-
if (priorContent === formatted) {
|
|
76
|
-
return {
|
|
77
|
-
exitCode: 0,
|
|
78
|
-
message: `Local work-types.json already matches upstream (${localPath}).`,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
try {
|
|
82
|
-
writeFileSync(localPath, formatted, 'utf8');
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
return {
|
|
86
|
-
exitCode: 2,
|
|
87
|
-
message: formatErrorLine(`Failed to write ${localPath}: ${describeError(error)}`),
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
exitCode: 0,
|
|
92
|
-
message: `Synced work-types.json from ${url} → ${localPath}.`,
|
|
93
|
-
};
|
|
94
|
-
}
|
package/dist/esm/work-types.json
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "./work-types.schema.json",
|
|
3
|
-
"markers": {
|
|
4
|
-
"breaking": {
|
|
5
|
-
"emoji": "🚨",
|
|
6
|
-
"label": "Breaking"
|
|
7
|
-
}
|
|
8
|
-
},
|
|
9
|
-
"tiers": ["public", "internal", "process"],
|
|
10
|
-
"types": [
|
|
11
|
-
{
|
|
12
|
-
"aliases": ["feature"],
|
|
13
|
-
"breakingPolicy": "optional",
|
|
14
|
-
"description": "A change that gives consumers a new capability or extends an existing one.",
|
|
15
|
-
"emoji": "🎉",
|
|
16
|
-
"key": "feat",
|
|
17
|
-
"label": "Features",
|
|
18
|
-
"tier": "public"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"aliases": [],
|
|
22
|
-
"breakingPolicy": "required",
|
|
23
|
-
"description": "A change that removes a capability or surface on which consumers depend.",
|
|
24
|
-
"emoji": "🪦",
|
|
25
|
-
"key": "drop",
|
|
26
|
-
"label": "Removed",
|
|
27
|
-
"tier": "public"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"aliases": [],
|
|
31
|
-
"breakingPolicy": "forbidden",
|
|
32
|
-
"description": "A change that marks a capability or surface for removal while the capability or surface keeps working.",
|
|
33
|
-
"emoji": "🗑️",
|
|
34
|
-
"key": "deprecate",
|
|
35
|
-
"label": "Deprecated",
|
|
36
|
-
"tier": "public"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"aliases": ["bugfix"],
|
|
40
|
-
"breakingPolicy": "optional",
|
|
41
|
-
"description": "A change that corrects behavior that consumers meet and that differs from what was intended.",
|
|
42
|
-
"emoji": "🐛",
|
|
43
|
-
"key": "fix",
|
|
44
|
-
"label": "Bug fixes",
|
|
45
|
-
"tier": "public"
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"aliases": ["security"],
|
|
49
|
-
"breakingPolicy": "optional",
|
|
50
|
-
"description": "A change that closes a vulnerability or hardens a consumer-facing surface against attack.",
|
|
51
|
-
"emoji": "🔒",
|
|
52
|
-
"key": "sec",
|
|
53
|
-
"label": "Security",
|
|
54
|
-
"tier": "public"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"aliases": ["performance"],
|
|
58
|
-
"breakingPolicy": "optional",
|
|
59
|
-
"description": "A change that reduces the time, memory, or other resources that consumer-facing work uses, without changing its result.",
|
|
60
|
-
"emoji": "⚡",
|
|
61
|
-
"key": "perf",
|
|
62
|
-
"label": "Performance",
|
|
63
|
-
"tier": "public"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"aliases": ["utility"],
|
|
67
|
-
"breakingPolicy": "forbidden",
|
|
68
|
-
"description": "A change that adds or extends a capability that consumers do not use directly, such as a helper or an internal module.",
|
|
69
|
-
"emoji": "🏗️",
|
|
70
|
-
"key": "internal",
|
|
71
|
-
"label": "Internal features",
|
|
72
|
-
"tier": "internal"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"aliases": [],
|
|
76
|
-
"breakingPolicy": "forbidden",
|
|
77
|
-
"description": "A change that restructures existing code without changing its behavior.",
|
|
78
|
-
"emoji": "♻️",
|
|
79
|
-
"key": "refactor",
|
|
80
|
-
"label": "Refactoring",
|
|
81
|
-
"tier": "internal"
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"aliases": ["test"],
|
|
85
|
-
"breakingPolicy": "forbidden",
|
|
86
|
-
"description": "A change confined to tests, test fixtures, or test helpers, including one that unblocks a build or a type check.",
|
|
87
|
-
"emoji": "🧪",
|
|
88
|
-
"key": "tests",
|
|
89
|
-
"label": "Tests",
|
|
90
|
-
"tier": "internal"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"aliases": [],
|
|
94
|
-
"breakingPolicy": "forbidden",
|
|
95
|
-
"description": "A change to the tools used to develop the project: build, lint, formatting, and release configuration, and development scripts.",
|
|
96
|
-
"emoji": "⚙️",
|
|
97
|
-
"key": "tooling",
|
|
98
|
-
"label": "Tooling",
|
|
99
|
-
"tier": "process"
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
"aliases": [],
|
|
103
|
-
"breakingPolicy": "forbidden",
|
|
104
|
-
"description": "A change to continuous-integration workflows and their configuration.",
|
|
105
|
-
"emoji": "👷",
|
|
106
|
-
"key": "ci",
|
|
107
|
-
"label": "CI",
|
|
108
|
-
"tier": "process"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"aliases": ["dep"],
|
|
112
|
-
"breakingPolicy": "forbidden",
|
|
113
|
-
"description": "A change that adds, removes, or upgrades a dependency, including its lockfile and version-catalog entries.",
|
|
114
|
-
"emoji": "📦",
|
|
115
|
-
"key": "deps",
|
|
116
|
-
"label": "Dependencies",
|
|
117
|
-
"tier": "process"
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
"aliases": [],
|
|
121
|
-
"breakingPolicy": "forbidden",
|
|
122
|
-
"description": "A change to guidance on working in the repository itself, such as its `AGENTS.md` or a repo-local skill, or to the repository's agent configuration.",
|
|
123
|
-
"emoji": "🤖",
|
|
124
|
-
"key": "ai",
|
|
125
|
-
"label": "Agentic support",
|
|
126
|
-
"tier": "process"
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
"aliases": ["doc"],
|
|
130
|
-
"breakingPolicy": "forbidden",
|
|
131
|
-
"description": "A change to documentation for human readers, such as a README, a guide, or a code comment.",
|
|
132
|
-
"emoji": "📚",
|
|
133
|
-
"key": "docs",
|
|
134
|
-
"label": "Documentation",
|
|
135
|
-
"tier": "process"
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
"aliases": [],
|
|
139
|
-
"breakingPolicy": "forbidden",
|
|
140
|
-
"description": "A change to formatting alone, such as whitespace or line wrapping, that leaves the content unchanged.",
|
|
141
|
-
"emoji": "🎨",
|
|
142
|
-
"excludedFromChangelog": true,
|
|
143
|
-
"key": "fmt",
|
|
144
|
-
"label": "Formatting",
|
|
145
|
-
"tier": "process"
|
|
146
|
-
}
|
|
147
|
-
],
|
|
148
|
-
"version": "1.1.0"
|
|
149
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://github.com/williamthorsen/node-monorepo-tools/raw/main/packages/release-kit/src/work-types.schema.json",
|
|
4
|
-
"title": "Work types",
|
|
5
|
-
"description": "Canonical taxonomy of commit work types used by release-kit. Drives section ordering, audience classification, and the `!` (breaking) policy. The structured single-source-of-truth for everything that previously lived in `DEFAULT_WORK_TYPES` and `cliff.toml.template` group definitions.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["tiers", "types", "markers", "version"],
|
|
8
|
-
"additionalProperties": false,
|
|
9
|
-
"properties": {
|
|
10
|
-
"$schema": {
|
|
11
|
-
"type": "string",
|
|
12
|
-
"description": "Optional reference to this schema for IDE validation."
|
|
13
|
-
},
|
|
14
|
-
"version": {
|
|
15
|
-
"type": "string",
|
|
16
|
-
"description": "Semantic version of the data shape. Bumped when the structure changes in a way that breaks downstream consumers.",
|
|
17
|
-
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
|
18
|
-
},
|
|
19
|
-
"tiers": {
|
|
20
|
-
"type": "array",
|
|
21
|
-
"description": "Render tiers in canonical order. Each entry's `tier` field must reference one of these names.",
|
|
22
|
-
"items": { "type": "string", "minLength": 1 },
|
|
23
|
-
"minItems": 1,
|
|
24
|
-
"uniqueItems": true
|
|
25
|
-
},
|
|
26
|
-
"types": {
|
|
27
|
-
"type": "array",
|
|
28
|
-
"description": "Work-type entries in canonical render order (tier order, then row order within tier).",
|
|
29
|
-
"items": { "$ref": "#/definitions/workType" },
|
|
30
|
-
"minItems": 1
|
|
31
|
-
},
|
|
32
|
-
"markers": {
|
|
33
|
-
"type": "object",
|
|
34
|
-
"description": "Orthogonal section markers used by downstream renderers (PR descriptions, changelogs, release notes). Keyed by marker name; values describe the rendering inputs (emoji + label). Markers are cross-cutting — they are not tied to a specific work type.",
|
|
35
|
-
"required": ["breaking"],
|
|
36
|
-
"properties": {
|
|
37
|
-
"breaking": { "$ref": "#/definitions/marker" }
|
|
38
|
-
},
|
|
39
|
-
"additionalProperties": { "$ref": "#/definitions/marker" }
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"definitions": {
|
|
43
|
-
"marker": {
|
|
44
|
-
"type": "object",
|
|
45
|
-
"description": "Rendering inputs for a single marker. Stored as plain text; consumers apply their own formatting (e.g., bolding, prefix punctuation) at construction time.",
|
|
46
|
-
"required": ["emoji", "label"],
|
|
47
|
-
"additionalProperties": false,
|
|
48
|
-
"properties": {
|
|
49
|
-
"emoji": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"description": "Decorative emoji rendered as the prefix of the marker.",
|
|
52
|
-
"minLength": 1
|
|
53
|
-
},
|
|
54
|
-
"label": {
|
|
55
|
-
"type": "string",
|
|
56
|
-
"description": "Human-readable marker label. Plain text; consumers add their own emphasis (e.g., bold) when constructing the rendered form.",
|
|
57
|
-
"minLength": 1
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
"workType": {
|
|
62
|
-
"type": "object",
|
|
63
|
-
"required": ["tier", "key", "aliases", "emoji", "label", "breakingPolicy", "description"],
|
|
64
|
-
"additionalProperties": false,
|
|
65
|
-
"properties": {
|
|
66
|
-
"tier": {
|
|
67
|
-
"type": "string",
|
|
68
|
-
"description": "Render tier this entry belongs to. Must match one of the names in the top-level `tiers` array."
|
|
69
|
-
},
|
|
70
|
-
"key": {
|
|
71
|
-
"type": "string",
|
|
72
|
-
"description": "Canonical work-type identifier (e.g. `feat`, `fix`). Must be globally unique across all entries.",
|
|
73
|
-
"minLength": 1,
|
|
74
|
-
"pattern": "^[a-z][a-z0-9]*$"
|
|
75
|
-
},
|
|
76
|
-
"aliases": {
|
|
77
|
-
"type": "array",
|
|
78
|
-
"description": "Alternate identifiers that resolve to this work type. Must be globally unique and not collide with any `key`.",
|
|
79
|
-
"items": { "type": "string", "minLength": 1, "pattern": "^[a-z][a-z0-9]*$" },
|
|
80
|
-
"uniqueItems": true
|
|
81
|
-
},
|
|
82
|
-
"emoji": {
|
|
83
|
-
"type": "string",
|
|
84
|
-
"description": "Decorative emoji rendered as the prefix of the section heading.",
|
|
85
|
-
"minLength": 1
|
|
86
|
-
},
|
|
87
|
-
"label": {
|
|
88
|
-
"type": "string",
|
|
89
|
-
"description": "Human-readable section label (rendered as `${emoji} ${label}` in changelogs and release notes).",
|
|
90
|
-
"minLength": 1
|
|
91
|
-
},
|
|
92
|
-
"description": {
|
|
93
|
-
"type": "string",
|
|
94
|
-
"description": "The changes that the type covers, read by an agent choosing a type for a change.",
|
|
95
|
-
"minLength": 1
|
|
96
|
-
},
|
|
97
|
-
"breakingPolicy": {
|
|
98
|
-
"type": "string",
|
|
99
|
-
"description": "Policy governing the `!` (breaking) marker for this type. `forbidden`: `!` is a policy violation. `optional`: `!` is allowed. `required`: bare type is a policy violation; only the `!` form is accepted.",
|
|
100
|
-
"enum": ["forbidden", "optional", "required"]
|
|
101
|
-
},
|
|
102
|
-
"excludedFromChangelog": {
|
|
103
|
-
"type": "boolean",
|
|
104
|
-
"description": "When `true`, this type's commits never appear in any changelog or release note. Currently only `fmt` sets this. Default: `false`.",
|
|
105
|
-
"default": false
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared helpers for the work-types canonical-source tooling.
|
|
3
|
-
*
|
|
4
|
-
* Both `checkWorkTypesDrift` and `syncWorkTypes` need to validate the upstream JSON's top-level
|
|
5
|
-
* shape and render unknown errors as strings. Keeping a single copy here avoids byte-for-byte
|
|
6
|
-
* duplication between the two entry points.
|
|
7
|
-
*/
|
|
8
|
-
/** Sanity-check that the parsed upstream JSON carries the expected top-level shape. */
|
|
9
|
-
export declare function hasExpectedTopLevelShape(value: unknown): value is {
|
|
10
|
-
tiers: unknown[];
|
|
11
|
-
types: unknown[];
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Build the `init` argument for `fetch` to reach codeassembly's canonical work-types files.
|
|
15
|
-
*
|
|
16
|
-
* Returns `{ headers: { Authorization: 'Bearer <token>' } }` when `GITHUB_TOKEN` is set in the
|
|
17
|
-
* environment; returns `undefined` otherwise so the call site stays byte-identical to an
|
|
18
|
-
* unauthenticated request. Centralised here so `checkWorkTypesDrift` and `syncWorkTypes`
|
|
19
|
-
* cannot diverge on auth handling. Tests stub the env via `vi.stubEnv` rather than parameter
|
|
20
|
-
* injection, so this reads `process.env` directly.
|
|
21
|
-
*/
|
|
22
|
-
export declare function buildFetchInit(): RequestInit | undefined;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export function hasExpectedTopLevelShape(value) {
|
|
2
|
-
if (typeof value !== 'object' || value === null) {
|
|
3
|
-
return false;
|
|
4
|
-
}
|
|
5
|
-
if (!('tiers' in value) || !('types' in value)) {
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
|
-
return Array.isArray(value.tiers) && Array.isArray(value.types);
|
|
9
|
-
}
|
|
10
|
-
export function buildFetchInit() {
|
|
11
|
-
const token = process.env['GITHUB_TOKEN'];
|
|
12
|
-
if (token === undefined || token === '') {
|
|
13
|
-
return undefined;
|
|
14
|
-
}
|
|
15
|
-
return { headers: { Authorization: `Bearer ${token}` } };
|
|
16
|
-
}
|