loopwind 0.25.6 → 0.25.7

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.
Files changed (90) hide show
  1. package/app/.astro/types.d.ts +1 -0
  2. package/app/dist/_astro/callback.Ci5gaEfJ.css +1 -0
  3. package/app/dist/auth/callback/index.html +81 -0
  4. package/app/dist/device/index.html +70 -0
  5. package/app/dist/index.html +327 -0
  6. package/app/package-lock.json +9239 -0
  7. package/app/package.json +23 -0
  8. package/app/wrangler.toml +8 -0
  9. package/dist/cli.js +54 -0
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/login.d.ts +5 -0
  12. package/dist/commands/login.d.ts.map +1 -0
  13. package/dist/commands/login.js +60 -0
  14. package/dist/commands/login.js.map +1 -0
  15. package/dist/commands/logout.d.ts +5 -0
  16. package/dist/commands/logout.d.ts.map +1 -0
  17. package/dist/commands/logout.js +15 -0
  18. package/dist/commands/logout.js.map +1 -0
  19. package/dist/commands/publish.d.ts +10 -0
  20. package/dist/commands/publish.d.ts.map +1 -0
  21. package/dist/commands/publish.js +155 -0
  22. package/dist/commands/publish.js.map +1 -0
  23. package/dist/commands/templates.d.ts +5 -0
  24. package/dist/commands/templates.d.ts.map +1 -0
  25. package/dist/commands/templates.js +60 -0
  26. package/dist/commands/templates.js.map +1 -0
  27. package/dist/commands/unpublish.d.ts +5 -0
  28. package/dist/commands/unpublish.d.ts.map +1 -0
  29. package/dist/commands/unpublish.js +54 -0
  30. package/dist/commands/unpublish.js.map +1 -0
  31. package/dist/commands/whoami.d.ts +5 -0
  32. package/dist/commands/whoami.d.ts.map +1 -0
  33. package/dist/commands/whoami.js +30 -0
  34. package/dist/commands/whoami.js.map +1 -0
  35. package/dist/lib/api.d.ts +92 -0
  36. package/dist/lib/api.d.ts.map +1 -0
  37. package/dist/lib/api.js +149 -0
  38. package/dist/lib/api.js.map +1 -0
  39. package/dist/lib/auth.d.ts +41 -0
  40. package/dist/lib/auth.d.ts.map +1 -0
  41. package/dist/lib/auth.js +89 -0
  42. package/dist/lib/auth.js.map +1 -0
  43. package/dist/lib/bundler.d.ts +18 -0
  44. package/dist/lib/bundler.d.ts.map +1 -0
  45. package/dist/lib/bundler.js +105 -0
  46. package/dist/lib/bundler.js.map +1 -0
  47. package/dist/lib/helpers.d.ts +35 -2
  48. package/dist/lib/helpers.d.ts.map +1 -1
  49. package/dist/lib/helpers.js +91 -13
  50. package/dist/lib/helpers.js.map +1 -1
  51. package/dist/lib/utils.d.ts.map +1 -1
  52. package/dist/lib/utils.js +9 -0
  53. package/dist/lib/utils.js.map +1 -1
  54. package/dist/sdk/edge.d.ts +65 -0
  55. package/dist/sdk/edge.d.ts.map +1 -0
  56. package/dist/sdk/edge.js +329 -0
  57. package/dist/sdk/edge.js.map +1 -0
  58. package/dist/sdk/errors.d.ts +64 -0
  59. package/dist/sdk/errors.d.ts.map +1 -0
  60. package/dist/sdk/errors.js +94 -0
  61. package/dist/sdk/errors.js.map +1 -0
  62. package/dist/sdk/index.d.ts +29 -0
  63. package/dist/sdk/index.d.ts.map +1 -0
  64. package/dist/sdk/index.js +30 -0
  65. package/dist/sdk/index.js.map +1 -0
  66. package/dist/sdk/render.d.ts +52 -0
  67. package/dist/sdk/render.d.ts.map +1 -0
  68. package/dist/sdk/render.js +432 -0
  69. package/dist/sdk/render.js.map +1 -0
  70. package/dist/sdk/types.d.ts +185 -0
  71. package/dist/sdk/types.d.ts.map +1 -0
  72. package/dist/sdk/types.js +5 -0
  73. package/dist/sdk/types.js.map +1 -0
  74. package/dist/types/template.d.ts +18 -0
  75. package/dist/types/template.d.ts.map +1 -1
  76. package/package.json +26 -4
  77. package/plans/PLATFORM.md +1637 -237
  78. package/plans/PLATFORM_IMPLEMENTATION.md +1347 -530
  79. package/plans/SDK.md +797 -0
  80. package/platform/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/ebad93a0a7be9c5768c512f3e30740b64d2b6e575277a40d77044af5ae8fd3f2.sqlite +0 -0
  81. package/platform/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/ebad93a0a7be9c5768c512f3e30740b64d2b6e575277a40d77044af5ae8fd3f2.sqlite-shm +0 -0
  82. package/platform/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/ebad93a0a7be9c5768c512f3e30740b64d2b6e575277a40d77044af5ae8fd3f2.sqlite-wal +0 -0
  83. package/platform/migrations/0001_initial.sql +90 -0
  84. package/platform/package-lock.json +3104 -0
  85. package/platform/package.json +30 -0
  86. package/platform/wrangler.toml +43 -0
  87. package/tests-sdk/createRenderer.test.ts +251 -0
  88. package/tests-sdk/errors.test.ts +230 -0
  89. package/tests-sdk/render.test.ts +241 -0
  90. package/tests-sdk/tw.test.ts +277 -0
