@hyprcart/app-manifest 1.0.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/README.md +5 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +280 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/README.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
declare const supportedSurfaces: readonly ["storefront_block", "admin_surface", "checkout_ui", "checkout_function", "pixel", "event", "flow", "mcp"];
|
|
2
|
+
type AppSurfaceKind = (typeof supportedSurfaces)[number];
|
|
3
|
+
type LocaleMessages = Record<string, string>;
|
|
4
|
+
interface AppManifestSurface {
|
|
5
|
+
id: string;
|
|
6
|
+
type: AppSurfaceKind;
|
|
7
|
+
entry: string;
|
|
8
|
+
label: Record<string, string>;
|
|
9
|
+
settings?: unknown[];
|
|
10
|
+
scopes?: string[];
|
|
11
|
+
deployable?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface AppManifest {
|
|
14
|
+
id?: string;
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
manifestVersion: string;
|
|
18
|
+
sdkVersion: string;
|
|
19
|
+
platformCompatibility: string;
|
|
20
|
+
surfaces: AppManifestSurface[];
|
|
21
|
+
scopes: string[];
|
|
22
|
+
translations: Record<string, LocaleMessages>;
|
|
23
|
+
egress?: string[];
|
|
24
|
+
resources?: {
|
|
25
|
+
bundleSizeBytes?: number;
|
|
26
|
+
cpuMs?: number;
|
|
27
|
+
memoryMb?: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
declare const defaultRequiredLocales: readonly ["en", "de"];
|
|
31
|
+
declare function isSupportedSurface(value: string): value is AppSurfaceKind;
|
|
32
|
+
|
|
33
|
+
type ValidationSeverity = "info" | "warning" | "error" | "blocker";
|
|
34
|
+
interface ValidationIssue {
|
|
35
|
+
code: string;
|
|
36
|
+
severity: ValidationSeverity;
|
|
37
|
+
path: string;
|
|
38
|
+
message: string;
|
|
39
|
+
suggestedFix?: string;
|
|
40
|
+
docsUrl?: string;
|
|
41
|
+
}
|
|
42
|
+
interface ScopeImpact {
|
|
43
|
+
scope: string;
|
|
44
|
+
action: "added" | "removed" | "unchanged";
|
|
45
|
+
dataClass: string;
|
|
46
|
+
approvalRequired: boolean;
|
|
47
|
+
reason: string;
|
|
48
|
+
}
|
|
49
|
+
interface TranslationGap {
|
|
50
|
+
locale: string;
|
|
51
|
+
key: string;
|
|
52
|
+
surface: AppSurfaceKind;
|
|
53
|
+
}
|
|
54
|
+
interface TranslationStatus {
|
|
55
|
+
requiredLocales: string[];
|
|
56
|
+
completeLocales: string[];
|
|
57
|
+
missing: TranslationGap[];
|
|
58
|
+
}
|
|
59
|
+
interface ValidationResult {
|
|
60
|
+
status: "valid" | "warning" | "invalid";
|
|
61
|
+
manifestHash: string;
|
|
62
|
+
issues: ValidationIssue[];
|
|
63
|
+
scopeImpact: ScopeImpact[];
|
|
64
|
+
translationStatus: TranslationStatus;
|
|
65
|
+
}
|
|
66
|
+
interface ValidationOptions {
|
|
67
|
+
requiredLocales?: string[];
|
|
68
|
+
maxBundleSizeBytes?: number;
|
|
69
|
+
supportedSdkMajor?: number;
|
|
70
|
+
}
|
|
71
|
+
declare function validateManifest(manifest: AppManifest, options?: ValidationOptions): ValidationResult;
|
|
72
|
+
declare function getTranslationStatus(manifest: AppManifest, requiredLocales: string[]): TranslationStatus;
|
|
73
|
+
|
|
74
|
+
interface GeneratedContractFile {
|
|
75
|
+
path: string;
|
|
76
|
+
content: string;
|
|
77
|
+
purpose: string;
|
|
78
|
+
}
|
|
79
|
+
interface ContractGenerationResult {
|
|
80
|
+
manifestHash: string;
|
|
81
|
+
schemaVersion: string;
|
|
82
|
+
sdkVersion: string;
|
|
83
|
+
files: GeneratedContractFile[];
|
|
84
|
+
}
|
|
85
|
+
declare function generateContracts(manifest: AppManifest, schemaVersion?: string): ContractGenerationResult;
|
|
86
|
+
|
|
87
|
+
interface CompatibilityResult {
|
|
88
|
+
ok: boolean;
|
|
89
|
+
code?: string;
|
|
90
|
+
message?: string;
|
|
91
|
+
docsUrl?: string;
|
|
92
|
+
}
|
|
93
|
+
declare function checkCompatibility(input: {
|
|
94
|
+
cliVersion?: string;
|
|
95
|
+
sdkVersion: string;
|
|
96
|
+
platformVersion: string;
|
|
97
|
+
requiredSdkMajor?: number;
|
|
98
|
+
}): CompatibilityResult;
|
|
99
|
+
|
|
100
|
+
declare function generateIdeMetadata(manifest: AppManifest): {
|
|
101
|
+
schemaVersion: string;
|
|
102
|
+
platformVersion: string;
|
|
103
|
+
surfaceContracts: {
|
|
104
|
+
surface: "storefront_block" | "admin_surface" | "checkout_ui" | "checkout_function" | "pixel" | "event" | "flow" | "mcp";
|
|
105
|
+
inputTypeName: string;
|
|
106
|
+
outputTypeName: string;
|
|
107
|
+
fixtureTypeName: string;
|
|
108
|
+
scopes: string[];
|
|
109
|
+
}[];
|
|
110
|
+
scopeWarnings: ScopeImpact[];
|
|
111
|
+
translationRequirements: TranslationStatus;
|
|
112
|
+
docsUrls: string[];
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
declare const developerToolingOperationMetadata: readonly [{
|
|
116
|
+
readonly operationName: "validateAppProject";
|
|
117
|
+
readonly scopes: readonly ["app.validation:run"];
|
|
118
|
+
readonly dataClass: "developer_app";
|
|
119
|
+
readonly costClass: "standard";
|
|
120
|
+
readonly idempotent: true;
|
|
121
|
+
readonly lifecycleEvents: readonly ["developer_tooling.validation_requested"];
|
|
122
|
+
readonly docsStatus: "public";
|
|
123
|
+
readonly stability: "preview";
|
|
124
|
+
}, {
|
|
125
|
+
readonly operationName: "requestDeveloperDeployment";
|
|
126
|
+
readonly scopes: readonly ["app.deployment:write"];
|
|
127
|
+
readonly dataClass: "developer_app";
|
|
128
|
+
readonly costClass: "elevated";
|
|
129
|
+
readonly idempotent: true;
|
|
130
|
+
readonly lifecycleEvents: readonly ["developer_tooling.deployment_requested"];
|
|
131
|
+
readonly docsStatus: "public";
|
|
132
|
+
readonly stability: "preview";
|
|
133
|
+
}];
|
|
134
|
+
|
|
135
|
+
export { type AppManifest, type AppManifestSurface, type AppSurfaceKind, type CompatibilityResult, type ContractGenerationResult, type GeneratedContractFile, type LocaleMessages, type ScopeImpact, type TranslationGap, type TranslationStatus, type ValidationIssue, type ValidationOptions, type ValidationResult, type ValidationSeverity, checkCompatibility, defaultRequiredLocales, developerToolingOperationMetadata, generateContracts, generateIdeMetadata, getTranslationStatus, isSupportedSurface, supportedSurfaces, validateManifest };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// src/schema.ts
|
|
2
|
+
var supportedSurfaces = [
|
|
3
|
+
"storefront_block",
|
|
4
|
+
"admin_surface",
|
|
5
|
+
"checkout_ui",
|
|
6
|
+
"checkout_function",
|
|
7
|
+
"pixel",
|
|
8
|
+
"event",
|
|
9
|
+
"flow",
|
|
10
|
+
"mcp"
|
|
11
|
+
];
|
|
12
|
+
var defaultRequiredLocales = ["en", "de"];
|
|
13
|
+
function isSupportedSurface(value) {
|
|
14
|
+
return supportedSurfaces.includes(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/validation.ts
|
|
18
|
+
var riskyDependencyPatterns = [/child_process/i, /node:fs/i, /eval\(/i];
|
|
19
|
+
function validateManifest(manifest, options = {}) {
|
|
20
|
+
const requiredLocales = options.requiredLocales ?? [...defaultRequiredLocales];
|
|
21
|
+
const maxBundleSizeBytes = options.maxBundleSizeBytes ?? 512 * 1024;
|
|
22
|
+
const supportedSdkMajor = options.supportedSdkMajor ?? 1;
|
|
23
|
+
const issues = [];
|
|
24
|
+
if (!manifest.name?.trim()) {
|
|
25
|
+
issues.push(issue("manifest.name.missing", "blocker", "name", "App name is required."));
|
|
26
|
+
}
|
|
27
|
+
if (!manifest.manifestVersion?.trim()) {
|
|
28
|
+
issues.push(issue("manifest.version.missing", "blocker", "manifestVersion", "Manifest version is required."));
|
|
29
|
+
}
|
|
30
|
+
if (!manifest.sdkVersion?.trim()) {
|
|
31
|
+
issues.push(issue("sdk.version.missing", "blocker", "sdkVersion", "SDK version is required."));
|
|
32
|
+
} else if (!isCompatibleSdk(manifest.sdkVersion, supportedSdkMajor)) {
|
|
33
|
+
issues.push(
|
|
34
|
+
issue(
|
|
35
|
+
"sdk.version.unsupported",
|
|
36
|
+
"blocker",
|
|
37
|
+
"sdkVersion",
|
|
38
|
+
`SDK version ${manifest.sdkVersion} is not compatible with this platform.`,
|
|
39
|
+
"Upgrade the app SDK and regenerate contracts.",
|
|
40
|
+
"https://developer.hyprcart.com/docs/app-platform/sdk"
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (!Array.isArray(manifest.surfaces) || manifest.surfaces.length === 0) {
|
|
45
|
+
issues.push(issue("surfaces.missing", "blocker", "surfaces", "At least one app surface is required."));
|
|
46
|
+
}
|
|
47
|
+
manifest.surfaces?.forEach((surface, index) => {
|
|
48
|
+
const basePath = `surfaces.${index}`;
|
|
49
|
+
if (!surface.id?.trim()) {
|
|
50
|
+
issues.push(issue("surface.id.missing", "error", `${basePath}.id`, "Surface id is required."));
|
|
51
|
+
}
|
|
52
|
+
if (!isSupportedSurface(surface.type)) {
|
|
53
|
+
issues.push(issue("surface.type.unsupported", "blocker", `${basePath}.type`, `Unsupported surface type: ${surface.type}`));
|
|
54
|
+
}
|
|
55
|
+
if (!surface.entry?.trim()) {
|
|
56
|
+
issues.push(issue("surface.entry.missing", "error", `${basePath}.entry`, "Surface entry file is required."));
|
|
57
|
+
}
|
|
58
|
+
if (surface.deployable === false) {
|
|
59
|
+
issues.push(
|
|
60
|
+
issue(
|
|
61
|
+
"surface.deferred",
|
|
62
|
+
"warning",
|
|
63
|
+
`${basePath}.deployable`,
|
|
64
|
+
"This surface is marked as preview-only and will not be deployed.",
|
|
65
|
+
"Remove the surface or mark it deployable when the platform supports it."
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const translationStatus = getTranslationStatus(manifest, requiredLocales);
|
|
71
|
+
for (const gap of translationStatus.missing) {
|
|
72
|
+
issues.push(
|
|
73
|
+
issue(
|
|
74
|
+
"validation.translation.missing",
|
|
75
|
+
gap.surface === "storefront_block" ? "error" : "warning",
|
|
76
|
+
`translations.${gap.locale}.${gap.key}`,
|
|
77
|
+
`Missing ${gap.locale} translation for ${gap.key}.`,
|
|
78
|
+
"Add the missing locale key before deployment.",
|
|
79
|
+
"https://developer.hyprcart.com/docs/app-platform/translations"
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if ((manifest.resources?.bundleSizeBytes ?? 0) > maxBundleSizeBytes) {
|
|
84
|
+
issues.push(
|
|
85
|
+
issue(
|
|
86
|
+
"bundle.size.exceeded",
|
|
87
|
+
"blocker",
|
|
88
|
+
"resources.bundleSizeBytes",
|
|
89
|
+
`Bundle size exceeds ${maxBundleSizeBytes} bytes.`,
|
|
90
|
+
"Remove unused dependencies or split the app surface."
|
|
91
|
+
)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
for (const domain of manifest.egress ?? []) {
|
|
95
|
+
if (!domain.startsWith("https://")) {
|
|
96
|
+
issues.push(issue("egress.domain.invalid", "blocker", "egress", "Egress domains must use https."));
|
|
97
|
+
}
|
|
98
|
+
if (riskyDependencyPatterns.some((pattern) => pattern.test(domain))) {
|
|
99
|
+
issues.push(issue("egress.domain.risky", "blocker", "egress", "Egress declaration contains risky content."));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const blocker = issues.some((entry) => entry.severity === "blocker" || entry.severity === "error");
|
|
103
|
+
const warning = issues.some((entry) => entry.severity === "warning");
|
|
104
|
+
return {
|
|
105
|
+
status: blocker ? "invalid" : warning ? "warning" : "valid",
|
|
106
|
+
manifestHash: hashObject(manifest),
|
|
107
|
+
issues,
|
|
108
|
+
scopeImpact: (manifest.scopes ?? []).map((scope) => ({
|
|
109
|
+
scope,
|
|
110
|
+
action: "added",
|
|
111
|
+
dataClass: classifyScope(scope),
|
|
112
|
+
approvalRequired: scope.includes("write") || scope.includes("customer"),
|
|
113
|
+
reason: "Declared by app manifest."
|
|
114
|
+
})),
|
|
115
|
+
translationStatus
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function getTranslationStatus(manifest, requiredLocales) {
|
|
119
|
+
const missing = [];
|
|
120
|
+
const completeLocales = [];
|
|
121
|
+
for (const locale of requiredLocales) {
|
|
122
|
+
const messages = manifest.translations?.[locale] ?? {};
|
|
123
|
+
const before = missing.length;
|
|
124
|
+
for (const surface of manifest.surfaces ?? []) {
|
|
125
|
+
const labelKey = `${surface.id}.label`;
|
|
126
|
+
if (!messages[labelKey]) {
|
|
127
|
+
missing.push({ locale, key: labelKey, surface: surface.type });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (missing.length === before) {
|
|
131
|
+
completeLocales.push(locale);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { requiredLocales, completeLocales, missing };
|
|
135
|
+
}
|
|
136
|
+
function issue(code, severity, path, message, suggestedFix, docsUrl) {
|
|
137
|
+
return { code, severity, path, message, suggestedFix, docsUrl };
|
|
138
|
+
}
|
|
139
|
+
function classifyScope(scope) {
|
|
140
|
+
if (scope.includes("customer")) return "customer";
|
|
141
|
+
if (scope.includes("order")) return "order";
|
|
142
|
+
if (scope.includes("product")) return "product";
|
|
143
|
+
return "standard";
|
|
144
|
+
}
|
|
145
|
+
function isCompatibleSdk(version, supportedMajor) {
|
|
146
|
+
const major = Number(version.split(".")[0]);
|
|
147
|
+
return Number.isFinite(major) && major === supportedMajor;
|
|
148
|
+
}
|
|
149
|
+
function hashObject(value) {
|
|
150
|
+
const json = JSON.stringify(value, Object.keys(value).sort());
|
|
151
|
+
let hash = 0;
|
|
152
|
+
for (let index = 0; index < json.length; index += 1) {
|
|
153
|
+
hash = hash * 31 + json.charCodeAt(index) >>> 0;
|
|
154
|
+
}
|
|
155
|
+
return `mf_${hash.toString(16).padStart(8, "0")}`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/contract-generation.ts
|
|
159
|
+
function generateContracts(manifest, schemaVersion = "2026-06-06") {
|
|
160
|
+
const surfaces = manifest.surfaces.map(renderSurfaceContract).join("\n\n");
|
|
161
|
+
const content = [
|
|
162
|
+
"/* Generated by Hyprcart app tooling. */",
|
|
163
|
+
`export const schemaVersion = ${JSON.stringify(schemaVersion)};`,
|
|
164
|
+
`export const sdkVersion = ${JSON.stringify(manifest.sdkVersion)};`,
|
|
165
|
+
surfaces
|
|
166
|
+
].join("\n");
|
|
167
|
+
return {
|
|
168
|
+
manifestHash: stableHash(JSON.stringify(manifest)),
|
|
169
|
+
schemaVersion,
|
|
170
|
+
sdkVersion: manifest.sdkVersion,
|
|
171
|
+
files: [
|
|
172
|
+
{
|
|
173
|
+
path: "generated/hyprcart.contracts.ts",
|
|
174
|
+
content,
|
|
175
|
+
purpose: "typed surface contracts"
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function renderSurfaceContract(surface) {
|
|
181
|
+
const name = toPascalCase(surface.id);
|
|
182
|
+
return [
|
|
183
|
+
`export interface ${name}Input {`,
|
|
184
|
+
` surface: ${JSON.stringify(surface.type)};`,
|
|
185
|
+
" context: Record<string, unknown>;",
|
|
186
|
+
"}",
|
|
187
|
+
`export interface ${name}Output {`,
|
|
188
|
+
" html?: string;",
|
|
189
|
+
" data?: Record<string, unknown>;",
|
|
190
|
+
" events?: Array<Record<string, unknown>>;",
|
|
191
|
+
"}",
|
|
192
|
+
`export const ${name}Contract = {`,
|
|
193
|
+
` id: ${JSON.stringify(surface.id)},`,
|
|
194
|
+
` type: ${JSON.stringify(surface.type)},`,
|
|
195
|
+
` entry: ${JSON.stringify(surface.entry)},`,
|
|
196
|
+
` scopes: ${JSON.stringify(surface.scopes ?? [])}`,
|
|
197
|
+
"} as const;"
|
|
198
|
+
].join("\n");
|
|
199
|
+
}
|
|
200
|
+
function toPascalCase(value) {
|
|
201
|
+
return value.replace(/[^a-zA-Z0-9]+/g, " ").split(" ").filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join("");
|
|
202
|
+
}
|
|
203
|
+
function stableHash(value) {
|
|
204
|
+
let hash = 5381;
|
|
205
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
206
|
+
hash = hash * 33 ^ value.charCodeAt(index);
|
|
207
|
+
}
|
|
208
|
+
return `ct_${(hash >>> 0).toString(16).padStart(8, "0")}`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/compatibility.ts
|
|
212
|
+
function checkCompatibility(input) {
|
|
213
|
+
const requiredSdkMajor = input.requiredSdkMajor ?? 1;
|
|
214
|
+
const sdkMajor = Number(input.sdkVersion.split(".")[0]);
|
|
215
|
+
if (!Number.isFinite(sdkMajor) || sdkMajor !== requiredSdkMajor) {
|
|
216
|
+
return {
|
|
217
|
+
ok: false,
|
|
218
|
+
code: "sdk.version.unsupported",
|
|
219
|
+
message: `SDK ${input.sdkVersion} is not compatible with platform ${input.platformVersion}.`,
|
|
220
|
+
docsUrl: "https://developer.hyprcart.com/docs/app-platform/sdk"
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return { ok: true };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/ide-metadata.ts
|
|
227
|
+
function generateIdeMetadata(manifest) {
|
|
228
|
+
const validation = validateManifest(manifest);
|
|
229
|
+
const contracts = generateContracts(manifest);
|
|
230
|
+
return {
|
|
231
|
+
schemaVersion: contracts.schemaVersion,
|
|
232
|
+
platformVersion: manifest.platformCompatibility,
|
|
233
|
+
surfaceContracts: manifest.surfaces.map((surface) => ({
|
|
234
|
+
surface: surface.type,
|
|
235
|
+
inputTypeName: `${surface.id}Input`,
|
|
236
|
+
outputTypeName: `${surface.id}Output`,
|
|
237
|
+
fixtureTypeName: `${surface.id}Fixture`,
|
|
238
|
+
scopes: surface.scopes ?? []
|
|
239
|
+
})),
|
|
240
|
+
scopeWarnings: validation.scopeImpact,
|
|
241
|
+
translationRequirements: validation.translationStatus,
|
|
242
|
+
docsUrls: ["https://developer.hyprcart.com/docs/app-platform/manifest"]
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/operation-metadata.ts
|
|
247
|
+
var developerToolingOperationMetadata = [
|
|
248
|
+
{
|
|
249
|
+
operationName: "validateAppProject",
|
|
250
|
+
scopes: ["app.validation:run"],
|
|
251
|
+
dataClass: "developer_app",
|
|
252
|
+
costClass: "standard",
|
|
253
|
+
idempotent: true,
|
|
254
|
+
lifecycleEvents: ["developer_tooling.validation_requested"],
|
|
255
|
+
docsStatus: "public",
|
|
256
|
+
stability: "preview"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
operationName: "requestDeveloperDeployment",
|
|
260
|
+
scopes: ["app.deployment:write"],
|
|
261
|
+
dataClass: "developer_app",
|
|
262
|
+
costClass: "elevated",
|
|
263
|
+
idempotent: true,
|
|
264
|
+
lifecycleEvents: ["developer_tooling.deployment_requested"],
|
|
265
|
+
docsStatus: "public",
|
|
266
|
+
stability: "preview"
|
|
267
|
+
}
|
|
268
|
+
];
|
|
269
|
+
export {
|
|
270
|
+
checkCompatibility,
|
|
271
|
+
defaultRequiredLocales,
|
|
272
|
+
developerToolingOperationMetadata,
|
|
273
|
+
generateContracts,
|
|
274
|
+
generateIdeMetadata,
|
|
275
|
+
getTranslationStatus,
|
|
276
|
+
isSupportedSurface,
|
|
277
|
+
supportedSurfaces,
|
|
278
|
+
validateManifest
|
|
279
|
+
};
|
|
280
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/validation.ts","../src/contract-generation.ts","../src/compatibility.ts","../src/ide-metadata.ts","../src/operation-metadata.ts"],"sourcesContent":["export const supportedSurfaces = [\n \"storefront_block\",\n \"admin_surface\",\n \"checkout_ui\",\n \"checkout_function\",\n \"pixel\",\n \"event\",\n \"flow\",\n \"mcp\",\n] as const;\n\nexport type AppSurfaceKind = (typeof supportedSurfaces)[number];\n\nexport type LocaleMessages = Record<string, string>;\n\nexport interface AppManifestSurface {\n id: string;\n type: AppSurfaceKind;\n entry: string;\n label: Record<string, string>;\n settings?: unknown[];\n scopes?: string[];\n deployable?: boolean;\n}\n\nexport interface AppManifest {\n id?: string;\n name: string;\n version: string;\n manifestVersion: string;\n sdkVersion: string;\n platformCompatibility: string;\n surfaces: AppManifestSurface[];\n scopes: string[];\n translations: Record<string, LocaleMessages>;\n egress?: string[];\n resources?: {\n bundleSizeBytes?: number;\n cpuMs?: number;\n memoryMb?: number;\n };\n}\n\nexport const defaultRequiredLocales = [\"en\", \"de\"] as const;\n\nexport function isSupportedSurface(value: string): value is AppSurfaceKind {\n return supportedSurfaces.includes(value as AppSurfaceKind);\n}\n","import {\n defaultRequiredLocales,\n type AppManifest,\n type AppSurfaceKind,\n isSupportedSurface,\n} from \"./schema\";\n\nexport type ValidationSeverity = \"info\" | \"warning\" | \"error\" | \"blocker\";\n\nexport interface ValidationIssue {\n code: string;\n severity: ValidationSeverity;\n path: string;\n message: string;\n suggestedFix?: string;\n docsUrl?: string;\n}\n\nexport interface ScopeImpact {\n scope: string;\n action: \"added\" | \"removed\" | \"unchanged\";\n dataClass: string;\n approvalRequired: boolean;\n reason: string;\n}\n\nexport interface TranslationGap {\n locale: string;\n key: string;\n surface: AppSurfaceKind;\n}\n\nexport interface TranslationStatus {\n requiredLocales: string[];\n completeLocales: string[];\n missing: TranslationGap[];\n}\n\nexport interface ValidationResult {\n status: \"valid\" | \"warning\" | \"invalid\";\n manifestHash: string;\n issues: ValidationIssue[];\n scopeImpact: ScopeImpact[];\n translationStatus: TranslationStatus;\n}\n\nexport interface ValidationOptions {\n requiredLocales?: string[];\n maxBundleSizeBytes?: number;\n supportedSdkMajor?: number;\n}\n\nconst riskyDependencyPatterns = [/child_process/i, /node:fs/i, /eval\\(/i];\n\nexport function validateManifest(\n manifest: AppManifest,\n options: ValidationOptions = {},\n): ValidationResult {\n const requiredLocales = options.requiredLocales ?? [...defaultRequiredLocales];\n const maxBundleSizeBytes = options.maxBundleSizeBytes ?? 512 * 1024;\n const supportedSdkMajor = options.supportedSdkMajor ?? 1;\n const issues: ValidationIssue[] = [];\n\n if (!manifest.name?.trim()) {\n issues.push(issue(\"manifest.name.missing\", \"blocker\", \"name\", \"App name is required.\"));\n }\n\n if (!manifest.manifestVersion?.trim()) {\n issues.push(issue(\"manifest.version.missing\", \"blocker\", \"manifestVersion\", \"Manifest version is required.\"));\n }\n\n if (!manifest.sdkVersion?.trim()) {\n issues.push(issue(\"sdk.version.missing\", \"blocker\", \"sdkVersion\", \"SDK version is required.\"));\n } else if (!isCompatibleSdk(manifest.sdkVersion, supportedSdkMajor)) {\n issues.push(\n issue(\n \"sdk.version.unsupported\",\n \"blocker\",\n \"sdkVersion\",\n `SDK version ${manifest.sdkVersion} is not compatible with this platform.`,\n \"Upgrade the app SDK and regenerate contracts.\",\n \"https://developer.hyprcart.com/docs/app-platform/sdk\",\n ),\n );\n }\n\n if (!Array.isArray(manifest.surfaces) || manifest.surfaces.length === 0) {\n issues.push(issue(\"surfaces.missing\", \"blocker\", \"surfaces\", \"At least one app surface is required.\"));\n }\n\n manifest.surfaces?.forEach((surface, index) => {\n const basePath = `surfaces.${index}`;\n if (!surface.id?.trim()) {\n issues.push(issue(\"surface.id.missing\", \"error\", `${basePath}.id`, \"Surface id is required.\"));\n }\n if (!isSupportedSurface(surface.type)) {\n issues.push(issue(\"surface.type.unsupported\", \"blocker\", `${basePath}.type`, `Unsupported surface type: ${surface.type}`));\n }\n if (!surface.entry?.trim()) {\n issues.push(issue(\"surface.entry.missing\", \"error\", `${basePath}.entry`, \"Surface entry file is required.\"));\n }\n if (surface.deployable === false) {\n issues.push(\n issue(\n \"surface.deferred\",\n \"warning\",\n `${basePath}.deployable`,\n \"This surface is marked as preview-only and will not be deployed.\",\n \"Remove the surface or mark it deployable when the platform supports it.\",\n ),\n );\n }\n });\n\n const translationStatus = getTranslationStatus(manifest, requiredLocales);\n for (const gap of translationStatus.missing) {\n issues.push(\n issue(\n \"validation.translation.missing\",\n gap.surface === \"storefront_block\" ? \"error\" : \"warning\",\n `translations.${gap.locale}.${gap.key}`,\n `Missing ${gap.locale} translation for ${gap.key}.`,\n \"Add the missing locale key before deployment.\",\n \"https://developer.hyprcart.com/docs/app-platform/translations\",\n ),\n );\n }\n\n if ((manifest.resources?.bundleSizeBytes ?? 0) > maxBundleSizeBytes) {\n issues.push(\n issue(\n \"bundle.size.exceeded\",\n \"blocker\",\n \"resources.bundleSizeBytes\",\n `Bundle size exceeds ${maxBundleSizeBytes} bytes.`,\n \"Remove unused dependencies or split the app surface.\",\n ),\n );\n }\n\n for (const domain of manifest.egress ?? []) {\n if (!domain.startsWith(\"https://\")) {\n issues.push(issue(\"egress.domain.invalid\", \"blocker\", \"egress\", \"Egress domains must use https.\"));\n }\n if (riskyDependencyPatterns.some((pattern) => pattern.test(domain))) {\n issues.push(issue(\"egress.domain.risky\", \"blocker\", \"egress\", \"Egress declaration contains risky content.\"));\n }\n }\n\n const blocker = issues.some((entry) => entry.severity === \"blocker\" || entry.severity === \"error\");\n const warning = issues.some((entry) => entry.severity === \"warning\");\n\n return {\n status: blocker ? \"invalid\" : warning ? \"warning\" : \"valid\",\n manifestHash: hashObject(manifest),\n issues,\n scopeImpact: (manifest.scopes ?? []).map((scope) => ({\n scope,\n action: \"added\",\n dataClass: classifyScope(scope),\n approvalRequired: scope.includes(\"write\") || scope.includes(\"customer\"),\n reason: \"Declared by app manifest.\",\n })),\n translationStatus,\n };\n}\n\nexport function getTranslationStatus(manifest: AppManifest, requiredLocales: string[]): TranslationStatus {\n const missing: TranslationGap[] = [];\n const completeLocales: string[] = [];\n\n for (const locale of requiredLocales) {\n const messages = manifest.translations?.[locale] ?? {};\n const before = missing.length;\n for (const surface of manifest.surfaces ?? []) {\n const labelKey = `${surface.id}.label`;\n if (!messages[labelKey]) {\n missing.push({ locale, key: labelKey, surface: surface.type });\n }\n }\n if (missing.length === before) {\n completeLocales.push(locale);\n }\n }\n\n return { requiredLocales, completeLocales, missing };\n}\n\nfunction issue(\n code: string,\n severity: ValidationSeverity,\n path: string,\n message: string,\n suggestedFix?: string,\n docsUrl?: string,\n): ValidationIssue {\n return { code, severity, path, message, suggestedFix, docsUrl };\n}\n\nfunction classifyScope(scope: string): string {\n if (scope.includes(\"customer\")) return \"customer\";\n if (scope.includes(\"order\")) return \"order\";\n if (scope.includes(\"product\")) return \"product\";\n return \"standard\";\n}\n\nfunction isCompatibleSdk(version: string, supportedMajor: number): boolean {\n const major = Number(version.split(\".\")[0]);\n return Number.isFinite(major) && major === supportedMajor;\n}\n\nfunction hashObject(value: unknown): string {\n const json = JSON.stringify(value, Object.keys(value as Record<string, unknown>).sort());\n let hash = 0;\n for (let index = 0; index < json.length; index += 1) {\n hash = (hash * 31 + json.charCodeAt(index)) >>> 0;\n }\n return `mf_${hash.toString(16).padStart(8, \"0\")}`;\n}\n","import type { AppManifest, AppManifestSurface } from \"./schema\";\n\nexport interface GeneratedContractFile {\n path: string;\n content: string;\n purpose: string;\n}\n\nexport interface ContractGenerationResult {\n manifestHash: string;\n schemaVersion: string;\n sdkVersion: string;\n files: GeneratedContractFile[];\n}\n\nexport function generateContracts(manifest: AppManifest, schemaVersion = \"2026-06-06\"): ContractGenerationResult {\n const surfaces = manifest.surfaces.map(renderSurfaceContract).join(\"\\n\\n\");\n const content = [\n \"/* Generated by Hyprcart app tooling. */\",\n `export const schemaVersion = ${JSON.stringify(schemaVersion)};`,\n `export const sdkVersion = ${JSON.stringify(manifest.sdkVersion)};`,\n surfaces,\n ].join(\"\\n\");\n\n return {\n manifestHash: stableHash(JSON.stringify(manifest)),\n schemaVersion,\n sdkVersion: manifest.sdkVersion,\n files: [\n {\n path: \"generated/hyprcart.contracts.ts\",\n content,\n purpose: \"typed surface contracts\",\n },\n ],\n };\n}\n\nfunction renderSurfaceContract(surface: AppManifestSurface): string {\n const name = toPascalCase(surface.id);\n return [\n `export interface ${name}Input {`,\n ` surface: ${JSON.stringify(surface.type)};`,\n \" context: Record<string, unknown>;\",\n \"}\",\n `export interface ${name}Output {`,\n \" html?: string;\",\n \" data?: Record<string, unknown>;\",\n \" events?: Array<Record<string, unknown>>;\",\n \"}\",\n `export const ${name}Contract = {`,\n ` id: ${JSON.stringify(surface.id)},`,\n ` type: ${JSON.stringify(surface.type)},`,\n ` entry: ${JSON.stringify(surface.entry)},`,\n ` scopes: ${JSON.stringify(surface.scopes ?? [])}`,\n \"} as const;\",\n ].join(\"\\n\");\n}\n\nfunction toPascalCase(value: string): string {\n return value\n .replace(/[^a-zA-Z0-9]+/g, \" \")\n .split(\" \")\n .filter(Boolean)\n .map((part) => `${part[0]?.toUpperCase() ?? \"\"}${part.slice(1)}`)\n .join(\"\");\n}\n\nfunction stableHash(value: string): string {\n let hash = 5381;\n for (let index = 0; index < value.length; index += 1) {\n hash = (hash * 33) ^ value.charCodeAt(index);\n }\n return `ct_${(hash >>> 0).toString(16).padStart(8, \"0\")}`;\n}\n","export interface CompatibilityResult {\n ok: boolean;\n code?: string;\n message?: string;\n docsUrl?: string;\n}\n\nexport function checkCompatibility(input: {\n cliVersion?: string;\n sdkVersion: string;\n platformVersion: string;\n requiredSdkMajor?: number;\n}): CompatibilityResult {\n const requiredSdkMajor = input.requiredSdkMajor ?? 1;\n const sdkMajor = Number(input.sdkVersion.split(\".\")[0]);\n\n if (!Number.isFinite(sdkMajor) || sdkMajor !== requiredSdkMajor) {\n return {\n ok: false,\n code: \"sdk.version.unsupported\",\n message: `SDK ${input.sdkVersion} is not compatible with platform ${input.platformVersion}.`,\n docsUrl: \"https://developer.hyprcart.com/docs/app-platform/sdk\",\n };\n }\n\n return { ok: true };\n}\n","import type { AppManifest } from \"./schema\";\nimport { generateContracts } from \"./contract-generation\";\nimport { validateManifest } from \"./validation\";\n\nexport function generateIdeMetadata(manifest: AppManifest) {\n const validation = validateManifest(manifest);\n const contracts = generateContracts(manifest);\n\n return {\n schemaVersion: contracts.schemaVersion,\n platformVersion: manifest.platformCompatibility,\n surfaceContracts: manifest.surfaces.map((surface) => ({\n surface: surface.type,\n inputTypeName: `${surface.id}Input`,\n outputTypeName: `${surface.id}Output`,\n fixtureTypeName: `${surface.id}Fixture`,\n scopes: surface.scopes ?? [],\n })),\n scopeWarnings: validation.scopeImpact,\n translationRequirements: validation.translationStatus,\n docsUrls: [\"https://developer.hyprcart.com/docs/app-platform/manifest\"],\n };\n}\n","export const developerToolingOperationMetadata = [\n {\n operationName: \"validateAppProject\",\n scopes: [\"app.validation:run\"],\n dataClass: \"developer_app\",\n costClass: \"standard\",\n idempotent: true,\n lifecycleEvents: [\"developer_tooling.validation_requested\"],\n docsStatus: \"public\",\n stability: \"preview\",\n },\n {\n operationName: \"requestDeveloperDeployment\",\n scopes: [\"app.deployment:write\"],\n dataClass: \"developer_app\",\n costClass: \"elevated\",\n idempotent: true,\n lifecycleEvents: [\"developer_tooling.deployment_requested\"],\n docsStatus: \"public\",\n stability: \"preview\",\n },\n] as const;\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hyprcart/app-manifest",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Manifest schema and validation helpers for Hyprcart apps.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public",
|
|
13
|
+
"registry": "https://registry.npmjs.org/"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"tsup": "^8.3.5",
|
|
25
|
+
"typescript": "^5.7.2",
|
|
26
|
+
"vitest": "^4.0.18",
|
|
27
|
+
"@repo/typescript-config": "0.0.1"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup",
|
|
31
|
+
"dev": "tsup --watch",
|
|
32
|
+
"lint": "tsc --noEmit",
|
|
33
|
+
"type-check": "tsc --noEmit",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"clean": "rm -rf dist .turbo"
|
|
36
|
+
}
|
|
37
|
+
}
|