@apps-in-toss/ait-format 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/dist/bundle.d.ts +113 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/format.d.ts +60 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +7 -0
- package/dist/reader.d.ts +93 -0
- package/dist/reader.d.ts.map +1 -0
- package/dist/utils/computeSha256Hex.d.ts +9 -0
- package/dist/utils/computeSha256Hex.d.ts.map +1 -0
- package/dist/utils/generateUUID7.d.ts +14 -0
- package/dist/utils/generateUUID7.d.ts.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/isValidUUID.d.ts +8 -0
- package/dist/utils/isValidUUID.d.ts.map +1 -0
- package/dist/writer.d.ts +90 -0
- package/dist/writer.d.ts.map +1 -0
- package/package.json +50 -0
package/dist/bundle.d.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for AIT (Apps-in-Toss) bundle operations.
|
|
3
|
+
*/
|
|
4
|
+
import { AITReader, AITReaderOptions } from "./reader";
|
|
5
|
+
import { AITWriter, AITWriterOptions } from "./writer";
|
|
6
|
+
import { Format } from "./format";
|
|
7
|
+
/**
|
|
8
|
+
* Main entry point for AIT bundle operations.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Writing (auto-generated UUIDv7 for deploymentId)
|
|
13
|
+
* const writer = AppsInTossBundle.writer({ appName: "app-name" });
|
|
14
|
+
* writer.setMetadata({ platform: PlatformType.REACT_NATIVE });
|
|
15
|
+
* writer.addFile("index.html", new TextEncoder().encode("<html>...</html>"));
|
|
16
|
+
* const buffer = await writer.toBuffer();
|
|
17
|
+
*
|
|
18
|
+
* // Writing with explicit deploymentId
|
|
19
|
+
* const writer = AppsInTossBundle.writer({
|
|
20
|
+
* deploymentId: "019bfa90-ad4c-799f-b227-b4159e6867f7",
|
|
21
|
+
* appName: "app-name",
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Reading
|
|
25
|
+
* const reader = AppsInTossBundle.reader(buffer);
|
|
26
|
+
* console.log(reader.deploymentId);
|
|
27
|
+
* console.log(reader.appName);
|
|
28
|
+
* const content = await reader.readEntry("index.html");
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class AppsInTossBundle {
|
|
32
|
+
private constructor();
|
|
33
|
+
/**
|
|
34
|
+
* Create a new writer.
|
|
35
|
+
*
|
|
36
|
+
* @param options Writer options including deploymentId and appName
|
|
37
|
+
* @returns AITWriter instance
|
|
38
|
+
*/
|
|
39
|
+
static writer(options: AITWriterOptions): AITWriter;
|
|
40
|
+
/**
|
|
41
|
+
* Create a reader from a Uint8Array buffer.
|
|
42
|
+
*
|
|
43
|
+
* @param buffer AIT file contents
|
|
44
|
+
* @param options Reader options
|
|
45
|
+
* @returns AITReader instance
|
|
46
|
+
*/
|
|
47
|
+
static reader(buffer: Uint8Array, options?: AITReaderOptions): AITReader;
|
|
48
|
+
/**
|
|
49
|
+
* Create a reader from an ArrayBuffer.
|
|
50
|
+
*
|
|
51
|
+
* @param buffer AIT file contents as ArrayBuffer
|
|
52
|
+
* @param options Reader options
|
|
53
|
+
* @returns AITReader instance
|
|
54
|
+
*/
|
|
55
|
+
static readerFromArrayBuffer(buffer: ArrayBuffer, options?: AITReaderOptions): AITReader;
|
|
56
|
+
/**
|
|
57
|
+
* Get the current format version.
|
|
58
|
+
*
|
|
59
|
+
* @returns Current format version
|
|
60
|
+
*/
|
|
61
|
+
static getFormatVersion(): number;
|
|
62
|
+
/**
|
|
63
|
+
* Get the magic bytes identifying AIT files.
|
|
64
|
+
*
|
|
65
|
+
* @returns Magic bytes
|
|
66
|
+
*/
|
|
67
|
+
static getMagic(): Uint8Array;
|
|
68
|
+
/**
|
|
69
|
+
* Bundle format types.
|
|
70
|
+
*/
|
|
71
|
+
static readonly Format: typeof Format;
|
|
72
|
+
/**
|
|
73
|
+
* Detect the bundle format from a buffer.
|
|
74
|
+
*
|
|
75
|
+
* @param buffer - The buffer to detect format from (only first 8 bytes are needed)
|
|
76
|
+
* @returns The detected format
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const buffer = await fs.readFile("bundle.ait");
|
|
81
|
+
* const format = AppsInTossBundle.detect(buffer);
|
|
82
|
+
*
|
|
83
|
+
* if (format === AppsInTossBundle.Format.AIT) {
|
|
84
|
+
* const reader = AppsInTossBundle.reader(buffer);
|
|
85
|
+
* // Process AIT bundle
|
|
86
|
+
* } else if (format === AppsInTossBundle.Format.ZIP) {
|
|
87
|
+
* // Process legacy ZIP bundle
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
static detect(buffer: Uint8Array): Format;
|
|
92
|
+
/**
|
|
93
|
+
* Check if the buffer represents an AIT format.
|
|
94
|
+
*
|
|
95
|
+
* @param buffer - The buffer to check (only first 8 bytes are needed)
|
|
96
|
+
* @returns true if AIT format
|
|
97
|
+
*/
|
|
98
|
+
static isAIT(buffer: Uint8Array): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Check if the buffer represents a ZIP format.
|
|
101
|
+
*
|
|
102
|
+
* @param buffer - The buffer to check (only first 4 bytes are needed)
|
|
103
|
+
* @returns true if ZIP format
|
|
104
|
+
*/
|
|
105
|
+
static isZIP(buffer: Uint8Array): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Generate a new UUIDv7 string.
|
|
108
|
+
*
|
|
109
|
+
* @returns A UUIDv7 string in standard format (8-4-4-4-12)
|
|
110
|
+
*/
|
|
111
|
+
static generateUUID7(): string;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEvD,OAAO,EAAgB,MAAM,EAAE,MAAM,UAAU,CAAC;AAGhD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO;IAIP;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS;IAInD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS;IAIxE;;;;;;OAMG;IACH,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS;IAIxF;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,IAAI,MAAM;IAIjC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,IAAI,UAAU;IAI7B;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM,gBAAU;IAEhC;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAIzC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAIzC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAIzC;;;;OAIG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;CAG/B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIT file format constants.
|
|
3
|
+
*/
|
|
4
|
+
/** Magic bytes identifying AIT files ("AITBUNDL") */
|
|
5
|
+
export declare const MAGIC: Uint8Array<ArrayBuffer>;
|
|
6
|
+
export declare const MAGIC_STRING = "AITBUNDL";
|
|
7
|
+
export declare const MAGIC_SIZE = 8;
|
|
8
|
+
/** Current format version */
|
|
9
|
+
export declare const FORMAT_VERSION = 1;
|
|
10
|
+
/** Header sizes (in bytes) */
|
|
11
|
+
export declare const VERSION_SIZE = 4;
|
|
12
|
+
export declare const LENGTH_SIZE = 8;
|
|
13
|
+
export declare const HEADER_SIZE: number;
|
|
14
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qDAAqD;AACrD,eAAO,MAAM,KAAK,yBAAmE,CAAC;AACtF,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,6BAA6B;AAC7B,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,8BAA8B;AAC9B,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,WAAW,QAA0C,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIT error classes.
|
|
3
|
+
*/
|
|
4
|
+
/** Base error for AIT operations */
|
|
5
|
+
export declare class AITError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/** Invalid AIT file format */
|
|
9
|
+
export declare class AITFormatError extends AITError {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
/** Unsupported AIT format version */
|
|
13
|
+
export declare class AITVersionError extends AITError {
|
|
14
|
+
constructor(message: string);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oCAAoC;AACpC,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM;CAI5B;AAED,8BAA8B;AAC9B,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,qCAAqC;AACrC,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM;CAI5B"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundle format detection utilities.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { BundleFormat, AITReader } from "@apps-in-toss/ait-format";
|
|
7
|
+
*
|
|
8
|
+
* const buffer = await fs.readFile("bundle.ait");
|
|
9
|
+
* const format = BundleFormat.detect(buffer);
|
|
10
|
+
*
|
|
11
|
+
* if (format === BundleFormat.Format.AIT) {
|
|
12
|
+
* const reader = AITReader.fromBuffer(buffer);
|
|
13
|
+
* // Process AIT bundle
|
|
14
|
+
* } else if (format === BundleFormat.Format.ZIP) {
|
|
15
|
+
* // Process legacy ZIP bundle
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Bundle format types.
|
|
21
|
+
*/
|
|
22
|
+
export declare enum Format {
|
|
23
|
+
/** AIT bundle format (AITBUNDL magic) */
|
|
24
|
+
AIT = "AIT",
|
|
25
|
+
/** Legacy ZIP format (PK magic) */
|
|
26
|
+
ZIP = "ZIP",
|
|
27
|
+
/** Unknown format */
|
|
28
|
+
UNKNOWN = "UNKNOWN"
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Bundle format detection utilities.
|
|
32
|
+
*/
|
|
33
|
+
export declare const BundleFormat: {
|
|
34
|
+
/**
|
|
35
|
+
* Format enum for convenience.
|
|
36
|
+
*/
|
|
37
|
+
readonly Format: typeof Format;
|
|
38
|
+
/**
|
|
39
|
+
* Detect the bundle format from a buffer.
|
|
40
|
+
*
|
|
41
|
+
* @param buffer - The buffer to detect format from (only first 8 bytes are needed)
|
|
42
|
+
* @returns The detected format
|
|
43
|
+
*/
|
|
44
|
+
readonly detect: (buffer: Uint8Array) => Format;
|
|
45
|
+
/**
|
|
46
|
+
* Check if the buffer represents an AIT format.
|
|
47
|
+
*
|
|
48
|
+
* @param buffer - The buffer to check (only first 8 bytes are needed)
|
|
49
|
+
* @returns true if AIT format
|
|
50
|
+
*/
|
|
51
|
+
readonly isAIT: (buffer: Uint8Array) => boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Check if the buffer represents a ZIP format.
|
|
54
|
+
*
|
|
55
|
+
* @param buffer - The buffer to check (only first 4 bytes are needed)
|
|
56
|
+
* @returns true if ZIP format
|
|
57
|
+
*/
|
|
58
|
+
readonly isZIP: (buffer: Uint8Array) => boolean;
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH;;GAEG;AACH,oBAAY,MAAM;IAChB,yCAAyC;IACzC,GAAG,QAAQ;IACX,mCAAmC;IACnC,GAAG,QAAQ;IACX,qBAAqB;IACrB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;;IAGH;;;;;OAKG;8BACY,UAAU,KAAG,MAAM;IAgClC;;;;;OAKG;6BACW,UAAU,KAAG,OAAO;IAYlC;;;;;OAKG;6BACW,UAAU,KAAG,OAAO;CAW1B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIT Format - Protocol Buffer definitions and reader/writer for Apps-in-Toss bundle format.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export * from "@apps-in-toss/ait-format-proto";
|
|
7
|
+
export { FORMAT_VERSION, MAGIC, MAGIC_STRING, HEADER_SIZE } from "./constants";
|
|
8
|
+
export { AITError, AITFormatError, AITVersionError } from "./errors";
|
|
9
|
+
export { AppsInTossBundle } from "./bundle";
|
|
10
|
+
export { AITReader, type AITReaderOptions, type AppJson, type AppJsonMetadata } from "./reader";
|
|
11
|
+
export { AITWriter, type AITWriterOptions, type MetadataOptions } from "./writer";
|
|
12
|
+
export { BundleFormat, Format } from "./format";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,gCAAgC,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/E,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAChG,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAGlF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var k=Object.create;var V=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var J=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var W=(r,e)=>{for(var t in e)V(r,t,{get:e[t],enumerable:!0})},E=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of L(e))!C.call(r,i)&&i!==t&&V(r,i,{get:()=>e[i],enumerable:!(n=G(e,i))||n.enumerable});return r},f=(r,e,t)=>(E(r,e,"default"),t&&E(t,e,"default")),S=(r,e,t)=>(t=r!=null?k(J(r)):{},E(e||!r||!r.__esModule?V(t,"default",{value:r,enumerable:!0}):t,r)),$=r=>E(V({},"__esModule",{value:!0}),r);var l={};W(l,{AITError:()=>b,AITFormatError:()=>p,AITReader:()=>g,AITVersionError:()=>x,AITWriter:()=>B,AppsInTossBundle:()=>O,BundleFormat:()=>T,FORMAT_VERSION:()=>m,Format:()=>w,HEADER_SIZE:()=>F,MAGIC:()=>o,MAGIC_STRING:()=>M});module.exports=$(l);f(l,require("@apps-in-toss/ait-format-proto"),module.exports);var o=new Uint8Array([65,73,84,66,85,78,68,76]),M="AITBUNDL",A=8,m=1,h=4,d=8,F=A+h+d;var b=class extends Error{constructor(e){super(e),this.name="AITError"}},p=class extends b{constructor(e){super(e),this.name="AITFormatError"}},x=class extends b{constructor(e){super(e),this.name="AITVersionError"}};var Z=require("@apps-in-toss/ait-format-proto");var g=class r{buffer;view;supportedVersions;_formatVersion=0;_bundle=null;_zipBlobOffset=0;_zipBlobLength=0;constructor(e,t){this.buffer=e,this.view=new DataView(e.buffer,e.byteOffset,e.byteLength),this.supportedVersions=t?.supportedVersions??[m],this.readHeader(),this.readBundle(),this.readZipHeader()}static fromBuffer(e,t){return new r(e,t)}static fromArrayBuffer(e,t){return new r(new Uint8Array(e),t)}readHeader(){if(this.buffer.length<A+h+d)throw new p("Buffer too small to be a valid AIT file");let e=this.buffer.slice(0,A);if(!this.arraysEqual(e,o))throw new p(`Invalid magic bytes: expected AITBUNDL, got ${new TextDecoder().decode(e)}`);if(this._formatVersion=this.view.getUint32(A,!1),!this.supportedVersions.includes(this._formatVersion))throw new x(`Unsupported format version: ${this._formatVersion}, supported: [${this.supportedVersions.join(", ")}]`)}readBundle(){let e=A+h,t=Number(this.view.getBigUint64(e,!1)),n=e+d;if(this.buffer.length<n+t)throw new p("Unexpected end of buffer reading bundle");let i=this.buffer.slice(n,n+t);if(this._bundle=Z.AITBundle.decode(i),!this._bundle.deploymentId)throw new p("Bundle deployment_id must not be empty");if(!this._bundle.appName)throw new p("Bundle app_name must not be empty");this._zipBlobOffset=n+t}readZipHeader(){if(this.buffer.length<this._zipBlobOffset+d)throw new p("Unexpected end of buffer reading ZIP blob length");this._zipBlobLength=Number(this.view.getBigUint64(this._zipBlobOffset,!1)),this._zipBlobOffset+=d}arraysEqual(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}get formatVersion(){return this._formatVersion}get deploymentId(){return this._bundle?.deploymentId??""}get appName(){return this._bundle?.appName??""}get bundle(){if(!this._bundle)throw new p("Bundle not loaded");return this._bundle}get metadata(){return this._bundle?.metadata}get permissions(){return this._bundle?.permissions??[]}readZipBlob(){return this.buffer.slice(this._zipBlobOffset,this._zipBlobOffset+this._zipBlobLength)}async readEntry(e){let{unzipSync:t}=await import("fflate"),n=this.readZipBlob(),s=t(n)[e];if(!s)throw new Error(`Entry not found: ${e}`);return s}listEntries(){return this._bundle?.index.map(e=>e.name)??[]}readSignature(){let e=this._zipBlobOffset+this._zipBlobLength;if(this.buffer.length<e+d)return null;let t=Number(this.view.getBigUint64(e,!1));if(t===0)return null;let n=e+d;return this.buffer.length<n+t?null:this.buffer.slice(n,n+t)}toAppJson(){let e={appName:this._bundle?.appName??"",permissions:(this._bundle?.permissions??[]).map(n=>({name:n.name,access:n.access})),_metadata:{deploymentId:this._bundle?.deploymentId??""}},t=this._bundle?.metadata;return t&&(t.runtimeVersion&&(e._metadata.runtimeVersion=t.runtimeVersion),t.bundleFiles&&t.bundleFiles.length>0&&(e._metadata.bundleFiles=[...t.bundleFiles]),t.packageJson&&(e._metadata.packageJson=t.packageJson),t.sdkVersion&&(e._metadata.sdkVersion=t.sdkVersion)),e}};var I=require("@apps-in-toss/ait-format-proto");function _(){let r=Date.now(),e=new Uint8Array(10);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(e);else for(let c=0;c<10;c++)e[c]=Math.floor(Math.random()*256);let t=(c,D)=>c.toString(16).padStart(D,"0"),n=c=>c.toString(16).padStart(2,"0"),i=Math.floor(r/65536),s=r&65535,N=t(i,8),u=t(s,4),y=28672|(e[0]<<4|e[1]>>4)&4095,a=t(y,4),z=32768|((e[1]&15)<<10|e[2]<<2|e[3]>>6)&16383,P=t(z,4),H=n(e[4])+n(e[5])+n(e[6])+n(e[7])+n(e[8])+n(e[9]);return`${N}-${u}-${a}-${P}-${H}`}function v(r){let e=r.toLowerCase().split("-");if(e.length!==5||e[0]?.length!==8||e[1]?.length!==4||e[2]?.length!==4||e[3]?.length!==4||e[4]?.length!==12)return!1;let t=/^[0-9a-f]+$/;return e.every(n=>t.test(n))}async function R(r){let e=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}var B=class{formatVersion;deploymentId;appName;createdBy;metadata=void 0;permissions=[];files=[];signature=null;constructor(e){if(!e.appName)throw new Error("appName must not be empty");if(e.deploymentId===void 0)this.deploymentId=_();else{if(!e.deploymentId)throw new Error("deploymentId must not be empty");if(!v(e.deploymentId))throw new Error("deploymentId must be a valid UUID format (e.g., '019bfa90-ad4c-799f-b227-b4159e6867f7')");this.deploymentId=e.deploymentId}this.formatVersion=e.formatVersion??m,this.appName=e.appName,this.createdBy=e.createdBy??""}setMetadata(e){return this.metadata={isGame:e.isGame??!1,platform:e.platform??I.PlatformType.PLATFORM_UNSPECIFIED,runtimeVersion:e.runtimeVersion??"",bundleFiles:e.bundleFiles??[],packageJson:e.packageJson,sdkVersion:e.sdkVersion??"",extra:e.extra},this}addPermission(e,t){return this.permissions.push({name:e,access:t}),this}addFile(e,t,n){return this.files.push({name:e,data:t,compress:n?.compress??!0}),this}setSignature(e){return this.signature=e,this}async buildZipBlob(){let{zipSync:e}=await import("fflate"),t={};for(let s of this.files)t[s.name]=s.data;let n=e(t,{level:6}),i=await Promise.all(this.files.map(async s=>({name:s.name,zipOffset:BigInt(0),compressedSize:BigInt(0),uncompressedSize:BigInt(s.data.length),compMethod:s.compress?I.CompressionMethod.DEFLATE:I.CompressionMethod.NONE,sha256Hex:await R(s.data),attrs:void 0})));return{zipBytes:n,index:i}}buildBundle(e){return{formatVersion:this.formatVersion,deploymentId:this.deploymentId,appName:this.appName,metadata:this.metadata,permissions:this.permissions,index:e,createdBy:this.createdBy,createdAtMs:BigInt(Date.now())}}async toBuffer(){let{zipBytes:e,index:t}=await this.buildZipBlob(),n=this.buildBundle(t),i=I.AITBundle.encode(n).finish(),s=this.signature??new Uint8Array(0),N=o.length+h+d+i.length+d+e.length+d+s.length,u=new Uint8Array(N),y=new DataView(u.buffer),a=0;return u.set(o,a),a+=o.length,y.setUint32(a,this.formatVersion,!1),a+=h,y.setBigUint64(a,BigInt(i.length),!1),a+=d,u.set(i,a),a+=i.length,y.setBigUint64(a,BigInt(e.length),!1),a+=d,u.set(e,a),a+=e.length,y.setBigUint64(a,BigInt(s.length),!1),a+=d,s.length>0&&u.set(s,a),u}};var U=new Uint8Array([80,75,3,4]),w=(n=>(n.AIT="AIT",n.ZIP="ZIP",n.UNKNOWN="UNKNOWN",n))(w||{}),T={Format:w,detect(r){if(r.length>=o.length){let e=!0;for(let t=0;t<o.length;t++)if(r[t]!==o[t]){e=!1;break}if(e)return"AIT"}if(r.length>=U.length){let e=!0;for(let t=0;t<U.length;t++)if(r[t]!==U[t]){e=!1;break}if(e)return"ZIP"}return"UNKNOWN"},isAIT(r){if(r.length<o.length)return!1;for(let e=0;e<o.length;e++)if(r[e]!==o[e])return!1;return!0},isZIP(r){if(r.length<U.length)return!1;for(let e=0;e<U.length;e++)if(r[e]!==U[e])return!1;return!0}};var O=class{constructor(){throw new Error("AppsInTossBundle is a utility class and cannot be instantiated")}static writer(e){return new B(e)}static reader(e,t){return g.fromBuffer(e,t)}static readerFromArrayBuffer(e,t){return g.fromArrayBuffer(e,t)}static getFormatVersion(){return m}static getMagic(){return o}static Format=w;static detect(e){return T.detect(e)}static isAIT(e){return T.isAIT(e)}static isZIP(e){return T.isZIP(e)}static generateUUID7(){return _()}};0&&(module.exports={AITError,AITFormatError,AITReader,AITVersionError,AITWriter,AppsInTossBundle,BundleFormat,FORMAT_VERSION,Format,HEADER_SIZE,MAGIC,MAGIC_STRING,...require("@apps-in-toss/ait-format-proto")});
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/constants.ts", "../src/errors.ts", "../src/reader.ts", "../src/writer.ts", "../src/utils/generateUUID7.ts", "../src/utils/isValidUUID.ts", "../src/utils/computeSha256Hex.ts", "../src/format.ts", "../src/bundle.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * AIT Format - Protocol Buffer definitions and reader/writer for Apps-in-Toss bundle format.\n *\n * @packageDocumentation\n */\n\n// Re-export protobuf types from generated package\nexport * from \"@apps-in-toss/ait-format-proto\";\n\n// Constants\nexport { FORMAT_VERSION, MAGIC, MAGIC_STRING, HEADER_SIZE } from \"./constants\";\n\n// Errors\nexport { AITError, AITFormatError, AITVersionError } from \"./errors\";\n\n// Main entry point\nexport { AppsInTossBundle } from \"./bundle\";\n\n// Reader/Writer\nexport { AITReader, type AITReaderOptions, type AppJson, type AppJsonMetadata } from \"./reader\";\nexport { AITWriter, type AITWriterOptions, type MetadataOptions } from \"./writer\";\n\n// Format detection\nexport { BundleFormat, Format } from \"./format\";\n", "/**\n * AIT file format constants.\n */\n\n/** Magic bytes identifying AIT files (\"AITBUNDL\") */\nexport const MAGIC = new Uint8Array([0x41, 0x49, 0x54, 0x42, 0x55, 0x4e, 0x44, 0x4c]);\nexport const MAGIC_STRING = \"AITBUNDL\";\nexport const MAGIC_SIZE = 8;\n\n/** Current format version */\nexport const FORMAT_VERSION = 1;\n\n/** Header sizes (in bytes) */\nexport const VERSION_SIZE = 4;\nexport const LENGTH_SIZE = 8;\nexport const HEADER_SIZE = MAGIC_SIZE + VERSION_SIZE + LENGTH_SIZE; // 20 bytes\n\n", "/**\n * AIT error classes.\n */\n\n/** Base error for AIT operations */\nexport class AITError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AITError\";\n }\n}\n\n/** Invalid AIT file format */\nexport class AITFormatError extends AITError {\n constructor(message: string) {\n super(message);\n this.name = \"AITFormatError\";\n }\n}\n\n/** Unsupported AIT format version */\nexport class AITVersionError extends AITError {\n constructor(message: string) {\n super(message);\n this.name = \"AITVersionError\";\n }\n}\n\n", "/**\n * AIT file reader implementation.\n */\n\nimport { AITBundle, AITMetadata, Permission } from \"@apps-in-toss/ait-format-proto\";\nimport { FORMAT_VERSION, LENGTH_SIZE, MAGIC, MAGIC_SIZE, VERSION_SIZE } from \"./constants\";\nimport { AITFormatError, AITVersionError } from \"./errors\";\n\nexport interface AITReaderOptions {\n /** Tuple of supported format versions */\n supportedVersions?: number[];\n}\n\n/**\n * Reader for AIT (Apps-in-Toss) bundle files.\n *\n * @example\n * ```typescript\n * const reader = AITReader.fromBuffer(buffer);\n * console.log(reader.deploymentId);\n * console.log(reader.appName);\n * console.log(reader.metadata);\n * const data = await reader.readEntry(\"index.html\");\n * ```\n */\nexport class AITReader {\n private readonly buffer: Uint8Array;\n private readonly view: DataView;\n private readonly supportedVersions: number[];\n\n private _formatVersion: number = 0;\n private _bundle: AITBundle | null = null;\n private _zipBlobOffset: number = 0;\n private _zipBlobLength: number = 0;\n\n private constructor(buffer: Uint8Array, options?: AITReaderOptions) {\n this.buffer = buffer;\n this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n this.supportedVersions = options?.supportedVersions ?? [FORMAT_VERSION];\n\n this.readHeader();\n this.readBundle();\n this.readZipHeader();\n }\n\n /**\n * Create an AITReader from a buffer.\n */\n static fromBuffer(buffer: Uint8Array, options?: AITReaderOptions): AITReader {\n return new AITReader(buffer, options);\n }\n\n /**\n * Create an AITReader from an ArrayBuffer.\n */\n static fromArrayBuffer(buffer: ArrayBuffer, options?: AITReaderOptions): AITReader {\n return new AITReader(new Uint8Array(buffer), options);\n }\n\n private readHeader(): void {\n // Validate minimum size\n if (this.buffer.length < MAGIC_SIZE + VERSION_SIZE + LENGTH_SIZE) {\n throw new AITFormatError(\"Buffer too small to be a valid AIT file\");\n }\n\n // Validate magic\n const magic = this.buffer.slice(0, MAGIC_SIZE);\n if (!this.arraysEqual(magic, MAGIC)) {\n throw new AITFormatError(\n `Invalid magic bytes: expected AITBUNDL, got ${new TextDecoder().decode(magic)}`\n );\n }\n\n // Read version\n this._formatVersion = this.view.getUint32(MAGIC_SIZE, false);\n if (!this.supportedVersions.includes(this._formatVersion)) {\n throw new AITVersionError(\n `Unsupported format version: ${this._formatVersion}, supported: [${this.supportedVersions.join(\", \")}]`\n );\n }\n }\n\n private readBundle(): void {\n const bundleLenOffset = MAGIC_SIZE + VERSION_SIZE;\n const bundleLen = Number(this.view.getBigUint64(bundleLenOffset, false));\n\n const bundleOffset = bundleLenOffset + LENGTH_SIZE;\n if (this.buffer.length < bundleOffset + bundleLen) {\n throw new AITFormatError(\"Unexpected end of buffer reading bundle\");\n }\n\n const bundleBytes = this.buffer.slice(bundleOffset, bundleOffset + bundleLen);\n this._bundle = AITBundle.decode(bundleBytes);\n\n if (!this._bundle.deploymentId) {\n throw new AITFormatError(\"Bundle deployment_id must not be empty\");\n }\n if (!this._bundle.appName) {\n throw new AITFormatError(\"Bundle app_name must not be empty\");\n }\n\n // Update offset for ZIP header\n this._zipBlobOffset = bundleOffset + bundleLen;\n }\n\n private readZipHeader(): void {\n if (this.buffer.length < this._zipBlobOffset + LENGTH_SIZE) {\n throw new AITFormatError(\"Unexpected end of buffer reading ZIP blob length\");\n }\n\n this._zipBlobLength = Number(this.view.getBigUint64(this._zipBlobOffset, false));\n this._zipBlobOffset += LENGTH_SIZE; // Now points to actual ZIP data\n }\n\n private arraysEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n /** Get the format version */\n get formatVersion(): number {\n return this._formatVersion;\n }\n\n /** Get the deployment ID */\n get deploymentId(): string {\n return this._bundle?.deploymentId ?? \"\";\n }\n\n /** Get the application name */\n get appName(): string {\n return this._bundle?.appName ?? \"\";\n }\n\n /** Get the bundle */\n get bundle(): AITBundle {\n if (!this._bundle) {\n throw new AITFormatError(\"Bundle not loaded\");\n }\n return this._bundle;\n }\n\n /** Get the metadata */\n get metadata(): AITMetadata | undefined {\n return this._bundle?.metadata;\n }\n\n /** Get the permissions */\n get permissions(): Permission[] {\n return this._bundle?.permissions ?? [];\n }\n\n /**\n * Read the entire ZIP blob.\n */\n readZipBlob(): Uint8Array {\n return this.buffer.slice(this._zipBlobOffset, this._zipBlobOffset + this._zipBlobLength);\n }\n\n /**\n * Read a single entry from the ZIP blob.\n */\n async readEntry(name: string): Promise<Uint8Array> {\n const { unzipSync } = await import(\"fflate\");\n const zipBlob = this.readZipBlob();\n const unzipped = unzipSync(zipBlob);\n\n const entry = unzipped[name];\n if (!entry) {\n throw new Error(`Entry not found: ${name}`);\n }\n\n return entry;\n }\n\n /**\n * List all entry names in the ZIP blob.\n */\n listEntries(): string[] {\n return this._bundle?.index.map((entry) => entry.name) ?? [];\n }\n\n /**\n * Read the signature if present.\n */\n readSignature(): Uint8Array | null {\n const sigLenOffset = this._zipBlobOffset + this._zipBlobLength;\n if (this.buffer.length < sigLenOffset + LENGTH_SIZE) {\n return null;\n }\n\n const sigLen = Number(this.view.getBigUint64(sigLenOffset, false));\n if (sigLen === 0) {\n return null;\n }\n\n const sigOffset = sigLenOffset + LENGTH_SIZE;\n if (this.buffer.length < sigOffset + sigLen) {\n return null;\n }\n\n return this.buffer.slice(sigOffset, sigOffset + sigLen);\n }\n\n /**\n * Convert bundle to app.json format.\n *\n * @returns Object in app.json format with appName, permissions, and _metadata.\n */\n toAppJson(): AppJson {\n const result: AppJson = {\n appName: this._bundle?.appName ?? \"\",\n permissions: (this._bundle?.permissions ?? []).map((p) => ({\n name: p.name,\n access: p.access,\n })),\n _metadata: {\n deploymentId: this._bundle?.deploymentId ?? \"\",\n },\n };\n\n // Add metadata fields if present\n const meta = this._bundle?.metadata;\n if (meta) {\n if (meta.runtimeVersion) {\n result._metadata.runtimeVersion = meta.runtimeVersion;\n }\n if (meta.bundleFiles && meta.bundleFiles.length > 0) {\n result._metadata.bundleFiles = [...meta.bundleFiles];\n }\n if (meta.packageJson) {\n result._metadata.packageJson = meta.packageJson as Record<string, unknown>;\n }\n if (meta.sdkVersion) {\n result._metadata.sdkVersion = meta.sdkVersion;\n }\n }\n\n return result;\n }\n}\n\n/** app.json format */\nexport interface AppJson {\n appName: string;\n permissions: Array<{ name: string; access: string }>;\n _metadata: AppJsonMetadata;\n}\n\nexport interface AppJsonMetadata {\n deploymentId: string;\n runtimeVersion?: string;\n bundleFiles?: string[];\n packageJson?: Record<string, unknown>;\n sdkVersion?: string;\n}\n", "/**\n * AIT file writer implementation.\n */\n\nimport {\n AITBundle,\n AITMetadata,\n Permission,\n ZipIndexEntry,\n CompressionMethod,\n PlatformType,\n} from \"@apps-in-toss/ait-format-proto\";\nimport { FORMAT_VERSION, LENGTH_SIZE, MAGIC, VERSION_SIZE } from \"./constants\";\nimport { computeSha256Hex, generateUUID7, isValidUUID } from \"./utils\";\n\nexport interface AITWriterOptions {\n /** Application name (required) */\n appName: string;\n /** Unique identifier for this deployment. If not provided, a UUIDv7 will be auto-generated. */\n deploymentId?: string;\n /** AIT format version (default: current version) */\n formatVersion?: number;\n /** Creator info string (e.g., \"my-service/1.0.0\") */\n createdBy?: string;\n}\n\nexport interface MetadataOptions {\n /** Whether this is a game app */\n isGame?: boolean;\n /** Platform type (WEB or REACT_NATIVE) */\n platform?: PlatformType;\n /** Runtime version string */\n runtimeVersion?: string;\n /** List of bundle file names */\n bundleFiles?: string[];\n /** Package JSON content */\n packageJson?: Record<string, unknown>;\n /** Additional metadata */\n extra?: Record<string, unknown>;\n /** SDK Version */\n sdkVersion?: string;\n}\n\ninterface FileEntry {\n name: string;\n data: Uint8Array;\n compress: boolean;\n}\n\n/**\n * Writer for AIT (Apps-in-Toss) bundle files.\n *\n * @example\n * ```typescript\n * // With auto-generated UUIDv7\n * const writer = new AITWriter({ appName: \"my-app\" });\n * writer.setMetadata({ isGame: false, platform: PlatformType.WEB });\n * writer.addFile(\"index.html\", new TextEncoder().encode(\"<html>...</html>\"));\n * const buffer = await writer.toBuffer();\n *\n * // With explicit deployment ID\n * const writer = new AITWriter({\n * deploymentId: \"019bfa90-ad4c-799f-b227-b4159e6867f7\",\n * appName: \"my-app\"\n * });\n * ```\n */\nexport class AITWriter {\n private readonly formatVersion: number;\n private readonly deploymentId: string;\n private readonly appName: string;\n private readonly createdBy: string;\n private metadata: AITMetadata | undefined = undefined;\n private readonly permissions: Permission[] = [];\n private readonly files: FileEntry[] = [];\n private signature: Uint8Array | null = null;\n\n constructor(options: AITWriterOptions) {\n if (!options.appName) {\n throw new Error(\"appName must not be empty\");\n }\n\n if (options.deploymentId === undefined) {\n // Auto-generate UUIDv7\n this.deploymentId = generateUUID7();\n } else {\n if (!options.deploymentId) {\n throw new Error(\"deploymentId must not be empty\");\n }\n if (!isValidUUID(options.deploymentId)) {\n throw new Error(\n \"deploymentId must be a valid UUID format (e.g., '019bfa90-ad4c-799f-b227-b4159e6867f7')\"\n );\n }\n this.deploymentId = options.deploymentId;\n }\n\n this.formatVersion = options.formatVersion ?? FORMAT_VERSION;\n this.appName = options.appName;\n this.createdBy = options.createdBy ?? \"\";\n }\n\n /**\n * Set the bundle metadata.\n */\n setMetadata(options: MetadataOptions): this {\n this.metadata = {\n isGame: options.isGame ?? false,\n platform: options.platform ?? PlatformType.PLATFORM_UNSPECIFIED,\n runtimeVersion: options.runtimeVersion ?? \"\",\n bundleFiles: options.bundleFiles ?? [],\n packageJson: options.packageJson,\n sdkVersion: options.sdkVersion ?? '',\n extra: options.extra,\n };\n return this;\n }\n\n /**\n * Add a permission entry.\n */\n addPermission(name: string, access: string): this {\n this.permissions.push({ name, access });\n return this;\n }\n\n /**\n * Add a file to the bundle.\n */\n addFile(name: string, data: Uint8Array, options?: { compress?: boolean }): this {\n this.files.push({\n name,\n data,\n compress: options?.compress ?? true,\n });\n return this;\n }\n\n /**\n * Set the digital signature.\n */\n setSignature(signature: Uint8Array): this {\n this.signature = signature;\n return this;\n }\n\n /**\n * Build the ZIP blob and index entries.\n */\n private async buildZipBlob(): Promise<{ zipBytes: Uint8Array; index: ZipIndexEntry[] }> {\n const { zipSync } = await import(\"fflate\");\n\n const zipInput: Record<string, Uint8Array> = {};\n for (const file of this.files) {\n zipInput[file.name] = file.data;\n }\n\n const zipBytes = zipSync(zipInput, { level: 6 });\n\n // Build index entries with SHA256 hashes\n const index: ZipIndexEntry[] = await Promise.all(\n this.files.map(async (file) => ({\n name: file.name,\n zipOffset: BigInt(0), // Simplified - actual offset would need ZIP parsing\n compressedSize: BigInt(0),\n uncompressedSize: BigInt(file.data.length),\n compMethod: file.compress ? CompressionMethod.DEFLATE : CompressionMethod.NONE,\n sha256Hex: await computeSha256Hex(file.data),\n attrs: undefined,\n }))\n );\n\n return { zipBytes, index };\n }\n\n /**\n * Build the bundle protobuf message.\n */\n private buildBundle(index: ZipIndexEntry[]): AITBundle {\n return {\n formatVersion: this.formatVersion,\n deploymentId: this.deploymentId,\n appName: this.appName,\n metadata: this.metadata,\n permissions: this.permissions,\n index,\n createdBy: this.createdBy,\n createdAtMs: BigInt(Date.now()),\n };\n }\n\n /**\n * Serialize the AIT bundle to a buffer.\n */\n async toBuffer(): Promise<Uint8Array> {\n const { zipBytes, index } = await this.buildZipBlob();\n const bundle = this.buildBundle(index);\n const bundleBytes = AITBundle.encode(bundle).finish();\n\n // Calculate total size\n const signatureBytes = this.signature ?? new Uint8Array(0);\n const totalSize =\n MAGIC.length +\n VERSION_SIZE +\n LENGTH_SIZE +\n bundleBytes.length +\n LENGTH_SIZE +\n zipBytes.length +\n LENGTH_SIZE +\n signatureBytes.length;\n\n const buffer = new Uint8Array(totalSize);\n const view = new DataView(buffer.buffer);\n let offset = 0;\n\n // Write MAGIC\n buffer.set(MAGIC, offset);\n offset += MAGIC.length;\n\n // Write FORMAT_VERSION (big-endian)\n view.setUint32(offset, this.formatVersion, false);\n offset += VERSION_SIZE;\n\n // Write BUNDLE_LEN (big-endian uint64)\n view.setBigUint64(offset, BigInt(bundleBytes.length), false);\n offset += LENGTH_SIZE;\n\n // Write BUNDLE_BYTES\n buffer.set(bundleBytes, offset);\n offset += bundleBytes.length;\n\n // Write ZIP_BLOB_LEN (big-endian uint64)\n view.setBigUint64(offset, BigInt(zipBytes.length), false);\n offset += LENGTH_SIZE;\n\n // Write ZIP_BLOB_BYTES\n buffer.set(zipBytes, offset);\n offset += zipBytes.length;\n\n // Write SIGNATURE_LEN (big-endian uint64)\n view.setBigUint64(offset, BigInt(signatureBytes.length), false);\n offset += LENGTH_SIZE;\n\n // Write SIGNATURE_BYTES\n if (signatureBytes.length > 0) {\n buffer.set(signatureBytes, offset);\n }\n\n return buffer;\n }\n}\n", "/**\n * Generate a UUID version 7 (time-ordered UUID).\n *\n * UUID v7 format:\n * - 48 bits: Unix timestamp in milliseconds\n * - 4 bits: Version (0111 for v7)\n * - 12 bits: Random data\n * - 2 bits: Variant (10 for RFC 4122)\n * - 62 bits: Random data\n *\n * @returns A UUIDv7 string in standard format (8-4-4-4-12)\n */\nexport function generateUUID7(): string {\n const timestamp = Date.now();\n\n // Generate random bytes (need 10 bytes: 2 for version field, 2 for variant field, 6 for node)\n const randomBytes = new Uint8Array(10);\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(randomBytes);\n } else {\n // Fallback for environments without crypto\n for (let i = 0; i < 10; i++) {\n randomBytes[i] = Math.floor(Math.random() * 256);\n }\n }\n\n const hex = (n: number, len: number) => n.toString(16).padStart(len, \"0\");\n const byteToHex = (b: number) => b.toString(16).padStart(2, \"0\");\n\n // First 48 bits: timestamp (split into 32-bit high + 16-bit low)\n const timeHigh = Math.floor(timestamp / 0x10000);\n const timeLow = timestamp & 0xffff;\n\n // time-high (32 bits) = first 8 hex chars\n const timeHighHex = hex(timeHigh, 8);\n // time-low (16 bits) = next 4 hex chars\n const timeLowHex = hex(timeLow, 4);\n\n // Next 16 bits: 4-bit version (0111) + 12-bit random\n const versionAndRandom = 0x7000 | (((randomBytes[0]! << 4) | (randomBytes[1]! >> 4)) & 0x0fff);\n const versionHex = hex(versionAndRandom, 4);\n\n // Next 16 bits: 2-bit variant (10) + 14-bit random\n const variantAndRandom =\n 0x8000 |\n ((((randomBytes[1]! & 0x0f) << 10) | (randomBytes[2]! << 2) | (randomBytes[3]! >> 6)) & 0x3fff);\n const variantHex = hex(variantAndRandom, 4);\n\n // Last 48 bits: random (6 bytes)\n const nodeHex =\n byteToHex(randomBytes[4]!) +\n byteToHex(randomBytes[5]!) +\n byteToHex(randomBytes[6]!) +\n byteToHex(randomBytes[7]!) +\n byteToHex(randomBytes[8]!) +\n byteToHex(randomBytes[9]!);\n\n return `${timeHighHex}-${timeLowHex}-${versionHex}-${variantHex}-${nodeHex}`;\n}\n", "/**\n * Validate if a string is a valid UUID format.\n *\n * @param uuid The string to validate\n * @returns true if the string is a valid UUID format\n */\nexport function isValidUUID(uuid: string): boolean {\n // UUID format: 8-4-4-4-12 hex characters\n const parts = uuid.toLowerCase().split(\"-\");\n if (parts.length !== 5) return false;\n if (parts[0]?.length !== 8) return false;\n if (parts[1]?.length !== 4) return false;\n if (parts[2]?.length !== 4) return false;\n if (parts[3]?.length !== 4) return false;\n if (parts[4]?.length !== 12) return false;\n\n // Check all characters are valid hex\n const hexPattern = /^[0-9a-f]+$/;\n return parts.every((part) => hexPattern.test(part));\n}\n", "/**\n * Compute SHA256 hash of data and return as hex string.\n * Uses SubtleCrypto for browser compatibility.\n *\n * @param data The data to hash\n * @returns SHA256 hash as lowercase hex string\n */\nexport async function computeSha256Hex(data: Uint8Array): Promise<string> {\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n", "/**\n * Bundle format detection utilities.\n *\n * @example\n * ```typescript\n * import { BundleFormat, AITReader } from \"@apps-in-toss/ait-format\";\n *\n * const buffer = await fs.readFile(\"bundle.ait\");\n * const format = BundleFormat.detect(buffer);\n *\n * if (format === BundleFormat.Format.AIT) {\n * const reader = AITReader.fromBuffer(buffer);\n * // Process AIT bundle\n * } else if (format === BundleFormat.Format.ZIP) {\n * // Process legacy ZIP bundle\n * }\n * ```\n */\n\nimport { MAGIC } from \"./constants\";\n\n/** ZIP local file header magic (PK\\x03\\x04) */\nconst ZIP_MAGIC = new Uint8Array([0x50, 0x4b, 0x03, 0x04]);\n\n/**\n * Bundle format types.\n */\nexport enum Format {\n /** AIT bundle format (AITBUNDL magic) */\n AIT = \"AIT\",\n /** Legacy ZIP format (PK magic) */\n ZIP = \"ZIP\",\n /** Unknown format */\n UNKNOWN = \"UNKNOWN\",\n}\n\n/**\n * Bundle format detection utilities.\n */\nexport const BundleFormat = {\n /**\n * Format enum for convenience.\n */\n Format,\n\n /**\n * Detect the bundle format from a buffer.\n *\n * @param buffer - The buffer to detect format from (only first 8 bytes are needed)\n * @returns The detected format\n */\n detect(buffer: Uint8Array): Format {\n // Check AIT magic (8 bytes)\n if (buffer.length >= MAGIC.length) {\n let isAIT = true;\n for (let i = 0; i < MAGIC.length; i++) {\n if (buffer[i] !== MAGIC[i]) {\n isAIT = false;\n break;\n }\n }\n if (isAIT) {\n return Format.AIT;\n }\n }\n\n // Check ZIP magic (4 bytes)\n if (buffer.length >= ZIP_MAGIC.length) {\n let isZIP = true;\n for (let i = 0; i < ZIP_MAGIC.length; i++) {\n if (buffer[i] !== ZIP_MAGIC[i]) {\n isZIP = false;\n break;\n }\n }\n if (isZIP) {\n return Format.ZIP;\n }\n }\n\n return Format.UNKNOWN;\n },\n\n /**\n * Check if the buffer represents an AIT format.\n *\n * @param buffer - The buffer to check (only first 8 bytes are needed)\n * @returns true if AIT format\n */\n isAIT(buffer: Uint8Array): boolean {\n if (buffer.length < MAGIC.length) {\n return false;\n }\n for (let i = 0; i < MAGIC.length; i++) {\n if (buffer[i] !== MAGIC[i]) {\n return false;\n }\n }\n return true;\n },\n\n /**\n * Check if the buffer represents a ZIP format.\n *\n * @param buffer - The buffer to check (only first 4 bytes are needed)\n * @returns true if ZIP format\n */\n isZIP(buffer: Uint8Array): boolean {\n if (buffer.length < ZIP_MAGIC.length) {\n return false;\n }\n for (let i = 0; i < ZIP_MAGIC.length; i++) {\n if (buffer[i] !== ZIP_MAGIC[i]) {\n return false;\n }\n }\n return true;\n },\n} as const;\n", "/**\n * Main entry point for AIT (Apps-in-Toss) bundle operations.\n */\n\nimport { AITReader, AITReaderOptions } from \"./reader\";\nimport { AITWriter, AITWriterOptions } from \"./writer\";\nimport { FORMAT_VERSION, MAGIC } from \"./constants\";\nimport { BundleFormat, Format } from \"./format\";\nimport { generateUUID7 } from \"./utils\";\n\n/**\n * Main entry point for AIT bundle operations.\n *\n * @example\n * ```typescript\n * // Writing (auto-generated UUIDv7 for deploymentId)\n * const writer = AppsInTossBundle.writer({ appName: \"app-name\" });\n * writer.setMetadata({ platform: PlatformType.REACT_NATIVE });\n * writer.addFile(\"index.html\", new TextEncoder().encode(\"<html>...</html>\"));\n * const buffer = await writer.toBuffer();\n *\n * // Writing with explicit deploymentId\n * const writer = AppsInTossBundle.writer({\n * deploymentId: \"019bfa90-ad4c-799f-b227-b4159e6867f7\",\n * appName: \"app-name\",\n * });\n *\n * // Reading\n * const reader = AppsInTossBundle.reader(buffer);\n * console.log(reader.deploymentId);\n * console.log(reader.appName);\n * const content = await reader.readEntry(\"index.html\");\n * ```\n */\nexport class AppsInTossBundle {\n private constructor() {\n throw new Error(\"AppsInTossBundle is a utility class and cannot be instantiated\");\n }\n\n /**\n * Create a new writer.\n *\n * @param options Writer options including deploymentId and appName\n * @returns AITWriter instance\n */\n static writer(options: AITWriterOptions): AITWriter {\n return new AITWriter(options);\n }\n\n /**\n * Create a reader from a Uint8Array buffer.\n *\n * @param buffer AIT file contents\n * @param options Reader options\n * @returns AITReader instance\n */\n static reader(buffer: Uint8Array, options?: AITReaderOptions): AITReader {\n return AITReader.fromBuffer(buffer, options);\n }\n\n /**\n * Create a reader from an ArrayBuffer.\n *\n * @param buffer AIT file contents as ArrayBuffer\n * @param options Reader options\n * @returns AITReader instance\n */\n static readerFromArrayBuffer(buffer: ArrayBuffer, options?: AITReaderOptions): AITReader {\n return AITReader.fromArrayBuffer(buffer, options);\n }\n\n /**\n * Get the current format version.\n *\n * @returns Current format version\n */\n static getFormatVersion(): number {\n return FORMAT_VERSION;\n }\n\n /**\n * Get the magic bytes identifying AIT files.\n *\n * @returns Magic bytes\n */\n static getMagic(): Uint8Array {\n return MAGIC;\n }\n\n /**\n * Bundle format types.\n */\n static readonly Format = Format;\n\n /**\n * Detect the bundle format from a buffer.\n *\n * @param buffer - The buffer to detect format from (only first 8 bytes are needed)\n * @returns The detected format\n *\n * @example\n * ```typescript\n * const buffer = await fs.readFile(\"bundle.ait\");\n * const format = AppsInTossBundle.detect(buffer);\n *\n * if (format === AppsInTossBundle.Format.AIT) {\n * const reader = AppsInTossBundle.reader(buffer);\n * // Process AIT bundle\n * } else if (format === AppsInTossBundle.Format.ZIP) {\n * // Process legacy ZIP bundle\n * }\n * ```\n */\n static detect(buffer: Uint8Array): Format {\n return BundleFormat.detect(buffer);\n }\n\n /**\n * Check if the buffer represents an AIT format.\n *\n * @param buffer - The buffer to check (only first 8 bytes are needed)\n * @returns true if AIT format\n */\n static isAIT(buffer: Uint8Array): boolean {\n return BundleFormat.isAIT(buffer);\n }\n\n /**\n * Check if the buffer represents a ZIP format.\n *\n * @param buffer - The buffer to check (only first 4 bytes are needed)\n * @returns true if ZIP format\n */\n static isZIP(buffer: Uint8Array): boolean {\n return BundleFormat.isZIP(buffer);\n }\n\n /**\n * Generate a new UUIDv7 string.\n *\n * @returns A UUIDv7 string in standard format (8-4-4-4-12)\n */\n static generateUUID7(): string {\n return generateUUID7();\n }\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["src_exports", "__export", "AITError", "AITFormatError", "AITReader", "AITVersionError", "AITWriter", "AppsInTossBundle", "BundleFormat", "FORMAT_VERSION", "Format", "HEADER_SIZE", "MAGIC", "MAGIC_STRING", "__toCommonJS", "__reExport", "MAGIC", "MAGIC_STRING", "MAGIC_SIZE", "FORMAT_VERSION", "VERSION_SIZE", "LENGTH_SIZE", "HEADER_SIZE", "AITError", "message", "AITFormatError", "AITVersionError", "import_ait_format_proto", "AITReader", "_AITReader", "buffer", "options", "FORMAT_VERSION", "MAGIC_SIZE", "VERSION_SIZE", "LENGTH_SIZE", "AITFormatError", "magic", "MAGIC", "AITVersionError", "bundleLenOffset", "bundleLen", "bundleOffset", "bundleBytes", "a", "b", "i", "name", "unzipSync", "zipBlob", "entry", "sigLenOffset", "sigLen", "sigOffset", "result", "p", "meta", "import_ait_format_proto", "generateUUID7", "timestamp", "randomBytes", "i", "hex", "n", "len", "byteToHex", "b", "timeHigh", "timeLow", "timeHighHex", "timeLowHex", "versionAndRandom", "versionHex", "variantAndRandom", "variantHex", "nodeHex", "isValidUUID", "uuid", "parts", "hexPattern", "part", "computeSha256Hex", "data", "hashBuffer", "b", "AITWriter", "options", "generateUUID7", "isValidUUID", "FORMAT_VERSION", "name", "access", "data", "signature", "zipSync", "zipInput", "file", "zipBytes", "index", "computeSha256Hex", "bundle", "bundleBytes", "signatureBytes", "totalSize", "MAGIC", "VERSION_SIZE", "LENGTH_SIZE", "buffer", "view", "offset", "ZIP_MAGIC", "Format", "BundleFormat", "buffer", "MAGIC", "isAIT", "i", "isZIP", "AppsInTossBundle", "options", "AITWriter", "buffer", "AITReader", "FORMAT_VERSION", "MAGIC", "Format", "BundleFormat", "generateUUID7"]
|
|
7
|
+
}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export*from"@apps-in-toss/ait-format-proto";var a=new Uint8Array([65,73,84,66,85,78,68,76]),S="AITBUNDL",h=8,u=1,m=4,o=8,M=h+m+o;var y=class extends Error{constructor(e){super(e),this.name="AITError"}},p=class extends y{constructor(e){super(e),this.name="AITFormatError"}},A=class extends y{constructor(e){super(e),this.name="AITVersionError"}};import{AITBundle as F}from"@apps-in-toss/ait-format-proto";var g=class n{buffer;view;supportedVersions;_formatVersion=0;_bundle=null;_zipBlobOffset=0;_zipBlobLength=0;constructor(e,t){this.buffer=e,this.view=new DataView(e.buffer,e.byteOffset,e.byteLength),this.supportedVersions=t?.supportedVersions??[u],this.readHeader(),this.readBundle(),this.readZipHeader()}static fromBuffer(e,t){return new n(e,t)}static fromArrayBuffer(e,t){return new n(new Uint8Array(e),t)}readHeader(){if(this.buffer.length<h+m+o)throw new p("Buffer too small to be a valid AIT file");let e=this.buffer.slice(0,h);if(!this.arraysEqual(e,a))throw new p(`Invalid magic bytes: expected AITBUNDL, got ${new TextDecoder().decode(e)}`);if(this._formatVersion=this.view.getUint32(h,!1),!this.supportedVersions.includes(this._formatVersion))throw new A(`Unsupported format version: ${this._formatVersion}, supported: [${this.supportedVersions.join(", ")}]`)}readBundle(){let e=h+m,t=Number(this.view.getBigUint64(e,!1)),r=e+o;if(this.buffer.length<r+t)throw new p("Unexpected end of buffer reading bundle");let d=this.buffer.slice(r,r+t);if(this._bundle=F.decode(d),!this._bundle.deploymentId)throw new p("Bundle deployment_id must not be empty");if(!this._bundle.appName)throw new p("Bundle app_name must not be empty");this._zipBlobOffset=r+t}readZipHeader(){if(this.buffer.length<this._zipBlobOffset+o)throw new p("Unexpected end of buffer reading ZIP blob length");this._zipBlobLength=Number(this.view.getBigUint64(this._zipBlobOffset,!1)),this._zipBlobOffset+=o}arraysEqual(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}get formatVersion(){return this._formatVersion}get deploymentId(){return this._bundle?.deploymentId??""}get appName(){return this._bundle?.appName??""}get bundle(){if(!this._bundle)throw new p("Bundle not loaded");return this._bundle}get metadata(){return this._bundle?.metadata}get permissions(){return this._bundle?.permissions??[]}readZipBlob(){return this.buffer.slice(this._zipBlobOffset,this._zipBlobOffset+this._zipBlobLength)}async readEntry(e){let{unzipSync:t}=await import("fflate"),r=this.readZipBlob(),i=t(r)[e];if(!i)throw new Error(`Entry not found: ${e}`);return i}listEntries(){return this._bundle?.index.map(e=>e.name)??[]}readSignature(){let e=this._zipBlobOffset+this._zipBlobLength;if(this.buffer.length<e+o)return null;let t=Number(this.view.getBigUint64(e,!1));if(t===0)return null;let r=e+o;return this.buffer.length<r+t?null:this.buffer.slice(r,r+t)}toAppJson(){let e={appName:this._bundle?.appName??"",permissions:(this._bundle?.permissions??[]).map(r=>({name:r.name,access:r.access})),_metadata:{deploymentId:this._bundle?.deploymentId??""}},t=this._bundle?.metadata;return t&&(t.runtimeVersion&&(e._metadata.runtimeVersion=t.runtimeVersion),t.bundleFiles&&t.bundleFiles.length>0&&(e._metadata.bundleFiles=[...t.bundleFiles]),t.packageJson&&(e._metadata.packageJson=t.packageJson),t.sdkVersion&&(e._metadata.sdkVersion=t.sdkVersion)),e}};import{AITBundle as Z,CompressionMethod as V,PlatformType as z}from"@apps-in-toss/ait-format-proto";function b(){let n=Date.now(),e=new Uint8Array(10);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(e);else for(let f=0;f<10;f++)e[f]=Math.floor(Math.random()*256);let t=(f,R)=>f.toString(16).padStart(R,"0"),r=f=>f.toString(16).padStart(2,"0"),d=Math.floor(n/65536),i=n&65535,w=t(d,8),l=t(i,4),c=28672|(e[0]<<4|e[1]>>4)&4095,s=t(c,4),O=32768|((e[1]&15)<<10|e[2]<<2|e[3]>>6)&16383,N=t(O,4),v=r(e[4])+r(e[5])+r(e[6])+r(e[7])+r(e[8])+r(e[9]);return`${w}-${l}-${s}-${N}-${v}`}function T(n){let e=n.toLowerCase().split("-");if(e.length!==5||e[0]?.length!==8||e[1]?.length!==4||e[2]?.length!==4||e[3]?.length!==4||e[4]?.length!==12)return!1;let t=/^[0-9a-f]+$/;return e.every(r=>t.test(r))}async function _(n){let e=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}var x=class{formatVersion;deploymentId;appName;createdBy;metadata=void 0;permissions=[];files=[];signature=null;constructor(e){if(!e.appName)throw new Error("appName must not be empty");if(e.deploymentId===void 0)this.deploymentId=b();else{if(!e.deploymentId)throw new Error("deploymentId must not be empty");if(!T(e.deploymentId))throw new Error("deploymentId must be a valid UUID format (e.g., '019bfa90-ad4c-799f-b227-b4159e6867f7')");this.deploymentId=e.deploymentId}this.formatVersion=e.formatVersion??u,this.appName=e.appName,this.createdBy=e.createdBy??""}setMetadata(e){return this.metadata={isGame:e.isGame??!1,platform:e.platform??z.PLATFORM_UNSPECIFIED,runtimeVersion:e.runtimeVersion??"",bundleFiles:e.bundleFiles??[],packageJson:e.packageJson,sdkVersion:e.sdkVersion??"",extra:e.extra},this}addPermission(e,t){return this.permissions.push({name:e,access:t}),this}addFile(e,t,r){return this.files.push({name:e,data:t,compress:r?.compress??!0}),this}setSignature(e){return this.signature=e,this}async buildZipBlob(){let{zipSync:e}=await import("fflate"),t={};for(let i of this.files)t[i.name]=i.data;let r=e(t,{level:6}),d=await Promise.all(this.files.map(async i=>({name:i.name,zipOffset:BigInt(0),compressedSize:BigInt(0),uncompressedSize:BigInt(i.data.length),compMethod:i.compress?V.DEFLATE:V.NONE,sha256Hex:await _(i.data),attrs:void 0})));return{zipBytes:r,index:d}}buildBundle(e){return{formatVersion:this.formatVersion,deploymentId:this.deploymentId,appName:this.appName,metadata:this.metadata,permissions:this.permissions,index:e,createdBy:this.createdBy,createdAtMs:BigInt(Date.now())}}async toBuffer(){let{zipBytes:e,index:t}=await this.buildZipBlob(),r=this.buildBundle(t),d=Z.encode(r).finish(),i=this.signature??new Uint8Array(0),w=a.length+m+o+d.length+o+e.length+o+i.length,l=new Uint8Array(w),c=new DataView(l.buffer),s=0;return l.set(a,s),s+=a.length,c.setUint32(s,this.formatVersion,!1),s+=m,c.setBigUint64(s,BigInt(d.length),!1),s+=o,l.set(d,s),s+=d.length,c.setBigUint64(s,BigInt(e.length),!1),s+=o,l.set(e,s),s+=e.length,c.setBigUint64(s,BigInt(i.length),!1),s+=o,i.length>0&&l.set(i,s),l}};var I=new Uint8Array([80,75,3,4]),B=(r=>(r.AIT="AIT",r.ZIP="ZIP",r.UNKNOWN="UNKNOWN",r))(B||{}),U={Format:B,detect(n){if(n.length>=a.length){let e=!0;for(let t=0;t<a.length;t++)if(n[t]!==a[t]){e=!1;break}if(e)return"AIT"}if(n.length>=I.length){let e=!0;for(let t=0;t<I.length;t++)if(n[t]!==I[t]){e=!1;break}if(e)return"ZIP"}return"UNKNOWN"},isAIT(n){if(n.length<a.length)return!1;for(let e=0;e<a.length;e++)if(n[e]!==a[e])return!1;return!0},isZIP(n){if(n.length<I.length)return!1;for(let e=0;e<I.length;e++)if(n[e]!==I[e])return!1;return!0}};var E=class{constructor(){throw new Error("AppsInTossBundle is a utility class and cannot be instantiated")}static writer(e){return new x(e)}static reader(e,t){return g.fromBuffer(e,t)}static readerFromArrayBuffer(e,t){return g.fromArrayBuffer(e,t)}static getFormatVersion(){return u}static getMagic(){return a}static Format=B;static detect(e){return U.detect(e)}static isAIT(e){return U.isAIT(e)}static isZIP(e){return U.isZIP(e)}static generateUUID7(){return b()}};export{y as AITError,p as AITFormatError,g as AITReader,A as AITVersionError,x as AITWriter,E as AppsInTossBundle,U as BundleFormat,u as FORMAT_VERSION,B as Format,M as HEADER_SIZE,a as MAGIC,S as MAGIC_STRING};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/constants.ts", "../src/errors.ts", "../src/reader.ts", "../src/writer.ts", "../src/utils/generateUUID7.ts", "../src/utils/isValidUUID.ts", "../src/utils/computeSha256Hex.ts", "../src/format.ts", "../src/bundle.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * AIT Format - Protocol Buffer definitions and reader/writer for Apps-in-Toss bundle format.\n *\n * @packageDocumentation\n */\n\n// Re-export protobuf types from generated package\nexport * from \"@apps-in-toss/ait-format-proto\";\n\n// Constants\nexport { FORMAT_VERSION, MAGIC, MAGIC_STRING, HEADER_SIZE } from \"./constants\";\n\n// Errors\nexport { AITError, AITFormatError, AITVersionError } from \"./errors\";\n\n// Main entry point\nexport { AppsInTossBundle } from \"./bundle\";\n\n// Reader/Writer\nexport { AITReader, type AITReaderOptions, type AppJson, type AppJsonMetadata } from \"./reader\";\nexport { AITWriter, type AITWriterOptions, type MetadataOptions } from \"./writer\";\n\n// Format detection\nexport { BundleFormat, Format } from \"./format\";\n", "/**\n * AIT file format constants.\n */\n\n/** Magic bytes identifying AIT files (\"AITBUNDL\") */\nexport const MAGIC = new Uint8Array([0x41, 0x49, 0x54, 0x42, 0x55, 0x4e, 0x44, 0x4c]);\nexport const MAGIC_STRING = \"AITBUNDL\";\nexport const MAGIC_SIZE = 8;\n\n/** Current format version */\nexport const FORMAT_VERSION = 1;\n\n/** Header sizes (in bytes) */\nexport const VERSION_SIZE = 4;\nexport const LENGTH_SIZE = 8;\nexport const HEADER_SIZE = MAGIC_SIZE + VERSION_SIZE + LENGTH_SIZE; // 20 bytes\n\n", "/**\n * AIT error classes.\n */\n\n/** Base error for AIT operations */\nexport class AITError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AITError\";\n }\n}\n\n/** Invalid AIT file format */\nexport class AITFormatError extends AITError {\n constructor(message: string) {\n super(message);\n this.name = \"AITFormatError\";\n }\n}\n\n/** Unsupported AIT format version */\nexport class AITVersionError extends AITError {\n constructor(message: string) {\n super(message);\n this.name = \"AITVersionError\";\n }\n}\n\n", "/**\n * AIT file reader implementation.\n */\n\nimport { AITBundle, AITMetadata, Permission } from \"@apps-in-toss/ait-format-proto\";\nimport { FORMAT_VERSION, LENGTH_SIZE, MAGIC, MAGIC_SIZE, VERSION_SIZE } from \"./constants\";\nimport { AITFormatError, AITVersionError } from \"./errors\";\n\nexport interface AITReaderOptions {\n /** Tuple of supported format versions */\n supportedVersions?: number[];\n}\n\n/**\n * Reader for AIT (Apps-in-Toss) bundle files.\n *\n * @example\n * ```typescript\n * const reader = AITReader.fromBuffer(buffer);\n * console.log(reader.deploymentId);\n * console.log(reader.appName);\n * console.log(reader.metadata);\n * const data = await reader.readEntry(\"index.html\");\n * ```\n */\nexport class AITReader {\n private readonly buffer: Uint8Array;\n private readonly view: DataView;\n private readonly supportedVersions: number[];\n\n private _formatVersion: number = 0;\n private _bundle: AITBundle | null = null;\n private _zipBlobOffset: number = 0;\n private _zipBlobLength: number = 0;\n\n private constructor(buffer: Uint8Array, options?: AITReaderOptions) {\n this.buffer = buffer;\n this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n this.supportedVersions = options?.supportedVersions ?? [FORMAT_VERSION];\n\n this.readHeader();\n this.readBundle();\n this.readZipHeader();\n }\n\n /**\n * Create an AITReader from a buffer.\n */\n static fromBuffer(buffer: Uint8Array, options?: AITReaderOptions): AITReader {\n return new AITReader(buffer, options);\n }\n\n /**\n * Create an AITReader from an ArrayBuffer.\n */\n static fromArrayBuffer(buffer: ArrayBuffer, options?: AITReaderOptions): AITReader {\n return new AITReader(new Uint8Array(buffer), options);\n }\n\n private readHeader(): void {\n // Validate minimum size\n if (this.buffer.length < MAGIC_SIZE + VERSION_SIZE + LENGTH_SIZE) {\n throw new AITFormatError(\"Buffer too small to be a valid AIT file\");\n }\n\n // Validate magic\n const magic = this.buffer.slice(0, MAGIC_SIZE);\n if (!this.arraysEqual(magic, MAGIC)) {\n throw new AITFormatError(\n `Invalid magic bytes: expected AITBUNDL, got ${new TextDecoder().decode(magic)}`\n );\n }\n\n // Read version\n this._formatVersion = this.view.getUint32(MAGIC_SIZE, false);\n if (!this.supportedVersions.includes(this._formatVersion)) {\n throw new AITVersionError(\n `Unsupported format version: ${this._formatVersion}, supported: [${this.supportedVersions.join(\", \")}]`\n );\n }\n }\n\n private readBundle(): void {\n const bundleLenOffset = MAGIC_SIZE + VERSION_SIZE;\n const bundleLen = Number(this.view.getBigUint64(bundleLenOffset, false));\n\n const bundleOffset = bundleLenOffset + LENGTH_SIZE;\n if (this.buffer.length < bundleOffset + bundleLen) {\n throw new AITFormatError(\"Unexpected end of buffer reading bundle\");\n }\n\n const bundleBytes = this.buffer.slice(bundleOffset, bundleOffset + bundleLen);\n this._bundle = AITBundle.decode(bundleBytes);\n\n if (!this._bundle.deploymentId) {\n throw new AITFormatError(\"Bundle deployment_id must not be empty\");\n }\n if (!this._bundle.appName) {\n throw new AITFormatError(\"Bundle app_name must not be empty\");\n }\n\n // Update offset for ZIP header\n this._zipBlobOffset = bundleOffset + bundleLen;\n }\n\n private readZipHeader(): void {\n if (this.buffer.length < this._zipBlobOffset + LENGTH_SIZE) {\n throw new AITFormatError(\"Unexpected end of buffer reading ZIP blob length\");\n }\n\n this._zipBlobLength = Number(this.view.getBigUint64(this._zipBlobOffset, false));\n this._zipBlobOffset += LENGTH_SIZE; // Now points to actual ZIP data\n }\n\n private arraysEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n /** Get the format version */\n get formatVersion(): number {\n return this._formatVersion;\n }\n\n /** Get the deployment ID */\n get deploymentId(): string {\n return this._bundle?.deploymentId ?? \"\";\n }\n\n /** Get the application name */\n get appName(): string {\n return this._bundle?.appName ?? \"\";\n }\n\n /** Get the bundle */\n get bundle(): AITBundle {\n if (!this._bundle) {\n throw new AITFormatError(\"Bundle not loaded\");\n }\n return this._bundle;\n }\n\n /** Get the metadata */\n get metadata(): AITMetadata | undefined {\n return this._bundle?.metadata;\n }\n\n /** Get the permissions */\n get permissions(): Permission[] {\n return this._bundle?.permissions ?? [];\n }\n\n /**\n * Read the entire ZIP blob.\n */\n readZipBlob(): Uint8Array {\n return this.buffer.slice(this._zipBlobOffset, this._zipBlobOffset + this._zipBlobLength);\n }\n\n /**\n * Read a single entry from the ZIP blob.\n */\n async readEntry(name: string): Promise<Uint8Array> {\n const { unzipSync } = await import(\"fflate\");\n const zipBlob = this.readZipBlob();\n const unzipped = unzipSync(zipBlob);\n\n const entry = unzipped[name];\n if (!entry) {\n throw new Error(`Entry not found: ${name}`);\n }\n\n return entry;\n }\n\n /**\n * List all entry names in the ZIP blob.\n */\n listEntries(): string[] {\n return this._bundle?.index.map((entry) => entry.name) ?? [];\n }\n\n /**\n * Read the signature if present.\n */\n readSignature(): Uint8Array | null {\n const sigLenOffset = this._zipBlobOffset + this._zipBlobLength;\n if (this.buffer.length < sigLenOffset + LENGTH_SIZE) {\n return null;\n }\n\n const sigLen = Number(this.view.getBigUint64(sigLenOffset, false));\n if (sigLen === 0) {\n return null;\n }\n\n const sigOffset = sigLenOffset + LENGTH_SIZE;\n if (this.buffer.length < sigOffset + sigLen) {\n return null;\n }\n\n return this.buffer.slice(sigOffset, sigOffset + sigLen);\n }\n\n /**\n * Convert bundle to app.json format.\n *\n * @returns Object in app.json format with appName, permissions, and _metadata.\n */\n toAppJson(): AppJson {\n const result: AppJson = {\n appName: this._bundle?.appName ?? \"\",\n permissions: (this._bundle?.permissions ?? []).map((p) => ({\n name: p.name,\n access: p.access,\n })),\n _metadata: {\n deploymentId: this._bundle?.deploymentId ?? \"\",\n },\n };\n\n // Add metadata fields if present\n const meta = this._bundle?.metadata;\n if (meta) {\n if (meta.runtimeVersion) {\n result._metadata.runtimeVersion = meta.runtimeVersion;\n }\n if (meta.bundleFiles && meta.bundleFiles.length > 0) {\n result._metadata.bundleFiles = [...meta.bundleFiles];\n }\n if (meta.packageJson) {\n result._metadata.packageJson = meta.packageJson as Record<string, unknown>;\n }\n if (meta.sdkVersion) {\n result._metadata.sdkVersion = meta.sdkVersion;\n }\n }\n\n return result;\n }\n}\n\n/** app.json format */\nexport interface AppJson {\n appName: string;\n permissions: Array<{ name: string; access: string }>;\n _metadata: AppJsonMetadata;\n}\n\nexport interface AppJsonMetadata {\n deploymentId: string;\n runtimeVersion?: string;\n bundleFiles?: string[];\n packageJson?: Record<string, unknown>;\n sdkVersion?: string;\n}\n", "/**\n * AIT file writer implementation.\n */\n\nimport {\n AITBundle,\n AITMetadata,\n Permission,\n ZipIndexEntry,\n CompressionMethod,\n PlatformType,\n} from \"@apps-in-toss/ait-format-proto\";\nimport { FORMAT_VERSION, LENGTH_SIZE, MAGIC, VERSION_SIZE } from \"./constants\";\nimport { computeSha256Hex, generateUUID7, isValidUUID } from \"./utils\";\n\nexport interface AITWriterOptions {\n /** Application name (required) */\n appName: string;\n /** Unique identifier for this deployment. If not provided, a UUIDv7 will be auto-generated. */\n deploymentId?: string;\n /** AIT format version (default: current version) */\n formatVersion?: number;\n /** Creator info string (e.g., \"my-service/1.0.0\") */\n createdBy?: string;\n}\n\nexport interface MetadataOptions {\n /** Whether this is a game app */\n isGame?: boolean;\n /** Platform type (WEB or REACT_NATIVE) */\n platform?: PlatformType;\n /** Runtime version string */\n runtimeVersion?: string;\n /** List of bundle file names */\n bundleFiles?: string[];\n /** Package JSON content */\n packageJson?: Record<string, unknown>;\n /** Additional metadata */\n extra?: Record<string, unknown>;\n /** SDK Version */\n sdkVersion?: string;\n}\n\ninterface FileEntry {\n name: string;\n data: Uint8Array;\n compress: boolean;\n}\n\n/**\n * Writer for AIT (Apps-in-Toss) bundle files.\n *\n * @example\n * ```typescript\n * // With auto-generated UUIDv7\n * const writer = new AITWriter({ appName: \"my-app\" });\n * writer.setMetadata({ isGame: false, platform: PlatformType.WEB });\n * writer.addFile(\"index.html\", new TextEncoder().encode(\"<html>...</html>\"));\n * const buffer = await writer.toBuffer();\n *\n * // With explicit deployment ID\n * const writer = new AITWriter({\n * deploymentId: \"019bfa90-ad4c-799f-b227-b4159e6867f7\",\n * appName: \"my-app\"\n * });\n * ```\n */\nexport class AITWriter {\n private readonly formatVersion: number;\n private readonly deploymentId: string;\n private readonly appName: string;\n private readonly createdBy: string;\n private metadata: AITMetadata | undefined = undefined;\n private readonly permissions: Permission[] = [];\n private readonly files: FileEntry[] = [];\n private signature: Uint8Array | null = null;\n\n constructor(options: AITWriterOptions) {\n if (!options.appName) {\n throw new Error(\"appName must not be empty\");\n }\n\n if (options.deploymentId === undefined) {\n // Auto-generate UUIDv7\n this.deploymentId = generateUUID7();\n } else {\n if (!options.deploymentId) {\n throw new Error(\"deploymentId must not be empty\");\n }\n if (!isValidUUID(options.deploymentId)) {\n throw new Error(\n \"deploymentId must be a valid UUID format (e.g., '019bfa90-ad4c-799f-b227-b4159e6867f7')\"\n );\n }\n this.deploymentId = options.deploymentId;\n }\n\n this.formatVersion = options.formatVersion ?? FORMAT_VERSION;\n this.appName = options.appName;\n this.createdBy = options.createdBy ?? \"\";\n }\n\n /**\n * Set the bundle metadata.\n */\n setMetadata(options: MetadataOptions): this {\n this.metadata = {\n isGame: options.isGame ?? false,\n platform: options.platform ?? PlatformType.PLATFORM_UNSPECIFIED,\n runtimeVersion: options.runtimeVersion ?? \"\",\n bundleFiles: options.bundleFiles ?? [],\n packageJson: options.packageJson,\n sdkVersion: options.sdkVersion ?? '',\n extra: options.extra,\n };\n return this;\n }\n\n /**\n * Add a permission entry.\n */\n addPermission(name: string, access: string): this {\n this.permissions.push({ name, access });\n return this;\n }\n\n /**\n * Add a file to the bundle.\n */\n addFile(name: string, data: Uint8Array, options?: { compress?: boolean }): this {\n this.files.push({\n name,\n data,\n compress: options?.compress ?? true,\n });\n return this;\n }\n\n /**\n * Set the digital signature.\n */\n setSignature(signature: Uint8Array): this {\n this.signature = signature;\n return this;\n }\n\n /**\n * Build the ZIP blob and index entries.\n */\n private async buildZipBlob(): Promise<{ zipBytes: Uint8Array; index: ZipIndexEntry[] }> {\n const { zipSync } = await import(\"fflate\");\n\n const zipInput: Record<string, Uint8Array> = {};\n for (const file of this.files) {\n zipInput[file.name] = file.data;\n }\n\n const zipBytes = zipSync(zipInput, { level: 6 });\n\n // Build index entries with SHA256 hashes\n const index: ZipIndexEntry[] = await Promise.all(\n this.files.map(async (file) => ({\n name: file.name,\n zipOffset: BigInt(0), // Simplified - actual offset would need ZIP parsing\n compressedSize: BigInt(0),\n uncompressedSize: BigInt(file.data.length),\n compMethod: file.compress ? CompressionMethod.DEFLATE : CompressionMethod.NONE,\n sha256Hex: await computeSha256Hex(file.data),\n attrs: undefined,\n }))\n );\n\n return { zipBytes, index };\n }\n\n /**\n * Build the bundle protobuf message.\n */\n private buildBundle(index: ZipIndexEntry[]): AITBundle {\n return {\n formatVersion: this.formatVersion,\n deploymentId: this.deploymentId,\n appName: this.appName,\n metadata: this.metadata,\n permissions: this.permissions,\n index,\n createdBy: this.createdBy,\n createdAtMs: BigInt(Date.now()),\n };\n }\n\n /**\n * Serialize the AIT bundle to a buffer.\n */\n async toBuffer(): Promise<Uint8Array> {\n const { zipBytes, index } = await this.buildZipBlob();\n const bundle = this.buildBundle(index);\n const bundleBytes = AITBundle.encode(bundle).finish();\n\n // Calculate total size\n const signatureBytes = this.signature ?? new Uint8Array(0);\n const totalSize =\n MAGIC.length +\n VERSION_SIZE +\n LENGTH_SIZE +\n bundleBytes.length +\n LENGTH_SIZE +\n zipBytes.length +\n LENGTH_SIZE +\n signatureBytes.length;\n\n const buffer = new Uint8Array(totalSize);\n const view = new DataView(buffer.buffer);\n let offset = 0;\n\n // Write MAGIC\n buffer.set(MAGIC, offset);\n offset += MAGIC.length;\n\n // Write FORMAT_VERSION (big-endian)\n view.setUint32(offset, this.formatVersion, false);\n offset += VERSION_SIZE;\n\n // Write BUNDLE_LEN (big-endian uint64)\n view.setBigUint64(offset, BigInt(bundleBytes.length), false);\n offset += LENGTH_SIZE;\n\n // Write BUNDLE_BYTES\n buffer.set(bundleBytes, offset);\n offset += bundleBytes.length;\n\n // Write ZIP_BLOB_LEN (big-endian uint64)\n view.setBigUint64(offset, BigInt(zipBytes.length), false);\n offset += LENGTH_SIZE;\n\n // Write ZIP_BLOB_BYTES\n buffer.set(zipBytes, offset);\n offset += zipBytes.length;\n\n // Write SIGNATURE_LEN (big-endian uint64)\n view.setBigUint64(offset, BigInt(signatureBytes.length), false);\n offset += LENGTH_SIZE;\n\n // Write SIGNATURE_BYTES\n if (signatureBytes.length > 0) {\n buffer.set(signatureBytes, offset);\n }\n\n return buffer;\n }\n}\n", "/**\n * Generate a UUID version 7 (time-ordered UUID).\n *\n * UUID v7 format:\n * - 48 bits: Unix timestamp in milliseconds\n * - 4 bits: Version (0111 for v7)\n * - 12 bits: Random data\n * - 2 bits: Variant (10 for RFC 4122)\n * - 62 bits: Random data\n *\n * @returns A UUIDv7 string in standard format (8-4-4-4-12)\n */\nexport function generateUUID7(): string {\n const timestamp = Date.now();\n\n // Generate random bytes (need 10 bytes: 2 for version field, 2 for variant field, 6 for node)\n const randomBytes = new Uint8Array(10);\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(randomBytes);\n } else {\n // Fallback for environments without crypto\n for (let i = 0; i < 10; i++) {\n randomBytes[i] = Math.floor(Math.random() * 256);\n }\n }\n\n const hex = (n: number, len: number) => n.toString(16).padStart(len, \"0\");\n const byteToHex = (b: number) => b.toString(16).padStart(2, \"0\");\n\n // First 48 bits: timestamp (split into 32-bit high + 16-bit low)\n const timeHigh = Math.floor(timestamp / 0x10000);\n const timeLow = timestamp & 0xffff;\n\n // time-high (32 bits) = first 8 hex chars\n const timeHighHex = hex(timeHigh, 8);\n // time-low (16 bits) = next 4 hex chars\n const timeLowHex = hex(timeLow, 4);\n\n // Next 16 bits: 4-bit version (0111) + 12-bit random\n const versionAndRandom = 0x7000 | (((randomBytes[0]! << 4) | (randomBytes[1]! >> 4)) & 0x0fff);\n const versionHex = hex(versionAndRandom, 4);\n\n // Next 16 bits: 2-bit variant (10) + 14-bit random\n const variantAndRandom =\n 0x8000 |\n ((((randomBytes[1]! & 0x0f) << 10) | (randomBytes[2]! << 2) | (randomBytes[3]! >> 6)) & 0x3fff);\n const variantHex = hex(variantAndRandom, 4);\n\n // Last 48 bits: random (6 bytes)\n const nodeHex =\n byteToHex(randomBytes[4]!) +\n byteToHex(randomBytes[5]!) +\n byteToHex(randomBytes[6]!) +\n byteToHex(randomBytes[7]!) +\n byteToHex(randomBytes[8]!) +\n byteToHex(randomBytes[9]!);\n\n return `${timeHighHex}-${timeLowHex}-${versionHex}-${variantHex}-${nodeHex}`;\n}\n", "/**\n * Validate if a string is a valid UUID format.\n *\n * @param uuid The string to validate\n * @returns true if the string is a valid UUID format\n */\nexport function isValidUUID(uuid: string): boolean {\n // UUID format: 8-4-4-4-12 hex characters\n const parts = uuid.toLowerCase().split(\"-\");\n if (parts.length !== 5) return false;\n if (parts[0]?.length !== 8) return false;\n if (parts[1]?.length !== 4) return false;\n if (parts[2]?.length !== 4) return false;\n if (parts[3]?.length !== 4) return false;\n if (parts[4]?.length !== 12) return false;\n\n // Check all characters are valid hex\n const hexPattern = /^[0-9a-f]+$/;\n return parts.every((part) => hexPattern.test(part));\n}\n", "/**\n * Compute SHA256 hash of data and return as hex string.\n * Uses SubtleCrypto for browser compatibility.\n *\n * @param data The data to hash\n * @returns SHA256 hash as lowercase hex string\n */\nexport async function computeSha256Hex(data: Uint8Array): Promise<string> {\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n", "/**\n * Bundle format detection utilities.\n *\n * @example\n * ```typescript\n * import { BundleFormat, AITReader } from \"@apps-in-toss/ait-format\";\n *\n * const buffer = await fs.readFile(\"bundle.ait\");\n * const format = BundleFormat.detect(buffer);\n *\n * if (format === BundleFormat.Format.AIT) {\n * const reader = AITReader.fromBuffer(buffer);\n * // Process AIT bundle\n * } else if (format === BundleFormat.Format.ZIP) {\n * // Process legacy ZIP bundle\n * }\n * ```\n */\n\nimport { MAGIC } from \"./constants\";\n\n/** ZIP local file header magic (PK\\x03\\x04) */\nconst ZIP_MAGIC = new Uint8Array([0x50, 0x4b, 0x03, 0x04]);\n\n/**\n * Bundle format types.\n */\nexport enum Format {\n /** AIT bundle format (AITBUNDL magic) */\n AIT = \"AIT\",\n /** Legacy ZIP format (PK magic) */\n ZIP = \"ZIP\",\n /** Unknown format */\n UNKNOWN = \"UNKNOWN\",\n}\n\n/**\n * Bundle format detection utilities.\n */\nexport const BundleFormat = {\n /**\n * Format enum for convenience.\n */\n Format,\n\n /**\n * Detect the bundle format from a buffer.\n *\n * @param buffer - The buffer to detect format from (only first 8 bytes are needed)\n * @returns The detected format\n */\n detect(buffer: Uint8Array): Format {\n // Check AIT magic (8 bytes)\n if (buffer.length >= MAGIC.length) {\n let isAIT = true;\n for (let i = 0; i < MAGIC.length; i++) {\n if (buffer[i] !== MAGIC[i]) {\n isAIT = false;\n break;\n }\n }\n if (isAIT) {\n return Format.AIT;\n }\n }\n\n // Check ZIP magic (4 bytes)\n if (buffer.length >= ZIP_MAGIC.length) {\n let isZIP = true;\n for (let i = 0; i < ZIP_MAGIC.length; i++) {\n if (buffer[i] !== ZIP_MAGIC[i]) {\n isZIP = false;\n break;\n }\n }\n if (isZIP) {\n return Format.ZIP;\n }\n }\n\n return Format.UNKNOWN;\n },\n\n /**\n * Check if the buffer represents an AIT format.\n *\n * @param buffer - The buffer to check (only first 8 bytes are needed)\n * @returns true if AIT format\n */\n isAIT(buffer: Uint8Array): boolean {\n if (buffer.length < MAGIC.length) {\n return false;\n }\n for (let i = 0; i < MAGIC.length; i++) {\n if (buffer[i] !== MAGIC[i]) {\n return false;\n }\n }\n return true;\n },\n\n /**\n * Check if the buffer represents a ZIP format.\n *\n * @param buffer - The buffer to check (only first 4 bytes are needed)\n * @returns true if ZIP format\n */\n isZIP(buffer: Uint8Array): boolean {\n if (buffer.length < ZIP_MAGIC.length) {\n return false;\n }\n for (let i = 0; i < ZIP_MAGIC.length; i++) {\n if (buffer[i] !== ZIP_MAGIC[i]) {\n return false;\n }\n }\n return true;\n },\n} as const;\n", "/**\n * Main entry point for AIT (Apps-in-Toss) bundle operations.\n */\n\nimport { AITReader, AITReaderOptions } from \"./reader\";\nimport { AITWriter, AITWriterOptions } from \"./writer\";\nimport { FORMAT_VERSION, MAGIC } from \"./constants\";\nimport { BundleFormat, Format } from \"./format\";\nimport { generateUUID7 } from \"./utils\";\n\n/**\n * Main entry point for AIT bundle operations.\n *\n * @example\n * ```typescript\n * // Writing (auto-generated UUIDv7 for deploymentId)\n * const writer = AppsInTossBundle.writer({ appName: \"app-name\" });\n * writer.setMetadata({ platform: PlatformType.REACT_NATIVE });\n * writer.addFile(\"index.html\", new TextEncoder().encode(\"<html>...</html>\"));\n * const buffer = await writer.toBuffer();\n *\n * // Writing with explicit deploymentId\n * const writer = AppsInTossBundle.writer({\n * deploymentId: \"019bfa90-ad4c-799f-b227-b4159e6867f7\",\n * appName: \"app-name\",\n * });\n *\n * // Reading\n * const reader = AppsInTossBundle.reader(buffer);\n * console.log(reader.deploymentId);\n * console.log(reader.appName);\n * const content = await reader.readEntry(\"index.html\");\n * ```\n */\nexport class AppsInTossBundle {\n private constructor() {\n throw new Error(\"AppsInTossBundle is a utility class and cannot be instantiated\");\n }\n\n /**\n * Create a new writer.\n *\n * @param options Writer options including deploymentId and appName\n * @returns AITWriter instance\n */\n static writer(options: AITWriterOptions): AITWriter {\n return new AITWriter(options);\n }\n\n /**\n * Create a reader from a Uint8Array buffer.\n *\n * @param buffer AIT file contents\n * @param options Reader options\n * @returns AITReader instance\n */\n static reader(buffer: Uint8Array, options?: AITReaderOptions): AITReader {\n return AITReader.fromBuffer(buffer, options);\n }\n\n /**\n * Create a reader from an ArrayBuffer.\n *\n * @param buffer AIT file contents as ArrayBuffer\n * @param options Reader options\n * @returns AITReader instance\n */\n static readerFromArrayBuffer(buffer: ArrayBuffer, options?: AITReaderOptions): AITReader {\n return AITReader.fromArrayBuffer(buffer, options);\n }\n\n /**\n * Get the current format version.\n *\n * @returns Current format version\n */\n static getFormatVersion(): number {\n return FORMAT_VERSION;\n }\n\n /**\n * Get the magic bytes identifying AIT files.\n *\n * @returns Magic bytes\n */\n static getMagic(): Uint8Array {\n return MAGIC;\n }\n\n /**\n * Bundle format types.\n */\n static readonly Format = Format;\n\n /**\n * Detect the bundle format from a buffer.\n *\n * @param buffer - The buffer to detect format from (only first 8 bytes are needed)\n * @returns The detected format\n *\n * @example\n * ```typescript\n * const buffer = await fs.readFile(\"bundle.ait\");\n * const format = AppsInTossBundle.detect(buffer);\n *\n * if (format === AppsInTossBundle.Format.AIT) {\n * const reader = AppsInTossBundle.reader(buffer);\n * // Process AIT bundle\n * } else if (format === AppsInTossBundle.Format.ZIP) {\n * // Process legacy ZIP bundle\n * }\n * ```\n */\n static detect(buffer: Uint8Array): Format {\n return BundleFormat.detect(buffer);\n }\n\n /**\n * Check if the buffer represents an AIT format.\n *\n * @param buffer - The buffer to check (only first 8 bytes are needed)\n * @returns true if AIT format\n */\n static isAIT(buffer: Uint8Array): boolean {\n return BundleFormat.isAIT(buffer);\n }\n\n /**\n * Check if the buffer represents a ZIP format.\n *\n * @param buffer - The buffer to check (only first 4 bytes are needed)\n * @returns true if ZIP format\n */\n static isZIP(buffer: Uint8Array): boolean {\n return BundleFormat.isZIP(buffer);\n }\n\n /**\n * Generate a new UUIDv7 string.\n *\n * @returns A UUIDv7 string in standard format (8-4-4-4-12)\n */\n static generateUUID7(): string {\n return generateUUID7();\n }\n}\n\n"],
|
|
5
|
+
"mappings": "AAOA,WAAc,iCCFP,IAAMA,EAAQ,IAAI,WAAW,CAAC,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,EAAI,CAAC,EACvEC,EAAe,WACfC,EAAa,EAGbC,EAAiB,EAGjBC,EAAe,EACfC,EAAc,EACdC,EAAcJ,EAAaE,EAAeC,ECVhD,IAAME,EAAN,cAAuB,KAAM,CAClC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,UACd,CACF,EAGaC,EAAN,cAA6BF,CAAS,CAC3C,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,gBACd,CACF,EAGaE,EAAN,cAA8BH,CAAS,CAC5C,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,iBACd,CACF,ECtBA,OAAS,aAAAG,MAA0C,iCAqB5C,IAAMC,EAAN,MAAMC,CAAU,CACJ,OACA,KACA,kBAET,eAAyB,EACzB,QAA4B,KAC5B,eAAyB,EACzB,eAAyB,EAEzB,YAAYC,EAAoBC,EAA4B,CAClE,KAAK,OAASD,EACd,KAAK,KAAO,IAAI,SAASA,EAAO,OAAQA,EAAO,WAAYA,EAAO,UAAU,EAC5E,KAAK,kBAAoBC,GAAS,mBAAqB,CAACC,CAAc,EAEtE,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,CACrB,CAKA,OAAO,WAAWF,EAAoBC,EAAuC,CAC3E,OAAO,IAAIF,EAAUC,EAAQC,CAAO,CACtC,CAKA,OAAO,gBAAgBD,EAAqBC,EAAuC,CACjF,OAAO,IAAIF,EAAU,IAAI,WAAWC,CAAM,EAAGC,CAAO,CACtD,CAEQ,YAAmB,CAEzB,GAAI,KAAK,OAAO,OAASE,EAAaC,EAAeC,EACnD,MAAM,IAAIC,EAAe,yCAAyC,EAIpE,IAAMC,EAAQ,KAAK,OAAO,MAAM,EAAGJ,CAAU,EAC7C,GAAI,CAAC,KAAK,YAAYI,EAAOC,CAAK,EAChC,MAAM,IAAIF,EACR,+CAA+C,IAAI,YAAY,EAAE,OAAOC,CAAK,CAAC,EAChF,EAKF,GADA,KAAK,eAAiB,KAAK,KAAK,UAAUJ,EAAY,EAAK,EACvD,CAAC,KAAK,kBAAkB,SAAS,KAAK,cAAc,EACtD,MAAM,IAAIM,EACR,+BAA+B,KAAK,cAAc,iBAAiB,KAAK,kBAAkB,KAAK,IAAI,CAAC,GACtG,CAEJ,CAEQ,YAAmB,CACzB,IAAMC,EAAkBP,EAAaC,EAC/BO,EAAY,OAAO,KAAK,KAAK,aAAaD,EAAiB,EAAK,CAAC,EAEjEE,EAAeF,EAAkBL,EACvC,GAAI,KAAK,OAAO,OAASO,EAAeD,EACtC,MAAM,IAAIL,EAAe,yCAAyC,EAGpE,IAAMO,EAAc,KAAK,OAAO,MAAMD,EAAcA,EAAeD,CAAS,EAG5E,GAFA,KAAK,QAAUG,EAAU,OAAOD,CAAW,EAEvC,CAAC,KAAK,QAAQ,aAChB,MAAM,IAAIP,EAAe,wCAAwC,EAEnE,GAAI,CAAC,KAAK,QAAQ,QAChB,MAAM,IAAIA,EAAe,mCAAmC,EAI9D,KAAK,eAAiBM,EAAeD,CACvC,CAEQ,eAAsB,CAC5B,GAAI,KAAK,OAAO,OAAS,KAAK,eAAiBN,EAC7C,MAAM,IAAIC,EAAe,kDAAkD,EAG7E,KAAK,eAAiB,OAAO,KAAK,KAAK,aAAa,KAAK,eAAgB,EAAK,CAAC,EAC/E,KAAK,gBAAkBD,CACzB,CAEQ,YAAYU,EAAeC,EAAwB,CACzD,GAAID,EAAE,SAAWC,EAAE,OAAQ,MAAO,GAClC,QAASC,EAAI,EAAGA,EAAIF,EAAE,OAAQE,IAC5B,GAAIF,EAAEE,CAAC,IAAMD,EAAEC,CAAC,EAAG,MAAO,GAE5B,MAAO,EACT,CAGA,IAAI,eAAwB,CAC1B,OAAO,KAAK,cACd,CAGA,IAAI,cAAuB,CACzB,OAAO,KAAK,SAAS,cAAgB,EACvC,CAGA,IAAI,SAAkB,CACpB,OAAO,KAAK,SAAS,SAAW,EAClC,CAGA,IAAI,QAAoB,CACtB,GAAI,CAAC,KAAK,QACR,MAAM,IAAIX,EAAe,mBAAmB,EAE9C,OAAO,KAAK,OACd,CAGA,IAAI,UAAoC,CACtC,OAAO,KAAK,SAAS,QACvB,CAGA,IAAI,aAA4B,CAC9B,OAAO,KAAK,SAAS,aAAe,CAAC,CACvC,CAKA,aAA0B,CACxB,OAAO,KAAK,OAAO,MAAM,KAAK,eAAgB,KAAK,eAAiB,KAAK,cAAc,CACzF,CAKA,MAAM,UAAUY,EAAmC,CACjD,GAAM,CAAE,UAAAC,CAAU,EAAI,KAAM,QAAO,QAAQ,EACrCC,EAAU,KAAK,YAAY,EAG3BC,EAFWF,EAAUC,CAAO,EAEXF,CAAI,EAC3B,GAAI,CAACG,EACH,MAAM,IAAI,MAAM,oBAAoBH,CAAI,EAAE,EAG5C,OAAOG,CACT,CAKA,aAAwB,CACtB,OAAO,KAAK,SAAS,MAAM,IAAKA,GAAUA,EAAM,IAAI,GAAK,CAAC,CAC5D,CAKA,eAAmC,CACjC,IAAMC,EAAe,KAAK,eAAiB,KAAK,eAChD,GAAI,KAAK,OAAO,OAASA,EAAejB,EACtC,OAAO,KAGT,IAAMkB,EAAS,OAAO,KAAK,KAAK,aAAaD,EAAc,EAAK,CAAC,EACjE,GAAIC,IAAW,EACb,OAAO,KAGT,IAAMC,EAAYF,EAAejB,EACjC,OAAI,KAAK,OAAO,OAASmB,EAAYD,EAC5B,KAGF,KAAK,OAAO,MAAMC,EAAWA,EAAYD,CAAM,CACxD,CAOA,WAAqB,CACnB,IAAME,EAAkB,CACtB,QAAS,KAAK,SAAS,SAAW,GAClC,aAAc,KAAK,SAAS,aAAe,CAAC,GAAG,IAAKC,IAAO,CACzD,KAAMA,EAAE,KACR,OAAQA,EAAE,MACZ,EAAE,EACF,UAAW,CACT,aAAc,KAAK,SAAS,cAAgB,EAC9C,CACF,EAGMC,EAAO,KAAK,SAAS,SAC3B,OAAIA,IACEA,EAAK,iBACPF,EAAO,UAAU,eAAiBE,EAAK,gBAErCA,EAAK,aAAeA,EAAK,YAAY,OAAS,IAChDF,EAAO,UAAU,YAAc,CAAC,GAAGE,EAAK,WAAW,GAEjDA,EAAK,cACPF,EAAO,UAAU,YAAcE,EAAK,aAElCA,EAAK,aACPF,EAAO,UAAU,WAAaE,EAAK,aAIhCF,CACT,CACF,EC/OA,OACE,aAAAG,EAIA,qBAAAC,EACA,gBAAAC,MACK,iCCCA,SAASC,GAAwB,CACtC,IAAMC,EAAY,KAAK,IAAI,EAGrBC,EAAc,IAAI,WAAW,EAAE,EACrC,GAAI,OAAO,OAAW,KAAe,OAAO,gBAC1C,OAAO,gBAAgBA,CAAW,MAGlC,SAASC,EAAI,EAAGA,EAAI,GAAIA,IACtBD,EAAYC,CAAC,EAAI,KAAK,MAAM,KAAK,OAAO,EAAI,GAAG,EAInD,IAAMC,EAAM,CAACC,EAAWC,IAAgBD,EAAE,SAAS,EAAE,EAAE,SAASC,EAAK,GAAG,EAClEC,EAAaC,GAAcA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EAGzDC,EAAW,KAAK,MAAMR,EAAY,KAAO,EACzCS,EAAUT,EAAY,MAGtBU,EAAcP,EAAIK,EAAU,CAAC,EAE7BG,EAAaR,EAAIM,EAAS,CAAC,EAG3BG,EAAmB,OAAYX,EAAY,CAAC,GAAM,EAAMA,EAAY,CAAC,GAAM,GAAM,KACjFY,EAAaV,EAAIS,EAAkB,CAAC,EAGpCE,EACJ,QACIb,EAAY,CAAC,EAAK,KAAS,GAAOA,EAAY,CAAC,GAAM,EAAMA,EAAY,CAAC,GAAM,GAAM,MACpFc,EAAaZ,EAAIW,EAAkB,CAAC,EAGpCE,EACJV,EAAUL,EAAY,CAAC,CAAE,EACzBK,EAAUL,EAAY,CAAC,CAAE,EACzBK,EAAUL,EAAY,CAAC,CAAE,EACzBK,EAAUL,EAAY,CAAC,CAAE,EACzBK,EAAUL,EAAY,CAAC,CAAE,EACzBK,EAAUL,EAAY,CAAC,CAAE,EAE3B,MAAO,GAAGS,CAAW,IAAIC,CAAU,IAAIE,CAAU,IAAIE,CAAU,IAAIC,CAAO,EAC5E,CCpDO,SAASC,EAAYC,EAAuB,CAEjD,IAAMC,EAAQD,EAAK,YAAY,EAAE,MAAM,GAAG,EAM1C,GALIC,EAAM,SAAW,GACjBA,EAAM,CAAC,GAAG,SAAW,GACrBA,EAAM,CAAC,GAAG,SAAW,GACrBA,EAAM,CAAC,GAAG,SAAW,GACrBA,EAAM,CAAC,GAAG,SAAW,GACrBA,EAAM,CAAC,GAAG,SAAW,GAAI,MAAO,GAGpC,IAAMC,EAAa,cACnB,OAAOD,EAAM,MAAOE,GAASD,EAAW,KAAKC,CAAI,CAAC,CACpD,CCZA,eAAsBC,EAAiBC,EAAmC,CACxE,IAAMC,EAAa,MAAM,OAAO,OAAO,OAAO,UAAWD,CAAI,EAC7D,OAAO,MAAM,KAAK,IAAI,WAAWC,CAAU,CAAC,EACzC,IAAKC,GAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAC1C,KAAK,EAAE,CACZ,CHuDO,IAAMC,EAAN,KAAgB,CACJ,cACA,aACA,QACA,UACT,SAAoC,OAC3B,YAA4B,CAAC,EAC7B,MAAqB,CAAC,EAC/B,UAA+B,KAEvC,YAAYC,EAA2B,CACrC,GAAI,CAACA,EAAQ,QACX,MAAM,IAAI,MAAM,2BAA2B,EAG7C,GAAIA,EAAQ,eAAiB,OAE3B,KAAK,aAAeC,EAAc,MAC7B,CACL,GAAI,CAACD,EAAQ,aACX,MAAM,IAAI,MAAM,gCAAgC,EAElD,GAAI,CAACE,EAAYF,EAAQ,YAAY,EACnC,MAAM,IAAI,MACR,yFACF,EAEF,KAAK,aAAeA,EAAQ,YAC9B,CAEA,KAAK,cAAgBA,EAAQ,eAAiBG,EAC9C,KAAK,QAAUH,EAAQ,QACvB,KAAK,UAAYA,EAAQ,WAAa,EACxC,CAKA,YAAYA,EAAgC,CAC1C,YAAK,SAAW,CACd,OAAQA,EAAQ,QAAU,GAC1B,SAAUA,EAAQ,UAAYI,EAAa,qBAC3C,eAAgBJ,EAAQ,gBAAkB,GAC1C,YAAaA,EAAQ,aAAe,CAAC,EACrC,YAAaA,EAAQ,YACrB,WAAYA,EAAQ,YAAc,GAClC,MAAOA,EAAQ,KACjB,EACO,IACT,CAKA,cAAcK,EAAcC,EAAsB,CAChD,YAAK,YAAY,KAAK,CAAE,KAAAD,EAAM,OAAAC,CAAO,CAAC,EAC/B,IACT,CAKA,QAAQD,EAAcE,EAAkBP,EAAwC,CAC9E,YAAK,MAAM,KAAK,CACd,KAAAK,EACA,KAAAE,EACA,SAAUP,GAAS,UAAY,EACjC,CAAC,EACM,IACT,CAKA,aAAaQ,EAA6B,CACxC,YAAK,UAAYA,EACV,IACT,CAKA,MAAc,cAA0E,CACtF,GAAM,CAAE,QAAAC,CAAQ,EAAI,KAAM,QAAO,QAAQ,EAEnCC,EAAuC,CAAC,EAC9C,QAAWC,KAAQ,KAAK,MACtBD,EAASC,EAAK,IAAI,EAAIA,EAAK,KAG7B,IAAMC,EAAWH,EAAQC,EAAU,CAAE,MAAO,CAAE,CAAC,EAGzCG,EAAyB,MAAM,QAAQ,IAC3C,KAAK,MAAM,IAAI,MAAOF,IAAU,CAC9B,KAAMA,EAAK,KACX,UAAW,OAAO,CAAC,EACnB,eAAgB,OAAO,CAAC,EACxB,iBAAkB,OAAOA,EAAK,KAAK,MAAM,EACzC,WAAYA,EAAK,SAAWG,EAAkB,QAAUA,EAAkB,KAC1E,UAAW,MAAMC,EAAiBJ,EAAK,IAAI,EAC3C,MAAO,MACT,EAAE,CACJ,EAEA,MAAO,CAAE,SAAAC,EAAU,MAAAC,CAAM,CAC3B,CAKQ,YAAYA,EAAmC,CACrD,MAAO,CACL,cAAe,KAAK,cACpB,aAAc,KAAK,aACnB,QAAS,KAAK,QACd,SAAU,KAAK,SACf,YAAa,KAAK,YAClB,MAAAA,EACA,UAAW,KAAK,UAChB,YAAa,OAAO,KAAK,IAAI,CAAC,CAChC,CACF,CAKA,MAAM,UAAgC,CACpC,GAAM,CAAE,SAAAD,EAAU,MAAAC,CAAM,EAAI,MAAM,KAAK,aAAa,EAC9CG,EAAS,KAAK,YAAYH,CAAK,EAC/BI,EAAcC,EAAU,OAAOF,CAAM,EAAE,OAAO,EAG9CG,EAAiB,KAAK,WAAa,IAAI,WAAW,CAAC,EACnDC,EACJC,EAAM,OACNC,EACAC,EACAN,EAAY,OACZM,EACAX,EAAS,OACTW,EACAJ,EAAe,OAEXK,EAAS,IAAI,WAAWJ,CAAS,EACjCK,EAAO,IAAI,SAASD,EAAO,MAAM,EACnCE,EAAS,EAGb,OAAAF,EAAO,IAAIH,EAAOK,CAAM,EACxBA,GAAUL,EAAM,OAGhBI,EAAK,UAAUC,EAAQ,KAAK,cAAe,EAAK,EAChDA,GAAUJ,EAGVG,EAAK,aAAaC,EAAQ,OAAOT,EAAY,MAAM,EAAG,EAAK,EAC3DS,GAAUH,EAGVC,EAAO,IAAIP,EAAaS,CAAM,EAC9BA,GAAUT,EAAY,OAGtBQ,EAAK,aAAaC,EAAQ,OAAOd,EAAS,MAAM,EAAG,EAAK,EACxDc,GAAUH,EAGVC,EAAO,IAAIZ,EAAUc,CAAM,EAC3BA,GAAUd,EAAS,OAGnBa,EAAK,aAAaC,EAAQ,OAAOP,EAAe,MAAM,EAAG,EAAK,EAC9DO,GAAUH,EAGNJ,EAAe,OAAS,GAC1BK,EAAO,IAAIL,EAAgBO,CAAM,EAG5BF,CACT,CACF,EIpOA,IAAMG,EAAY,IAAI,WAAW,CAAC,GAAM,GAAM,EAAM,CAAI,CAAC,EAK7CC,OAEVA,EAAA,IAAM,MAENA,EAAA,IAAM,MAENA,EAAA,QAAU,UANAA,OAAA,IAYCC,EAAe,CAI1B,OAAAD,EAQA,OAAOE,EAA4B,CAEjC,GAAIA,EAAO,QAAUC,EAAM,OAAQ,CACjC,IAAIC,EAAQ,GACZ,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAChC,GAAIH,EAAOG,CAAC,IAAMF,EAAME,CAAC,EAAG,CAC1BD,EAAQ,GACR,KACF,CAEF,GAAIA,EACF,MAAO,KAEX,CAGA,GAAIF,EAAO,QAAUH,EAAU,OAAQ,CACrC,IAAIO,EAAQ,GACZ,QAASD,EAAI,EAAGA,EAAIN,EAAU,OAAQM,IACpC,GAAIH,EAAOG,CAAC,IAAMN,EAAUM,CAAC,EAAG,CAC9BC,EAAQ,GACR,KACF,CAEF,GAAIA,EACF,MAAO,KAEX,CAEA,MAAO,SACT,EAQA,MAAMJ,EAA6B,CACjC,GAAIA,EAAO,OAASC,EAAM,OACxB,MAAO,GAET,QAASE,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAChC,GAAIH,EAAOG,CAAC,IAAMF,EAAME,CAAC,EACvB,MAAO,GAGX,MAAO,EACT,EAQA,MAAMH,EAA6B,CACjC,GAAIA,EAAO,OAASH,EAAU,OAC5B,MAAO,GAET,QAASM,EAAI,EAAGA,EAAIN,EAAU,OAAQM,IACpC,GAAIH,EAAOG,CAAC,IAAMN,EAAUM,CAAC,EAC3B,MAAO,GAGX,MAAO,EACT,CACF,ECpFO,IAAME,EAAN,KAAuB,CACpB,aAAc,CACpB,MAAM,IAAI,MAAM,gEAAgE,CAClF,CAQA,OAAO,OAAOC,EAAsC,CAClD,OAAO,IAAIC,EAAUD,CAAO,CAC9B,CASA,OAAO,OAAOE,EAAoBF,EAAuC,CACvE,OAAOG,EAAU,WAAWD,EAAQF,CAAO,CAC7C,CASA,OAAO,sBAAsBE,EAAqBF,EAAuC,CACvF,OAAOG,EAAU,gBAAgBD,EAAQF,CAAO,CAClD,CAOA,OAAO,kBAA2B,CAChC,OAAOI,CACT,CAOA,OAAO,UAAuB,CAC5B,OAAOC,CACT,CAKA,OAAgB,OAASC,EAqBzB,OAAO,OAAOJ,EAA4B,CACxC,OAAOK,EAAa,OAAOL,CAAM,CACnC,CAQA,OAAO,MAAMA,EAA6B,CACxC,OAAOK,EAAa,MAAML,CAAM,CAClC,CAQA,OAAO,MAAMA,EAA6B,CACxC,OAAOK,EAAa,MAAML,CAAM,CAClC,CAOA,OAAO,eAAwB,CAC7B,OAAOM,EAAc,CACvB,CACF",
|
|
6
|
+
"names": ["MAGIC", "MAGIC_STRING", "MAGIC_SIZE", "FORMAT_VERSION", "VERSION_SIZE", "LENGTH_SIZE", "HEADER_SIZE", "AITError", "message", "AITFormatError", "AITVersionError", "AITBundle", "AITReader", "_AITReader", "buffer", "options", "FORMAT_VERSION", "MAGIC_SIZE", "VERSION_SIZE", "LENGTH_SIZE", "AITFormatError", "magic", "MAGIC", "AITVersionError", "bundleLenOffset", "bundleLen", "bundleOffset", "bundleBytes", "AITBundle", "a", "b", "i", "name", "unzipSync", "zipBlob", "entry", "sigLenOffset", "sigLen", "sigOffset", "result", "p", "meta", "AITBundle", "CompressionMethod", "PlatformType", "generateUUID7", "timestamp", "randomBytes", "i", "hex", "n", "len", "byteToHex", "b", "timeHigh", "timeLow", "timeHighHex", "timeLowHex", "versionAndRandom", "versionHex", "variantAndRandom", "variantHex", "nodeHex", "isValidUUID", "uuid", "parts", "hexPattern", "part", "computeSha256Hex", "data", "hashBuffer", "b", "AITWriter", "options", "generateUUID7", "isValidUUID", "FORMAT_VERSION", "PlatformType", "name", "access", "data", "signature", "zipSync", "zipInput", "file", "zipBytes", "index", "CompressionMethod", "computeSha256Hex", "bundle", "bundleBytes", "AITBundle", "signatureBytes", "totalSize", "MAGIC", "VERSION_SIZE", "LENGTH_SIZE", "buffer", "view", "offset", "ZIP_MAGIC", "Format", "BundleFormat", "buffer", "MAGIC", "isAIT", "i", "isZIP", "AppsInTossBundle", "options", "AITWriter", "buffer", "AITReader", "FORMAT_VERSION", "MAGIC", "Format", "BundleFormat", "generateUUID7"]
|
|
7
|
+
}
|
package/dist/reader.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIT file reader implementation.
|
|
3
|
+
*/
|
|
4
|
+
import { AITBundle, AITMetadata, Permission } from "@apps-in-toss/ait-format-proto";
|
|
5
|
+
export interface AITReaderOptions {
|
|
6
|
+
/** Tuple of supported format versions */
|
|
7
|
+
supportedVersions?: number[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Reader for AIT (Apps-in-Toss) bundle files.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const reader = AITReader.fromBuffer(buffer);
|
|
15
|
+
* console.log(reader.deploymentId);
|
|
16
|
+
* console.log(reader.appName);
|
|
17
|
+
* console.log(reader.metadata);
|
|
18
|
+
* const data = await reader.readEntry("index.html");
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class AITReader {
|
|
22
|
+
private readonly buffer;
|
|
23
|
+
private readonly view;
|
|
24
|
+
private readonly supportedVersions;
|
|
25
|
+
private _formatVersion;
|
|
26
|
+
private _bundle;
|
|
27
|
+
private _zipBlobOffset;
|
|
28
|
+
private _zipBlobLength;
|
|
29
|
+
private constructor();
|
|
30
|
+
/**
|
|
31
|
+
* Create an AITReader from a buffer.
|
|
32
|
+
*/
|
|
33
|
+
static fromBuffer(buffer: Uint8Array, options?: AITReaderOptions): AITReader;
|
|
34
|
+
/**
|
|
35
|
+
* Create an AITReader from an ArrayBuffer.
|
|
36
|
+
*/
|
|
37
|
+
static fromArrayBuffer(buffer: ArrayBuffer, options?: AITReaderOptions): AITReader;
|
|
38
|
+
private readHeader;
|
|
39
|
+
private readBundle;
|
|
40
|
+
private readZipHeader;
|
|
41
|
+
private arraysEqual;
|
|
42
|
+
/** Get the format version */
|
|
43
|
+
get formatVersion(): number;
|
|
44
|
+
/** Get the deployment ID */
|
|
45
|
+
get deploymentId(): string;
|
|
46
|
+
/** Get the application name */
|
|
47
|
+
get appName(): string;
|
|
48
|
+
/** Get the bundle */
|
|
49
|
+
get bundle(): AITBundle;
|
|
50
|
+
/** Get the metadata */
|
|
51
|
+
get metadata(): AITMetadata | undefined;
|
|
52
|
+
/** Get the permissions */
|
|
53
|
+
get permissions(): Permission[];
|
|
54
|
+
/**
|
|
55
|
+
* Read the entire ZIP blob.
|
|
56
|
+
*/
|
|
57
|
+
readZipBlob(): Uint8Array;
|
|
58
|
+
/**
|
|
59
|
+
* Read a single entry from the ZIP blob.
|
|
60
|
+
*/
|
|
61
|
+
readEntry(name: string): Promise<Uint8Array>;
|
|
62
|
+
/**
|
|
63
|
+
* List all entry names in the ZIP blob.
|
|
64
|
+
*/
|
|
65
|
+
listEntries(): string[];
|
|
66
|
+
/**
|
|
67
|
+
* Read the signature if present.
|
|
68
|
+
*/
|
|
69
|
+
readSignature(): Uint8Array | null;
|
|
70
|
+
/**
|
|
71
|
+
* Convert bundle to app.json format.
|
|
72
|
+
*
|
|
73
|
+
* @returns Object in app.json format with appName, permissions, and _metadata.
|
|
74
|
+
*/
|
|
75
|
+
toAppJson(): AppJson;
|
|
76
|
+
}
|
|
77
|
+
/** app.json format */
|
|
78
|
+
export interface AppJson {
|
|
79
|
+
appName: string;
|
|
80
|
+
permissions: Array<{
|
|
81
|
+
name: string;
|
|
82
|
+
access: string;
|
|
83
|
+
}>;
|
|
84
|
+
_metadata: AppJsonMetadata;
|
|
85
|
+
}
|
|
86
|
+
export interface AppJsonMetadata {
|
|
87
|
+
deploymentId: string;
|
|
88
|
+
runtimeVersion?: string;
|
|
89
|
+
bundleFiles?: string[];
|
|
90
|
+
packageJson?: Record<string, unknown>;
|
|
91
|
+
sdkVersion?: string;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAIpF,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAW;IAE7C,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,cAAc,CAAa;IAEnC,OAAO;IAUP;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS;IAI5E;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS;IAIlF,OAAO,CAAC,UAAU;IAuBlB,OAAO,CAAC,UAAU;IAuBlB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,WAAW;IAQnB,6BAA6B;IAC7B,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,4BAA4B;IAC5B,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,+BAA+B;IAC/B,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,qBAAqB;IACrB,IAAI,MAAM,IAAI,SAAS,CAKtB;IAED,uBAAuB;IACvB,IAAI,QAAQ,IAAI,WAAW,GAAG,SAAS,CAEtC;IAED,0BAA0B;IAC1B,IAAI,WAAW,IAAI,UAAU,EAAE,CAE9B;IAED;;OAEG;IACH,WAAW,IAAI,UAAU;IAIzB;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAalD;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAmBlC;;;;OAIG;IACH,SAAS,IAAI,OAAO;CA+BrB;AAED,sBAAsB;AACtB,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute SHA256 hash of data and return as hex string.
|
|
3
|
+
* Uses SubtleCrypto for browser compatibility.
|
|
4
|
+
*
|
|
5
|
+
* @param data The data to hash
|
|
6
|
+
* @returns SHA256 hash as lowercase hex string
|
|
7
|
+
*/
|
|
8
|
+
export declare function computeSha256Hex(data: Uint8Array): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=computeSha256Hex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computeSha256Hex.d.ts","sourceRoot":"","sources":["../../src/utils/computeSha256Hex.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAKxE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a UUID version 7 (time-ordered UUID).
|
|
3
|
+
*
|
|
4
|
+
* UUID v7 format:
|
|
5
|
+
* - 48 bits: Unix timestamp in milliseconds
|
|
6
|
+
* - 4 bits: Version (0111 for v7)
|
|
7
|
+
* - 12 bits: Random data
|
|
8
|
+
* - 2 bits: Variant (10 for RFC 4122)
|
|
9
|
+
* - 62 bits: Random data
|
|
10
|
+
*
|
|
11
|
+
* @returns A UUIDv7 string in standard format (8-4-4-4-12)
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateUUID7(): string;
|
|
14
|
+
//# sourceMappingURL=generateUUID7.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateUUID7.d.ts","sourceRoot":"","sources":["../../src/utils/generateUUID7.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,IAAI,MAAM,CA8CtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isValidUUID.d.ts","sourceRoot":"","sources":["../../src/utils/isValidUUID.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAajD"}
|
package/dist/writer.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIT file writer implementation.
|
|
3
|
+
*/
|
|
4
|
+
import { PlatformType } from "@apps-in-toss/ait-format-proto";
|
|
5
|
+
export interface AITWriterOptions {
|
|
6
|
+
/** Application name (required) */
|
|
7
|
+
appName: string;
|
|
8
|
+
/** Unique identifier for this deployment. If not provided, a UUIDv7 will be auto-generated. */
|
|
9
|
+
deploymentId?: string;
|
|
10
|
+
/** AIT format version (default: current version) */
|
|
11
|
+
formatVersion?: number;
|
|
12
|
+
/** Creator info string (e.g., "my-service/1.0.0") */
|
|
13
|
+
createdBy?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface MetadataOptions {
|
|
16
|
+
/** Whether this is a game app */
|
|
17
|
+
isGame?: boolean;
|
|
18
|
+
/** Platform type (WEB or REACT_NATIVE) */
|
|
19
|
+
platform?: PlatformType;
|
|
20
|
+
/** Runtime version string */
|
|
21
|
+
runtimeVersion?: string;
|
|
22
|
+
/** List of bundle file names */
|
|
23
|
+
bundleFiles?: string[];
|
|
24
|
+
/** Package JSON content */
|
|
25
|
+
packageJson?: Record<string, unknown>;
|
|
26
|
+
/** Additional metadata */
|
|
27
|
+
extra?: Record<string, unknown>;
|
|
28
|
+
/** SDK Version */
|
|
29
|
+
sdkVersion?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Writer for AIT (Apps-in-Toss) bundle files.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // With auto-generated UUIDv7
|
|
37
|
+
* const writer = new AITWriter({ appName: "my-app" });
|
|
38
|
+
* writer.setMetadata({ isGame: false, platform: PlatformType.WEB });
|
|
39
|
+
* writer.addFile("index.html", new TextEncoder().encode("<html>...</html>"));
|
|
40
|
+
* const buffer = await writer.toBuffer();
|
|
41
|
+
*
|
|
42
|
+
* // With explicit deployment ID
|
|
43
|
+
* const writer = new AITWriter({
|
|
44
|
+
* deploymentId: "019bfa90-ad4c-799f-b227-b4159e6867f7",
|
|
45
|
+
* appName: "my-app"
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class AITWriter {
|
|
50
|
+
private readonly formatVersion;
|
|
51
|
+
private readonly deploymentId;
|
|
52
|
+
private readonly appName;
|
|
53
|
+
private readonly createdBy;
|
|
54
|
+
private metadata;
|
|
55
|
+
private readonly permissions;
|
|
56
|
+
private readonly files;
|
|
57
|
+
private signature;
|
|
58
|
+
constructor(options: AITWriterOptions);
|
|
59
|
+
/**
|
|
60
|
+
* Set the bundle metadata.
|
|
61
|
+
*/
|
|
62
|
+
setMetadata(options: MetadataOptions): this;
|
|
63
|
+
/**
|
|
64
|
+
* Add a permission entry.
|
|
65
|
+
*/
|
|
66
|
+
addPermission(name: string, access: string): this;
|
|
67
|
+
/**
|
|
68
|
+
* Add a file to the bundle.
|
|
69
|
+
*/
|
|
70
|
+
addFile(name: string, data: Uint8Array, options?: {
|
|
71
|
+
compress?: boolean;
|
|
72
|
+
}): this;
|
|
73
|
+
/**
|
|
74
|
+
* Set the digital signature.
|
|
75
|
+
*/
|
|
76
|
+
setSignature(signature: Uint8Array): this;
|
|
77
|
+
/**
|
|
78
|
+
* Build the ZIP blob and index entries.
|
|
79
|
+
*/
|
|
80
|
+
private buildZipBlob;
|
|
81
|
+
/**
|
|
82
|
+
* Build the bundle protobuf message.
|
|
83
|
+
*/
|
|
84
|
+
private buildBundle;
|
|
85
|
+
/**
|
|
86
|
+
* Serialize the AIT bundle to a buffer.
|
|
87
|
+
*/
|
|
88
|
+
toBuffer(): Promise<Uint8Array>;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAML,YAAY,EACb,MAAM,gCAAgC,CAAC;AAIxC,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,+FAA+F;IAC/F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,SAAS,CAA2B;gBAEhC,OAAO,EAAE,gBAAgB;IAyBrC;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAa3C;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKjD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAS/E;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAKzC;;OAEG;YACW,YAAY;IA0B1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;CAwDtC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@apps-in-toss/ait-format",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AIT (Apps-in-Toss) format reader/writer",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"protobuf",
|
|
20
|
+
"ait",
|
|
21
|
+
"apps-in-toss"
|
|
22
|
+
],
|
|
23
|
+
"author": "Apps In Toss",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@apps-in-toss/ait-format-proto": "^1.0.0",
|
|
26
|
+
"fflate": "^0.8.2"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^20.11.0",
|
|
30
|
+
"esbuild": "^0.20.0",
|
|
31
|
+
"tsx": "^4.7.0",
|
|
32
|
+
"typescript": "^5.3.0",
|
|
33
|
+
"vitest": "^1.0.0"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"registry": "https://registry.npmjs.org/",
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=24"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "npm run build:types && npm run build:bundle",
|
|
44
|
+
"build:types": "tsc --emitDeclarationOnly",
|
|
45
|
+
"build:bundle": "npx tsx build.mts",
|
|
46
|
+
"clean": "rm -rf dist",
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest"
|
|
49
|
+
}
|
|
50
|
+
}
|