@@ -0,0 +1,92 @@
1
+ /**
2
+ * API client for Loopwind Platform
3
+ */
4
+ import { type Credentials } from './auth.js';
5
+ declare const API_BASE_URL: string;
6
+ declare const APP_BASE_URL: string;
7
+ export { API_BASE_URL, APP_BASE_URL };
8
+ interface DeviceCodeResponse {
9
+ device_code: string;
10
+ user_code: string;
11
+ verification_uri: string;
12
+ verification_uri_complete: string;
13
+ expires_in: number;
14
+ interval: number;
15
+ }
16
+ interface TokenResponse {
17
+ access_token: string;
18
+ token_type: string;
19
+ expires_in: number;
20
+ }
21
+ interface MeResponse {
22
+ user: {
23
+ id: string;
24
+ github_username: string;
25
+ email: string | null;
26
+ };
27
+ organization: {
28
+ id: string;
29
+ name: string;
30
+ slug: string;
31
+ };
32
+ }
33
+ interface PublishResponse {
34
+ id: string;
35
+ name: string;
36
+ version: number;
37
+ token: string;
38
+ render_url: string;
39
+ created: boolean;
40
+ }
41
+ interface Template {
42
+ id: string;
43
+ name: string;
44
+ version: number;
45
+ created_at: string;
46
+ updated_at: string;
47
+ }
48
+ interface Organization {
49
+ id: string;
50
+ name: string;
51
+ slug: string;
52
+ role?: string;
53
+ }
54
+ export declare function setCurrentOrg(orgId: string | null): void;
55
+ /**
56
+ * Start device code flow for CLI login
57
+ */
58
+ export declare function startDeviceFlow(): Promise<DeviceCodeResponse>;
59
+ /**
60
+ * Poll for device code authorization
61
+ */
62
+ export declare function pollForToken(deviceCode: string, interval?: number): Promise<TokenResponse>;
63
+ /**
64
+ * Get current user and organization info
65
+ */
66
+ export declare function getMe(): Promise<MeResponse>;
67
+ /**
68
+ * Fetch user info and update credentials
69
+ */
70
+ export declare function fetchAndSaveUserInfo(token: string): Promise<Credentials>;
71
+ /**
72
+ * List templates
73
+ */
74
+ export declare function listTemplates(): Promise<Template[]>;
75
+ /**
76
+ * Publish template
77
+ */
78
+ export declare function publishTemplate(name: string, bundleBase64: string, meta?: {
79
+ description?: string;
80
+ schema?: Record<string, unknown>;
81
+ defaults?: Record<string, unknown>;
82
+ }): Promise<PublishResponse>;
83
+ /**
84
+ * Delete template
85
+ */
86
+ export declare function deleteTemplate(name: string): Promise<void>;
87
+ /**
88
+ * List user's organizations
89
+ */
90
+ export declare function listOrganizations(): Promise<Organization[]>;
91
+ export type { Organization };
92
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA8C,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAEzF,QAAA,MAAM,YAAY,QAAsE,CAAC;AACzF,QAAA,MAAM,YAAY,QAA6D,CAAC;AAEhF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAOtC,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,eAAe,EAAE,MAAM,CAAC;QACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KACtB,CAAC;IACF,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,QAEjD;AAoCD;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAYnE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAa,GACtB,OAAO,CAAC,aAAa,CAAC,CAuBxB;AAED;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqC9E;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGzD;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE;IACL,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GACA,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAGjE;AAED,YAAY,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * API client for Loopwind Platform
3
+ */
4
+ import { getToken, saveCredentials } from './auth.js';
5
+ const API_BASE_URL = process.env.LOOPWIND_API_URL || 'https://loopwind-api.loopwind.dev';
6
+ const APP_BASE_URL = process.env.LOOPWIND_APP_URL || 'https://app.loopwind.dev';
7
+ export { API_BASE_URL, APP_BASE_URL };
8
+ // Current org override for API requests
9
+ let currentOrgId = null;
10
+ export function setCurrentOrg(orgId) {
11
+ currentOrgId = orgId;
12
+ }
13
+ /**
14
+ * Make authenticated API request
15
+ */
16
+ async function apiRequest(path, options = {}) {
17
+ const token = await getToken();
18
+ const headers = {
19
+ 'Content-Type': 'application/json',
20
+ Authorization: `Bearer ${token}`,
21
+ };
22
+ if (currentOrgId) {
23
+ headers['X-Org-Id'] = currentOrgId;
24
+ }
25
+ const response = await fetch(`${API_BASE_URL}${path}`, {
26
+ ...options,
27
+ headers: {
28
+ ...headers,
29
+ ...options.headers,
30
+ },
31
+ });
32
+ if (!response.ok) {
33
+ const error = (await response.json());
34
+ throw new Error(error.error || `API error: ${response.status}`);
35
+ }
36
+ return response.json();
37
+ }
38
+ /**
39
+ * Start device code flow for CLI login
40
+ */
41
+ export async function startDeviceFlow() {
42
+ const response = await fetch(`${API_BASE_URL}/auth/device/code`, {
43
+ method: 'POST',
44
+ headers: { 'Content-Type': 'application/json' },
45
+ });
46
+ if (!response.ok) {
47
+ const error = (await response.json());
48
+ throw new Error(error.error || 'Failed to start login');
49
+ }
50
+ return response.json();
51
+ }
52
+ /**
53
+ * Poll for device code authorization
54
+ */
55
+ export async function pollForToken(deviceCode, interval = 5000) {
56
+ while (true) {
57
+ const response = await fetch(`${API_BASE_URL}/auth/device/token`, {
58
+ method: 'POST',
59
+ headers: { 'Content-Type': 'application/json' },
60
+ body: JSON.stringify({ device_code: deviceCode }),
61
+ });
62
+ const data = (await response.json());
63
+ if ('access_token' in data) {
64
+ return data;
65
+ }
66
+ if ('error' in data) {
67
+ if (data.error === 'authorization_pending') {
68
+ // Keep polling
69
+ await new Promise((resolve) => setTimeout(resolve, interval));
70
+ continue;
71
+ }
72
+ throw new Error(data.error_description || data.error);
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Get current user and organization info
78
+ */
79
+ export async function getMe() {
80
+ return apiRequest('/organizations/current');
81
+ }
82
+ /**
83
+ * Fetch user info and update credentials
84
+ */
85
+ export async function fetchAndSaveUserInfo(token) {
86
+ const response = await fetch(`${API_BASE_URL}/organizations/current`, {
87
+ headers: {
88
+ Authorization: `Bearer ${token}`,
89
+ 'Content-Type': 'application/json',
90
+ },
91
+ });
92
+ if (!response.ok) {
93
+ throw new Error('Failed to get user info');
94
+ }
95
+ const org = await response.json();
96
+ // Parse token to get user ID (JWT)
97
+ const payload = JSON.parse(atob(token.split('.')[1]));
98
+ const credentials = {
99
+ token,
100
+ user: {
101
+ id: payload.sub,
102
+ username: '', // Will be filled from API
103
+ },
104
+ organization: {
105
+ id: org.id,
106
+ name: org.name,
107
+ slug: org.slug,
108
+ },
109
+ expiresAt: new Date(payload.exp * 1000).toISOString(),
110
+ };
111
+ await saveCredentials(credentials);
112
+ return credentials;
113
+ }
114
+ /**
115
+ * List templates
116
+ */
117
+ export async function listTemplates() {
118
+ const response = await apiRequest('/templates');
119
+ return response.templates;
120
+ }
121
+ /**
122
+ * Publish template
123
+ */
124
+ export async function publishTemplate(name, bundleBase64, meta) {
125
+ return apiRequest('/templates', {
126
+ method: 'POST',
127
+ body: JSON.stringify({
128
+ name,
129
+ bundle: bundleBase64,
130
+ meta,
131
+ }),
132
+ });
133
+ }
134
+ /**
135
+ * Delete template
136
+ */
137
+ export async function deleteTemplate(name) {
138
+ await apiRequest(`/templates/${encodeURIComponent(name)}`, {
139
+ method: 'DELETE',
140
+ });
141
+ }
142
+ /**
143
+ * List user's organizations
144
+ */
145
+ export async function listOrganizations() {
146
+ const response = await apiRequest('/organizations');
147
+ return response.organizations;
148
+ }
149
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * CLI Authentication - credential storage and management
3
+ */
4
+ export interface Credentials {
5
+ token: string;
6
+ user: {
7
+ id: string;
8
+ username: string;
9
+ };
10
+ organization: {
11
+ id: string;
12
+ name: string;
13
+ slug: string;
14
+ };
15
+ expiresAt?: string;
16
+ }
17
+ /**
18
+ * Save credentials to disk
19
+ */
20
+ export declare function saveCredentials(credentials: Credentials): Promise<void>;
21
+ /**
22
+ * Load credentials from disk
23
+ */
24
+ export declare function loadCredentials(): Promise<Credentials | null>;
25
+ /**
26
+ * Clear credentials (logout)
27
+ */
28
+ export declare function clearCredentials(): Promise<void>;
29
+ /**
30
+ * Check if user is authenticated
31
+ */
32
+ export declare function isAuthenticated(): Promise<boolean>;
33
+ /**
34
+ * Get current token, throw if not authenticated
35
+ */
36
+ export declare function getToken(): Promise<string>;
37
+ /**
38
+ * Get current organization ID
39
+ */
40
+ export declare function getOrgId(): Promise<string>;
41
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAG7E;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAUnE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOtD;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAcxD;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAMhD;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAMhD"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * CLI Authentication - credential storage and management
3
+ */
4
+ import { readFile, writeFile, mkdir } from 'fs/promises';
5
+ import { existsSync } from 'fs';
6
+ import { homedir } from 'os';
7
+ import { join } from 'path';
8
+ const LOOPWIND_DIR = join(homedir(), '.loopwind');
9
+ const CREDENTIALS_FILE = join(LOOPWIND_DIR, 'credentials.json');
10
+ /**
11
+ * Ensure ~/.loopwind directory exists
12
+ */
13
+ async function ensureDir() {
14
+ if (!existsSync(LOOPWIND_DIR)) {
15
+ await mkdir(LOOPWIND_DIR, { recursive: true });
16
+ }
17
+ }
18
+ /**
19
+ * Save credentials to disk
20
+ */
21
+ export async function saveCredentials(credentials) {
22
+ await ensureDir();
23
+ await writeFile(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), 'utf-8');
24
+ }
25
+ /**
26
+ * Load credentials from disk
27
+ */
28
+ export async function loadCredentials() {
29
+ try {
30
+ if (!existsSync(CREDENTIALS_FILE)) {
31
+ return null;
32
+ }
33
+ const data = await readFile(CREDENTIALS_FILE, 'utf-8');
34
+ return JSON.parse(data);
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * Clear credentials (logout)
42
+ */
43
+ export async function clearCredentials() {
44
+ try {
45
+ const { unlink } = await import('fs/promises');
46
+ await unlink(CREDENTIALS_FILE);
47
+ }
48
+ catch {
49
+ // File doesn't exist, that's fine
50
+ }
51
+ }
52
+ /**
53
+ * Check if user is authenticated
54
+ */
55
+ export async function isAuthenticated() {
56
+ const credentials = await loadCredentials();
57
+ if (!credentials)
58
+ return false;
59
+ // Check expiration if set
60
+ if (credentials.expiresAt) {
61
+ const expiry = new Date(credentials.expiresAt);
62
+ if (expiry < new Date()) {
63
+ await clearCredentials();
64
+ return false;
65
+ }
66
+ }
67
+ return true;
68
+ }
69
+ /**
70
+ * Get current token, throw if not authenticated
71
+ */
72
+ export async function getToken() {
73
+ const credentials = await loadCredentials();
74
+ if (!credentials) {
75
+ throw new Error('Not authenticated. Run: loopwind login');
76
+ }
77
+ return credentials.token;
78
+ }
79
+ /**
80
+ * Get current organization ID
81
+ */
82
+ export async function getOrgId() {
83
+ const credentials = await loadCredentials();
84
+ if (!credentials) {
85
+ throw new Error('Not authenticated. Run: loopwind login');
86
+ }
87
+ return credentials.organization.id;
88
+ }
89
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Template bundler for publishing to Loopwind Platform
3
+ *
4
+ * Creates a self-contained bundle that can be executed on the edge.
5
+ */
6
+ /**
7
+ * Bundle a template file into a self-contained module
8
+ * @param templatePath - Path to the template file (TSX)
9
+ * @returns The bundled JavaScript as a Uint8Array
10
+ */
11
+ export declare function bundleTemplate(templatePath: string): Promise<Uint8Array>;
12
+ /**
13
+ * Bundle multiple templates into a single module
14
+ * @param templates - Map of template names to file paths
15
+ * @returns The bundled JavaScript as a Uint8Array
16
+ */
17
+ export declare function bundleTemplates(templates: Record<string, string>): Promise<Uint8Array>;
18
+ //# sourceMappingURL=bundler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundler.d.ts","sourceRoot":"","sources":["../../src/lib/bundler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAuC9E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,UAAU,CAAC,CAyDrB"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Template bundler for publishing to Loopwind Platform
3
+ *
4
+ * Creates a self-contained bundle that can be executed on the edge.
5
+ */
6
+ import { build } from 'esbuild';
7
+ import { resolve } from 'path';
8
+ /**
9
+ * Bundle a template file into a self-contained module
10
+ * @param templatePath - Path to the template file (TSX)
11
+ * @returns The bundled JavaScript as a Uint8Array
12
+ */
13
+ export async function bundleTemplate(templatePath) {
14
+ const absolutePath = resolve(templatePath);
15
+ // Bundle with esbuild
16
+ const result = await build({
17
+ entryPoints: [absolutePath],
18
+ bundle: true,
19
+ format: 'esm',
20
+ write: false,
21
+ jsx: 'automatic',
22
+ jsxImportSource: 'react',
23
+ target: 'esnext',
24
+ platform: 'browser',
25
+ minify: true,
26
+ treeShaking: true,
27
+ external: [
28
+ 'react', // Provided by runtime
29
+ 'react/jsx-runtime', // Provided by runtime
30
+ ],
31
+ // Define exports for the template
32
+ footer: {
33
+ js: `
34
+ // Export the default template component
35
+ export { default } from '${absolutePath}';
36
+ `,
37
+ },
38
+ });
39
+ if (result.errors.length > 0) {
40
+ const errorMessages = result.errors.map((e) => e.text).join('\n');
41
+ throw new Error(`Bundle failed:\n${errorMessages}`);
42
+ }
43
+ const output = result.outputFiles?.[0];
44
+ if (!output) {
45
+ throw new Error('No output generated from bundle');
46
+ }
47
+ return output.contents;
48
+ }
49
+ /**
50
+ * Bundle multiple templates into a single module
51
+ * @param templates - Map of template names to file paths
52
+ * @returns The bundled JavaScript as a Uint8Array
53
+ */
54
+ export async function bundleTemplates(templates) {
55
+ // Create a virtual entry point that exports all templates
56
+ const imports = Object.entries(templates)
57
+ .map(([name, path], i) => `import _t${i} from '${resolve(path)}';`)
58
+ .join('\n');
59
+ const exports = Object.entries(templates)
60
+ .map(([name], i) => ` '${name}': _t${i},`)
61
+ .join('\n');
62
+ const entryContent = `
63
+ ${imports}
64
+
65
+ export const templates = {
66
+ ${exports}
67
+ };
68
+
69
+ export default templates;
70
+ `;
71
+ // Write virtual entry point
72
+ const { writeFile, unlink } = await import('fs/promises');
73
+ const { tmpdir } = await import('os');
74
+ const { join } = await import('path');
75
+ const tmpFile = join(tmpdir(), `loopwind-bundle-entry-${Date.now()}.ts`);
76
+ await writeFile(tmpFile, entryContent, 'utf-8');
77
+ try {
78
+ const result = await build({
79
+ entryPoints: [tmpFile],
80
+ bundle: true,
81
+ format: 'esm',
82
+ write: false,
83
+ jsx: 'automatic',
84
+ jsxImportSource: 'react',
85
+ target: 'esnext',
86
+ platform: 'browser',
87
+ minify: true,
88
+ treeShaking: true,
89
+ external: ['react', 'react/jsx-runtime'],
90
+ });
91
+ if (result.errors.length > 0) {
92
+ const errorMessages = result.errors.map((e) => e.text).join('\n');
93
+ throw new Error(`Bundle failed:\n${errorMessages}`);
94
+ }
95
+ const output = result.outputFiles?.[0];
96
+ if (!output) {
97
+ throw new Error('No output generated from bundle');
98
+ }
99
+ return output.contents;
100
+ }
101
+ finally {
102
+ await unlink(tmpFile).catch(() => { });
103
+ }
104
+ }
105
+ //# sourceMappingURL=bundler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundler.js","sourceRoot":"","sources":["../../src/lib/bundler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,OAAO,EAAE,OAAO,EAAW,MAAM,MAAM,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,YAAoB;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAE3C,sBAAsB;IACtB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;QACzB,WAAW,EAAE,CAAC,YAAY,CAAC;QAC3B,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,KAAK;QACZ,GAAG,EAAE,WAAW;QAChB,eAAe,EAAE,OAAO;QACxB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,SAAS;QACnB,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE;YACR,OAAO,EAAE,sBAAsB;YAC/B,mBAAmB,EAAE,sBAAsB;SAC5C;QACD,kCAAkC;QAClC,MAAM,EAAE;YACN,EAAE,EAAE;;2BAEiB,YAAY;CACtC;SACI;KACF,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,mBAAmB,aAAa,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiC;IAEjC,0DAA0D;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;SAClE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC;SAC1C,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,YAAY,GAAG;EACrB,OAAO;;;EAGP,OAAO;;;;CAIR,CAAC;IAEA,4BAA4B;IAC5B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,yBAAyB,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACzE,MAAM,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;YACzB,WAAW,EAAE,CAAC,OAAO,CAAC;YACtB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,WAAW;YAChB,eAAe,EAAE,OAAO;YACxB,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC;SACzC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,mBAAmB,aAAa,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
@@ -1,3 +1,20 @@
1
+ /**
2
+ * Image transform options for resizing, cropping, and format conversion
3
+ */
4
+ export interface ImageTransformOptions {
5
+ /** Target width in pixels */
6
+ width?: number;
7
+ /** Target height in pixels */
8
+ height?: number;
9
+ /** How to fit the image: cover (crop to fill), contain (fit within), fill (stretch) */
10
+ fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
11
+ /** Output format */
12
+ format?: 'png' | 'jpeg' | 'webp' | 'avif';
13
+ /** Quality for lossy formats (1-100) */
14
+ quality?: number;
15
+ /** Background color for contain/fill modes (default: transparent for png, white for jpeg) */
16
+ background?: string;
17
+ }
1
18
  /**
2
19
  * QR Code helper for templates
3
20
  * Generates a data URI for a QR code from a string
@@ -13,7 +30,23 @@ export declare function qr(text: string, options?: {
13
30
  }): Promise<string>;
14
31
  /**
15
32
  * Image helper for templates
16
- * Converts an image file or URL to a data URI
33
+ * Converts an image file or URL to a data URI with optional transformations
34
+ *
35
+ * @param filePathOrUrl - Local file path or HTTP(S) URL
36
+ * @param transform - Optional transform options for resize, crop, format conversion
37
+ * @returns Data URI string
38
+ *
39
+ * @example
40
+ * // Basic usage - no transform
41
+ * image("https://example.com/photo.jpg")
42
+ *
43
+ * @example
44
+ * // Resize and crop to cover 400x300
45
+ * image("https://example.com/photo.jpg", { width: 400, height: 300, fit: "cover" })
46
+ *
47
+ * @example
48
+ * // Convert to WebP with quality
49
+ * image("./photo.png", { format: "webp", quality: 80 })
17
50
  */
18
- export declare function image(filePathOrUrl: string): Promise<string>;
51
+ export declare function image(filePathOrUrl: string, transform?: ImageTransformOptions): Promise<string>;
19
52
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/lib/helpers.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,EAAE,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC7C,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,GACA,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED;;;GAGG;AACH,wBAAsB,KAAK,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClE"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/lib/helpers.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC1D,oBAAoB;IACpB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,EAAE,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC7C,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,GACA,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,KAAK,CACzB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,qBAAqB,GAChC,OAAO,CAAC,MAAM,CAAC,CA8CjB"}