@spacefast/common 0.0.23 → 0.0.26
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/brand-assets/LICENSE-Haskoy.txt +93 -0
- package/brand-assets/haskoy-latin-variable.woff2 +0 -0
- package/brand-assets/spacefast-favicon.svg +4 -4
- package/brand-assets/spacefast-sf-full-bleed.svg +3 -3
- package/brand-assets/spacefast-wordmark.svg +2 -4
- package/dist/agents/connect-targets.js +1 -1
- package/dist/agents/private-key-oauth.d.ts +0 -1
- package/dist/agents/private-key-oauth.js +46 -63
- package/dist/brand-assets-build.js +4 -6
- package/dist/brand-assets.d.ts +5 -15
- package/dist/brand-assets.js +15 -14
- package/dist/config/domains.d.ts +47 -7
- package/dist/config/domains.js +66 -10
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +0 -1
- package/dist/contracts/abuse.d.ts +2 -0
- package/dist/contracts/abuse.js +12 -0
- package/dist/contracts/access.d.ts +124 -12
- package/dist/contracts/access.js +73 -9
- package/dist/contracts/activity.d.ts +1 -1
- package/dist/contracts/activity.js +5 -12
- package/dist/contracts/api-keys.d.ts +21 -21
- package/dist/contracts/api-keys.js +2 -2
- package/dist/contracts/beta.js +1 -1
- package/dist/contracts/billing.d.ts +3 -35
- package/dist/contracts/billing.js +33 -52
- package/dist/contracts/builds.d.ts +30 -18
- package/dist/contracts/builds.js +28 -9
- package/dist/contracts/channels.js +1 -1
- package/dist/contracts/cli.d.ts +10 -0
- package/dist/contracts/cli.js +10 -0
- package/dist/contracts/collab-public.d.ts +63 -0
- package/dist/contracts/collab-public.js +46 -0
- package/dist/contracts/comments.d.ts +282 -53
- package/dist/contracts/comments.js +173 -52
- package/dist/contracts/common.d.ts +3 -3
- package/dist/contracts/common.js +5 -5
- package/dist/contracts/crons.d.ts +35 -0
- package/dist/contracts/crons.js +42 -0
- package/dist/contracts/device-auth.d.ts +6 -6
- package/dist/contracts/device-auth.js +2 -2
- package/dist/contracts/docs.js +2 -2
- package/dist/contracts/domains.d.ts +38 -27
- package/dist/contracts/domains.js +29 -2
- package/dist/contracts/enums.d.ts +34 -30
- package/dist/contracts/enums.js +62 -48
- package/dist/contracts/error-code-meta.d.ts +50 -125
- package/dist/contracts/error-code-meta.js +29 -41
- package/dist/contracts/error-codes.d.ts +1 -1
- package/dist/contracts/error-codes.js +14 -33
- package/dist/contracts/execution.d.ts +47 -66
- package/dist/contracts/execution.js +53 -49
- package/dist/contracts/feature-lifecycle-core.d.ts +0 -6
- package/dist/contracts/feature-lifecycle-core.js +2 -31
- package/dist/contracts/feature-lifecycle.d.ts +12 -52
- package/dist/contracts/feature-lifecycle.js +16 -59
- package/dist/contracts/features.d.ts +48 -60
- package/dist/contracts/features.js +59 -51
- package/dist/contracts/functions.d.ts +266 -72
- package/dist/contracts/functions.js +260 -37
- package/dist/contracts/git.d.ts +28 -34
- package/dist/contracts/git.js +10 -11
- package/dist/contracts/grants.d.ts +9 -5
- package/dist/contracts/grants.js +18 -9
- package/dist/contracts/ids.js +2 -2
- package/dist/contracts/internal.d.ts +8 -6
- package/dist/contracts/internal.js +12 -12
- package/dist/contracts/mcp.d.ts +11 -0
- package/dist/contracts/mcp.js +5 -0
- package/dist/contracts/me.js +1 -1
- package/dist/contracts/oauth-resources.d.ts +4 -3
- package/dist/contracts/oauth-resources.js +12 -3
- package/dist/contracts/operations.d.ts +90 -5
- package/dist/contracts/operations.js +77 -3
- package/dist/contracts/pages.d.ts +12 -7
- package/dist/contracts/pages.js +24 -1
- package/dist/contracts/plan-policy.d.ts +0 -2
- package/dist/contracts/plan-policy.js +2 -3
- package/dist/contracts/platform.d.ts +61 -148
- package/dist/contracts/platform.js +70 -126
- package/dist/contracts/publish-archive.d.ts +508 -0
- package/dist/contracts/publish-archive.js +32 -0
- package/dist/contracts/push-new.d.ts +4 -4
- package/dist/contracts/quotas.js +2 -2
- package/dist/contracts/repository-connections.d.ts +43 -30
- package/dist/contracts/repository-connections.js +11 -3
- package/dist/contracts/resources.d.ts +12 -24
- package/dist/contracts/resources.js +36 -16
- package/dist/contracts/runtime-api.d.ts +433 -192
- package/dist/contracts/runtime-api.js +421 -356
- package/dist/contracts/runtime-app.d.ts +127 -120
- package/dist/contracts/runtime-app.js +19 -10
- package/dist/contracts/runtime-db.d.ts +5 -5
- package/dist/contracts/runtime-db.js +2 -2
- package/dist/contracts/runtime-purge.d.ts +8 -0
- package/dist/contracts/runtime-purge.js +7 -0
- package/dist/contracts/runtime-services.d.ts +219 -0
- package/dist/contracts/runtime-services.js +437 -0
- package/dist/contracts/runtime-storage.d.ts +46 -32
- package/dist/contracts/runtime-storage.js +31 -8
- package/dist/contracts/sf-config-v1.d.ts +48 -10
- package/dist/contracts/space-config.d.ts +69 -18
- package/dist/contracts/space-config.js +226 -27
- package/dist/contracts/spaces.d.ts +236 -450
- package/dist/contracts/spaces.js +131 -151
- package/dist/contracts/superadmin-activity.d.ts +57 -4
- package/dist/contracts/superadmin-activity.js +48 -2
- package/dist/contracts/superadmin-search.d.ts +126 -0
- package/dist/contracts/superadmin-search.js +61 -0
- package/dist/contracts/superadmin-spaces.d.ts +361 -92
- package/dist/contracts/superadmin-spaces.js +97 -24
- package/dist/contracts/superadmin-teams.d.ts +28 -10
- package/dist/contracts/superadmin-teams.js +5 -8
- package/dist/contracts/superadmin-tenants.d.ts +0 -6
- package/dist/contracts/superadmin-tenants.js +1 -7
- package/dist/contracts/superadmin.d.ts +135 -54
- package/dist/contracts/superadmin.js +46 -23
- package/dist/contracts/tags.d.ts +12 -12
- package/dist/contracts/tags.js +3 -3
- package/dist/contracts/teams.d.ts +49 -14
- package/dist/contracts/teams.js +40 -22
- package/dist/contracts/transfers.d.ts +0 -49
- package/dist/contracts/transfers.js +4 -8
- package/dist/contracts/usage.d.ts +61 -0
- package/dist/contracts/usage.js +64 -0
- package/dist/contracts/variables.d.ts +2 -7
- package/dist/contracts/variables.js +9 -8
- package/dist/contracts/webhooks.d.ts +2 -2
- package/dist/contracts/zero.d.ts +102 -73
- package/dist/contracts/zero.js +94 -32
- package/dist/dashboard-paths/index.d.ts +1 -1
- package/dist/dashboard-paths/index.js +1 -0
- package/dist/docs/agent-prose.d.ts +2 -2
- package/dist/docs/agent-prose.js +63 -70
- package/dist/docs/agent-setup.js +45 -15
- package/dist/docs/catalog.d.ts +24 -24
- package/dist/docs/catalog.js +35 -24
- package/dist/docs/error-docs.js +194 -270
- package/dist/docs/skills.d.ts +12 -12
- package/dist/docs/skills.js +4 -4
- package/dist/test-helpers/fetch-stub.d.ts +16 -0
- package/dist/test-helpers/fetch-stub.js +25 -0
- package/dist/utils/build-settings.d.ts +5 -1
- package/dist/utils/build-settings.js +91 -13
- package/dist/utils/canonical-json.d.ts +10 -0
- package/dist/utils/canonical-json.js +22 -0
- package/dist/utils/cast-transport.d.ts +28 -0
- package/dist/utils/cast-transport.js +52 -0
- package/dist/utils/claim-token.d.ts +0 -8
- package/dist/utils/claim-token.js +3 -15
- package/dist/utils/concurrency.js +1 -0
- package/dist/utils/credential-policy.d.ts +1 -1
- package/dist/utils/credential-policy.js +4 -3
- package/dist/utils/dns-instructions.js +9 -9
- package/dist/utils/env-file.d.ts +17 -0
- package/dist/utils/env-file.js +96 -0
- package/dist/utils/error-code.d.ts +2 -0
- package/dist/utils/error-code.js +8 -0
- package/dist/utils/generate-space-name.d.ts +8 -10
- package/dist/utils/generate-space-name.js +206 -21
- package/dist/utils/grant-decision.fixtures.json +2938 -0
- package/dist/utils/grants.d.ts +2 -0
- package/dist/utils/grants.js +26 -1
- package/dist/utils/gravatar.d.ts +9 -0
- package/dist/utils/gravatar.js +31 -0
- package/dist/utils/idempotency.d.ts +6 -0
- package/dist/utils/idempotency.js +28 -0
- package/dist/utils/local-space-state.d.ts +9 -16
- package/dist/utils/local-space-state.js +20 -50
- package/dist/utils/one-shot-replay.d.ts +4 -1
- package/dist/utils/page-colors.d.ts +14 -12
- package/dist/utils/page-colors.js +15 -13
- package/dist/utils/page-fonts.d.ts +2 -2
- package/dist/utils/page-fonts.js +15 -4
- package/dist/utils/pages.d.ts +21 -3
- package/dist/utils/pages.js +42 -13
- package/dist/utils/publish-form-data.d.ts +12 -0
- package/dist/utils/publish-form-data.js +10 -0
- package/dist/utils/publish-policy.d.ts +27 -0
- package/dist/utils/publish-policy.fixtures.json +403 -0
- package/dist/utils/publish-policy.js +45 -20
- package/dist/utils/push-new.d.ts +7 -0
- package/dist/utils/push-new.js +7 -0
- package/dist/utils/query-keys.d.ts +4 -5
- package/dist/utils/query-keys.js +2 -3
- package/dist/utils/runtime-paths.d.ts +5 -0
- package/dist/utils/runtime-paths.js +5 -0
- package/dist/utils/runtime-upload-batch.d.ts +0 -5
- package/dist/utils/runtime-upload-batch.js +1 -27
- package/dist/utils/runtime-upload.d.ts +6 -11
- package/dist/utils/runtime-upload.js +10 -13
- package/dist/utils/secure-local-file.js +5 -16
- package/dist/utils/space-config.d.ts +1 -34
- package/dist/utils/space-config.js +8 -326
- package/dist/utils/static-runtime-policy.d.ts +9 -3
- package/dist/utils/static-runtime-policy.fixtures.json +38 -41
- package/dist/utils/static-runtime-policy.js +22 -56
- package/dist/utils/storage-policy.d.ts +1 -1
- package/dist/utils/storage-policy.js +3 -1
- package/dist/utils/structured-error.d.ts +14 -0
- package/dist/utils/structured-error.js +22 -0
- package/dist/utils/upload-session.d.ts +4 -1
- package/dist/utils/upload-session.js +33 -5
- package/dist/utils/version-path.js +13 -4
- package/dist/vocabulary.d.ts +13 -11
- package/dist/vocabulary.js +42 -28
- package/package.json +7 -17
- package/dist/config/postgres-budget.d.ts +0 -129
- package/dist/config/postgres-budget.js +0 -140
- package/dist/config/postgres-budget.json +0 -51
- package/dist/contracts/archives.d.ts +0 -331
- package/dist/contracts/archives.js +0 -120
- package/dist/contracts/deployments.d.ts +0 -574
- package/dist/contracts/deployments.js +0 -97
- package/dist/contracts/sites.d.ts +0 -416
- package/dist/contracts/sites.js +0 -168
- package/dist/contracts/superadmin-queues.d.ts +0 -414
- package/dist/contracts/superadmin-queues.js +0 -202
- package/dist/contracts/superadmin-runtime.d.ts +0 -27
- package/dist/contracts/superadmin-runtime.js +0 -38
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/utils/api.d.ts +0 -4
- package/dist/utils/api.js +0 -13
|
@@ -141,7 +141,7 @@ export function policyIsSubsetOfGrantor(requested, grantor) {
|
|
|
141
141
|
return statement.actions.every((action) => statement.resources.every((resource) => grantorAllows(grantor, action, resource, statement.conditions)));
|
|
142
142
|
}) && grantorDeniesArePreserved(requested, grantor));
|
|
143
143
|
}
|
|
144
|
-
// Request-time evaluation (
|
|
144
|
+
// Request-time evaluation (the platform spec IAM-lite): explicit deny wins,
|
|
145
145
|
// explicit allow permits, otherwise implicit deny. Condition keys are ANDed and an
|
|
146
146
|
// unresolvable condition attribute fails closed (see `conditionsMatch`).
|
|
147
147
|
export function policyAllows(input) {
|
|
@@ -152,7 +152,7 @@ export function policyAllows(input) {
|
|
|
152
152
|
return resources.some((resource) => matchesEffect(input.policy, "allow", input.action, resource, input.conditions, "request"));
|
|
153
153
|
}
|
|
154
154
|
// The tenants a credential's policy grants any access to. Drives tenant
|
|
155
|
-
// selection (
|
|
155
|
+
// selection (the platform spec Tenant): `X-Spacefast-Tenant-Id` may pick
|
|
156
156
|
// one granted tenant but is never an authority by itself, and a token spanning
|
|
157
157
|
// multiple tenants must fail ambiguous requests with `tenant_selection_required`.
|
|
158
158
|
export function grantedTenantsFromPolicy(policy) {
|
|
@@ -259,7 +259,7 @@ function resourceMatches(pattern, resource) {
|
|
|
259
259
|
if (pattern.endsWith("/*")) {
|
|
260
260
|
return resource === pattern.slice(0, -2) || resource.startsWith(pattern.slice(0, -1));
|
|
261
261
|
}
|
|
262
|
-
// A tenant-rooted resource is scope-wide (
|
|
262
|
+
// A tenant-rooted resource is scope-wide (the platform spec:
|
|
263
263
|
// `stt://tenant/{t}` is a grantable StatticResource and resource grants cover
|
|
264
264
|
// their subtree): it covers every resource inside that tenant. This is the
|
|
265
265
|
// tenant-scoped (partner/agency) credential shape.
|
|
@@ -273,6 +273,7 @@ function conditionsMatch(statementConditions, contextConditions, effect, mode) {
|
|
|
273
273
|
return true;
|
|
274
274
|
}
|
|
275
275
|
return Object.entries(statementConditions).every(([key, value]) => {
|
|
276
|
+
// SAFETY: Object.entries obtains key from the named RequestCondition object immediately above.
|
|
276
277
|
const resolved = contextConditions?.[key];
|
|
277
278
|
if (resolved === undefined && mode === "request") {
|
|
278
279
|
// Fail closed on unresolvable condition attributes: the condition never
|
|
@@ -15,15 +15,15 @@ export function addressDnsInstructionsForHostname(input) {
|
|
|
15
15
|
normalizeDnsName(instruction.name) !== hostname) {
|
|
16
16
|
return [];
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
];
|
|
18
|
+
const result = {
|
|
19
|
+
type: instruction.type,
|
|
20
|
+
name: instruction.name,
|
|
21
|
+
value: instruction.value,
|
|
22
|
+
purpose: instruction.purpose,
|
|
23
|
+
};
|
|
24
|
+
if (instruction.ttl !== undefined)
|
|
25
|
+
result.ttl = instruction.ttl;
|
|
26
|
+
return [result];
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
function normalizeAddress(value) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ParsedEnvFileEntry = {
|
|
2
|
+
name: string;
|
|
3
|
+
value: string;
|
|
4
|
+
line: number;
|
|
5
|
+
};
|
|
6
|
+
type ValidationErrorFactory = (message: string) => Error;
|
|
7
|
+
export declare function parseEnvFile(content: string, options?: {
|
|
8
|
+
reservedStatticPrefix?: boolean;
|
|
9
|
+
validationError?: ValidationErrorFactory;
|
|
10
|
+
}): ParsedEnvFileEntry[];
|
|
11
|
+
export declare function loadEnvFileSource<const File extends string>(root: string, files: readonly File[], options?: {
|
|
12
|
+
validationError?: ValidationErrorFactory;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
file: File;
|
|
15
|
+
content: string;
|
|
16
|
+
} | null>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { variableNameSchema } from "../contracts/variables.js";
|
|
4
|
+
import { hasErrorCode } from "./error-code.js";
|
|
5
|
+
import { structuredValidationError } from "./structured-error.js";
|
|
6
|
+
const localEnvNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
7
|
+
function stripInlineComment(value) {
|
|
8
|
+
let quoted = null;
|
|
9
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
10
|
+
const char = value[index];
|
|
11
|
+
if (quoted) {
|
|
12
|
+
if (char === "\\" && quoted === '"')
|
|
13
|
+
index += 1;
|
|
14
|
+
else if (char === quoted)
|
|
15
|
+
quoted = null;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (char === "'" || char === '"')
|
|
19
|
+
quoted = char;
|
|
20
|
+
else if (char === "#" && (index === 0 || /\s/.test(value[index - 1] ?? ""))) {
|
|
21
|
+
return value.slice(0, index).trimEnd();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return value.trimEnd();
|
|
25
|
+
}
|
|
26
|
+
function unescapeDoubleQuotedValue(value) {
|
|
27
|
+
return value.replace(/\\([nrt"\\$])/g, (_, escaped) => {
|
|
28
|
+
if (escaped === "n")
|
|
29
|
+
return "\n";
|
|
30
|
+
if (escaped === "r")
|
|
31
|
+
return "\r";
|
|
32
|
+
if (escaped === "t")
|
|
33
|
+
return "\t";
|
|
34
|
+
return escaped;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function parseEnvValue(rawValue, line, error) {
|
|
38
|
+
const value = stripInlineComment(rawValue.trim());
|
|
39
|
+
if (value.startsWith('"')) {
|
|
40
|
+
if (!value.endsWith('"') || value.length === 1) {
|
|
41
|
+
throw error(`Invalid .env value on line ${line}: missing closing double quote.`);
|
|
42
|
+
}
|
|
43
|
+
return unescapeDoubleQuotedValue(value.slice(1, -1));
|
|
44
|
+
}
|
|
45
|
+
if (value.startsWith("'")) {
|
|
46
|
+
if (!value.endsWith("'") || value.length === 1) {
|
|
47
|
+
throw error(`Invalid .env value on line ${line}: missing closing single quote.`);
|
|
48
|
+
}
|
|
49
|
+
return value.slice(1, -1);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
export function parseEnvFile(content, options = { reservedStatticPrefix: true }) {
|
|
54
|
+
const error = options.validationError ?? structuredValidationError;
|
|
55
|
+
const entries = new Map();
|
|
56
|
+
const lines = content.replace(/^\uFEFF/, "").split(/\r?\n/);
|
|
57
|
+
for (const [index, rawLine] of lines.entries()) {
|
|
58
|
+
const line = index + 1;
|
|
59
|
+
const trimmed = rawLine.trim();
|
|
60
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
61
|
+
continue;
|
|
62
|
+
const withoutExport = trimmed.startsWith("export ")
|
|
63
|
+
? trimmed.slice("export ".length).trim()
|
|
64
|
+
: trimmed;
|
|
65
|
+
const equalsIndex = withoutExport.indexOf("=");
|
|
66
|
+
if (equalsIndex < 0)
|
|
67
|
+
throw error(`Invalid .env entry on line ${line}: expected NAME=value.`);
|
|
68
|
+
const name = withoutExport.slice(0, equalsIndex).trim();
|
|
69
|
+
const validName = options.reservedStatticPrefix === false
|
|
70
|
+
? localEnvNamePattern.test(name)
|
|
71
|
+
: variableNameSchema.safeParse(name).success;
|
|
72
|
+
if (!validName)
|
|
73
|
+
throw error(`Invalid .env variable name on line ${line}: ${name}.`);
|
|
74
|
+
const value = parseEnvValue(withoutExport.slice(equalsIndex + 1), line, error);
|
|
75
|
+
if (value.length === 0) {
|
|
76
|
+
throw error(`Invalid .env value on line ${line}: empty values are not supported yet.`);
|
|
77
|
+
}
|
|
78
|
+
entries.set(name, { name, value, line });
|
|
79
|
+
}
|
|
80
|
+
return [...entries.values()];
|
|
81
|
+
}
|
|
82
|
+
export async function loadEnvFileSource(root, files, options = {}) {
|
|
83
|
+
const error = options.validationError ?? structuredValidationError;
|
|
84
|
+
const candidates = await Promise.all(files.map(async (file) => {
|
|
85
|
+
const content = await readFile(path.join(root, file), "utf8").catch((reason) => {
|
|
86
|
+
if (hasErrorCode(reason, "ENOENT"))
|
|
87
|
+
return null;
|
|
88
|
+
throw reason;
|
|
89
|
+
});
|
|
90
|
+
return content === null ? null : { file, content };
|
|
91
|
+
}));
|
|
92
|
+
const present = candidates.filter((candidate) => candidate !== null);
|
|
93
|
+
if (present.length > 1)
|
|
94
|
+
throw error(`Use either ${files[0]} or ${files[1]}, not both.`);
|
|
95
|
+
return present[0] ?? null;
|
|
96
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** True when `error` carries the given syscall-style `code` (ENOENT, EEXIST, …). */
|
|
2
|
+
export function hasErrorCode(error, code) {
|
|
3
|
+
return (error !== null &&
|
|
4
|
+
typeof error === "object" &&
|
|
5
|
+
"code" in error &&
|
|
6
|
+
// SAFETY: The preceding checks prove error is a non-null object with a code property.
|
|
7
|
+
error.code === code);
|
|
8
|
+
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates a
|
|
2
|
+
* Generates a short, readable space title.
|
|
3
3
|
*
|
|
4
|
-
* The pool mixes WordPress
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* requirement is that two back-to-back calls almost never collide.
|
|
4
|
+
* The pool mixes a little WordPress and web flavor with broad nature, color,
|
|
5
|
+
* motion, and craft vocabulary. The result should suit any site instead of
|
|
6
|
+
* reading like a CMS inside joke, while staying compact enough for a hostname.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* unlikely. The generator is intentionally dependency-free so it can be
|
|
12
|
-
* shared by the control-plane, the CLI, and any future surface.
|
|
8
|
+
* The generator is intentionally dependency-free so it can be shared by the
|
|
9
|
+
* control-plane, dashboard, CLI, and future publishing surfaces.
|
|
13
10
|
*/
|
|
14
|
-
export declare
|
|
11
|
+
export declare const SPACE_TITLE_COMBINATION_COUNT: number;
|
|
12
|
+
export declare function generateSpaceTitle(random?: () => number): string;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates a
|
|
2
|
+
* Generates a short, readable space title.
|
|
3
3
|
*
|
|
4
|
-
* The pool mixes WordPress
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* requirement is that two back-to-back calls almost never collide.
|
|
4
|
+
* The pool mixes a little WordPress and web flavor with broad nature, color,
|
|
5
|
+
* motion, and craft vocabulary. The result should suit any site instead of
|
|
6
|
+
* reading like a CMS inside joke, while staying compact enough for a hostname.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* unlikely. The generator is intentionally dependency-free so it can be
|
|
12
|
-
* shared by the control-plane, the CLI, and any future surface.
|
|
8
|
+
* The generator is intentionally dependency-free so it can be shared by the
|
|
9
|
+
* control-plane, dashboard, CLI, and future publishing surfaces.
|
|
13
10
|
*/
|
|
14
11
|
const ADJECTIVES = [
|
|
15
12
|
"Atomic",
|
|
@@ -44,6 +41,102 @@ const ADJECTIVES = [
|
|
|
44
41
|
"Templated",
|
|
45
42
|
"Responsive",
|
|
46
43
|
"Trackbacked",
|
|
44
|
+
"Agile",
|
|
45
|
+
"Amber",
|
|
46
|
+
"Ancient",
|
|
47
|
+
"Arctic",
|
|
48
|
+
"Azure",
|
|
49
|
+
"Balanced",
|
|
50
|
+
"Bold",
|
|
51
|
+
"Bright",
|
|
52
|
+
"Brisk",
|
|
53
|
+
"Calm",
|
|
54
|
+
"Candid",
|
|
55
|
+
"Celestial",
|
|
56
|
+
"Clever",
|
|
57
|
+
"Coastal",
|
|
58
|
+
"Composed",
|
|
59
|
+
"Cosmic",
|
|
60
|
+
"Crisp",
|
|
61
|
+
"Curious",
|
|
62
|
+
"Daring",
|
|
63
|
+
"Deep",
|
|
64
|
+
"Electric",
|
|
65
|
+
"Elegant",
|
|
66
|
+
"Emerald",
|
|
67
|
+
"Endless",
|
|
68
|
+
"Evergreen",
|
|
69
|
+
"Fluid",
|
|
70
|
+
"Focused",
|
|
71
|
+
"Gentle",
|
|
72
|
+
"Golden",
|
|
73
|
+
"Grand",
|
|
74
|
+
"Harmonic",
|
|
75
|
+
"Hidden",
|
|
76
|
+
"Honest",
|
|
77
|
+
"Indigo",
|
|
78
|
+
"Infinite",
|
|
79
|
+
"Keen",
|
|
80
|
+
"Kind",
|
|
81
|
+
"Lively",
|
|
82
|
+
"Lucid",
|
|
83
|
+
"Lunar",
|
|
84
|
+
"Magnetic",
|
|
85
|
+
"Mellow",
|
|
86
|
+
"Modern",
|
|
87
|
+
"Nimble",
|
|
88
|
+
"Northern",
|
|
89
|
+
"Open",
|
|
90
|
+
"Pacific",
|
|
91
|
+
"Patient",
|
|
92
|
+
"Polished",
|
|
93
|
+
"Prime",
|
|
94
|
+
"Quiet",
|
|
95
|
+
"Radiant",
|
|
96
|
+
"Rapid",
|
|
97
|
+
"Rare",
|
|
98
|
+
"Ready",
|
|
99
|
+
"Regal",
|
|
100
|
+
"Remote",
|
|
101
|
+
"Restless",
|
|
102
|
+
"Robust",
|
|
103
|
+
"Royal",
|
|
104
|
+
"Sable",
|
|
105
|
+
"Silent",
|
|
106
|
+
"Simple",
|
|
107
|
+
"Solar",
|
|
108
|
+
"Steady",
|
|
109
|
+
"Stellar",
|
|
110
|
+
"Still",
|
|
111
|
+
"Swift",
|
|
112
|
+
"Tactile",
|
|
113
|
+
"Tidy",
|
|
114
|
+
"Timeless",
|
|
115
|
+
"Tranquil",
|
|
116
|
+
"True",
|
|
117
|
+
"Vivid",
|
|
118
|
+
"Warm",
|
|
119
|
+
"Wild",
|
|
120
|
+
"Wise",
|
|
121
|
+
"Woven",
|
|
122
|
+
"Young",
|
|
123
|
+
"Zealous",
|
|
124
|
+
"Airy",
|
|
125
|
+
"Autumn",
|
|
126
|
+
"Blue",
|
|
127
|
+
"Clear",
|
|
128
|
+
"Copper",
|
|
129
|
+
"Distant",
|
|
130
|
+
"Early",
|
|
131
|
+
"Fresh",
|
|
132
|
+
"Glowing",
|
|
133
|
+
"Green",
|
|
134
|
+
"Light",
|
|
135
|
+
"Misty",
|
|
136
|
+
"Neon",
|
|
137
|
+
"Silver",
|
|
138
|
+
"Spring",
|
|
139
|
+
"Summer",
|
|
47
140
|
];
|
|
48
141
|
const NOUNS = [
|
|
49
142
|
"Codex",
|
|
@@ -78,18 +171,110 @@ const NOUNS = [
|
|
|
78
171
|
"Gravatar",
|
|
79
172
|
"Reblog",
|
|
80
173
|
"Opengraph",
|
|
174
|
+
"Acre",
|
|
175
|
+
"Arcade",
|
|
176
|
+
"Atlas",
|
|
177
|
+
"Beacon",
|
|
178
|
+
"Birch",
|
|
179
|
+
"Bloom",
|
|
180
|
+
"Bridge",
|
|
181
|
+
"Brook",
|
|
182
|
+
"Canyon",
|
|
183
|
+
"Cedar",
|
|
184
|
+
"Circuit",
|
|
185
|
+
"Cloud",
|
|
186
|
+
"Coast",
|
|
187
|
+
"Comet",
|
|
188
|
+
"Cove",
|
|
189
|
+
"Creek",
|
|
190
|
+
"Delta",
|
|
191
|
+
"Dune",
|
|
192
|
+
"Echo",
|
|
193
|
+
"Ember",
|
|
194
|
+
"Field",
|
|
195
|
+
"Fjord",
|
|
196
|
+
"Forest",
|
|
197
|
+
"Forge",
|
|
198
|
+
"Garden",
|
|
199
|
+
"Grove",
|
|
200
|
+
"Harbor",
|
|
201
|
+
"Haven",
|
|
202
|
+
"Hill",
|
|
203
|
+
"Horizon",
|
|
204
|
+
"Island",
|
|
205
|
+
"Junction",
|
|
206
|
+
"Kite",
|
|
207
|
+
"Lake",
|
|
208
|
+
"Lantern",
|
|
209
|
+
"Meadow",
|
|
210
|
+
"Mesa",
|
|
211
|
+
"Moon",
|
|
212
|
+
"Nest",
|
|
213
|
+
"Oak",
|
|
214
|
+
"Ocean",
|
|
215
|
+
"Orchard",
|
|
216
|
+
"Peak",
|
|
217
|
+
"Pine",
|
|
218
|
+
"Plain",
|
|
219
|
+
"Pond",
|
|
220
|
+
"Prairie",
|
|
221
|
+
"Prism",
|
|
222
|
+
"Reef",
|
|
223
|
+
"Ridge",
|
|
224
|
+
"River",
|
|
225
|
+
"Road",
|
|
226
|
+
"Rock",
|
|
227
|
+
"Sage",
|
|
228
|
+
"Shore",
|
|
229
|
+
"Signal",
|
|
230
|
+
"Sky",
|
|
231
|
+
"Spark",
|
|
232
|
+
"Star",
|
|
233
|
+
"Stone",
|
|
234
|
+
"Studio",
|
|
235
|
+
"Summit",
|
|
236
|
+
"Sun",
|
|
237
|
+
"Trail",
|
|
238
|
+
"Vale",
|
|
239
|
+
"Valley",
|
|
240
|
+
"Vault",
|
|
241
|
+
"Wave",
|
|
242
|
+
"Willow",
|
|
243
|
+
"Wind",
|
|
244
|
+
"Window",
|
|
245
|
+
"Wood",
|
|
246
|
+
"Bay",
|
|
247
|
+
"Branch",
|
|
248
|
+
"Breeze",
|
|
249
|
+
"Canvas",
|
|
250
|
+
"Castle",
|
|
251
|
+
"Cavern",
|
|
252
|
+
"Cliff",
|
|
253
|
+
"Dawn",
|
|
254
|
+
"Drift",
|
|
255
|
+
"Falcon",
|
|
256
|
+
"Flame",
|
|
257
|
+
"Glade",
|
|
258
|
+
"Harborlight",
|
|
259
|
+
"Loom",
|
|
260
|
+
"Maple",
|
|
261
|
+
"Marsh",
|
|
262
|
+
"North",
|
|
263
|
+
"Pebble",
|
|
264
|
+
"Quartz",
|
|
265
|
+
"Rain",
|
|
266
|
+
"Range",
|
|
267
|
+
"Terrace",
|
|
268
|
+
"Thicket",
|
|
269
|
+
"Wren",
|
|
81
270
|
];
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
271
|
+
export const SPACE_TITLE_COMBINATION_COUNT = ADJECTIVES.length * NOUNS.length;
|
|
272
|
+
export function generateSpaceTitle(random = Math.random) {
|
|
273
|
+
const index = Math.floor(random() * SPACE_TITLE_COMBINATION_COUNT);
|
|
274
|
+
const adjective = ADJECTIVES[Math.floor(index / NOUNS.length)];
|
|
275
|
+
const noun = NOUNS[index % NOUNS.length];
|
|
276
|
+
if (!adjective || !noun) {
|
|
277
|
+
throw new Error("generateSpaceName: random source must return a value from 0 up to 1.");
|
|
85
278
|
}
|
|
86
|
-
|
|
87
|
-
const value = list[index];
|
|
88
|
-
if (value === undefined) {
|
|
89
|
-
throw new Error("generateSpaceName: word list contained a hole.");
|
|
90
|
-
}
|
|
91
|
-
return value;
|
|
92
|
-
}
|
|
93
|
-
export function generateSpaceTitle() {
|
|
94
|
-
return `${pickRandom(ADJECTIVES)} ${pickRandom(NOUNS)}`;
|
|
279
|
+
return `${adjective} ${noun}`;
|
|
95
280
|
}
|