create-outsystems-astro 0.10.0 → 0.11.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/bin/cli.js +7 -2
- package/integrations/bun.lock +25 -0
- package/integrations/deno.lock +51 -4
- package/integrations/package-lock.json +118 -90
- package/integrations/package.json +5 -2
- package/integrations/pnpm-lock.yaml +70 -7
- package/integrations/tsconfig.json +2 -1
- package/integrations/twig/client.ts +34 -0
- package/integrations/twig/index.ts +185 -0
- package/integrations/twig/server.ts +54 -0
- package/integrations/yarn.lock +71 -1
- package/package.json +1 -1
- package/template/AGENTS.md +47 -0
- package/template/astro.config.mjs +4 -0
- package/template/bun.lock +17 -65
- package/template/deno.lock +36 -30
- package/template/package-lock.json +98 -201
- package/template/package.json +3 -1
- package/template/pnpm-lock.yaml +42 -0
- package/template/src/env.d.ts +6 -0
- package/template/src/framework/twig/Demo.twig +100 -0
- package/template/src/framework/twig/Store.twig +45 -0
- package/template/src/images/twig.png +0 -0
- package/template/src/pages/multi/store.astro +10 -0
- package/template/src/pages/twig/twig-demo.astro +65 -0
- package/template/src/stores/framework.ts +1 -0
- package/template/test/e2e/twig/twig-demo.spec.ts +36 -0
- package/template/test/integration/twig/Demo.test.ts +84 -0
- package/template/vitest.config.ts +9 -0
- package/template/yarn.lock +52 -5
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"module": "ESNext",
|
|
4
4
|
"moduleResolution": "Bundler",
|
|
5
5
|
"target": "ESNext",
|
|
6
|
+
"esModuleInterop": true,
|
|
6
7
|
"declaration": true,
|
|
7
8
|
"declarationMap": true,
|
|
8
9
|
"outDir": "dist",
|
|
@@ -10,6 +11,6 @@
|
|
|
10
11
|
"strict": true,
|
|
11
12
|
"skipLibCheck": true
|
|
12
13
|
},
|
|
13
|
-
"include": ["html/**/*.ts"],
|
|
14
|
+
"include": ["html/**/*.ts", "twig/**/*.ts"],
|
|
14
15
|
"exclude": ["node_modules", "dist"]
|
|
15
16
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Twig from "twig";
|
|
2
|
+
|
|
3
|
+
const client_default =
|
|
4
|
+
(element: HTMLElement) =>
|
|
5
|
+
(
|
|
6
|
+
Component: unknown,
|
|
7
|
+
props: Record<string, unknown>,
|
|
8
|
+
{ client }: { client: string },
|
|
9
|
+
) => {
|
|
10
|
+
if (client !== "only" && !element.hasAttribute("ssr")) return;
|
|
11
|
+
|
|
12
|
+
let template: string;
|
|
13
|
+
if (typeof Component === "string") {
|
|
14
|
+
template = Component;
|
|
15
|
+
} else if (typeof Component === "function") {
|
|
16
|
+
template = (Component as (p: Record<string, unknown>) => string)({
|
|
17
|
+
...props,
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
template = "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const html = Twig.twig({ data: template }).render({ ...props });
|
|
24
|
+
|
|
25
|
+
element.innerHTML = html;
|
|
26
|
+
|
|
27
|
+
element.querySelectorAll("script").forEach((oldScript) => {
|
|
28
|
+
const newScript = document.createElement("script");
|
|
29
|
+
newScript.textContent = oldScript.textContent;
|
|
30
|
+
oldScript.parentNode?.replaceChild(newScript, oldScript);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default client_default;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
import type { AstroIntegration, AstroRenderer } from "astro";
|
|
6
|
+
|
|
7
|
+
const VIRTUAL_SERVER_ID = "virtual:islands/twig/server-with-filter";
|
|
8
|
+
const RESOLVED_VIRTUAL_SERVER_ID = `\0${VIRTUAL_SERVER_ID}`;
|
|
9
|
+
|
|
10
|
+
function getRenderer(filtered: boolean): AstroRenderer {
|
|
11
|
+
return {
|
|
12
|
+
clientEntrypoint: "islands-integrations/twig/client",
|
|
13
|
+
name: "islands/twig",
|
|
14
|
+
serverEntrypoint: filtered
|
|
15
|
+
? VIRTUAL_SERVER_ID
|
|
16
|
+
: "islands-integrations/twig/server",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const getContainerRenderer = (): AstroRenderer => getRenderer(false);
|
|
21
|
+
|
|
22
|
+
export interface Options {
|
|
23
|
+
exclude?: string[];
|
|
24
|
+
include?: string[];
|
|
25
|
+
namespaces?: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type Namespaces = Record<string, string>;
|
|
29
|
+
|
|
30
|
+
function normalizeNamespaces(
|
|
31
|
+
namespaces: Record<string, string> | undefined,
|
|
32
|
+
root: string,
|
|
33
|
+
): Namespaces {
|
|
34
|
+
const normalized: Namespaces = {};
|
|
35
|
+
for (const [name, dir] of Object.entries(namespaces ?? {})) {
|
|
36
|
+
normalized[name.replace(/^@/, "")] = path.resolve(root, dir);
|
|
37
|
+
}
|
|
38
|
+
return normalized;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const NAMESPACE_PATH = /^@([^/]+)\/(.*)$/;
|
|
42
|
+
|
|
43
|
+
function resolveIncludePath(
|
|
44
|
+
includePath: string,
|
|
45
|
+
dir: string,
|
|
46
|
+
namespaces: Namespaces,
|
|
47
|
+
): string {
|
|
48
|
+
const match = NAMESPACE_PATH.exec(includePath);
|
|
49
|
+
if (!match) return path.resolve(dir, includePath);
|
|
50
|
+
|
|
51
|
+
const [, name, rest] = match;
|
|
52
|
+
const base = namespaces[name];
|
|
53
|
+
if (!base) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Twig namespace "@${name}" is not configured. Add it to the \`namespaces\` option of the twig() integration.`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return path.resolve(base, rest);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function twigFilterPlugin(include?: string[], exclude?: string[]) {
|
|
62
|
+
return {
|
|
63
|
+
load(id: string) {
|
|
64
|
+
if (id !== RESOLVED_VIRTUAL_SERVER_ID) return;
|
|
65
|
+
return [
|
|
66
|
+
`import { createRenderer } from "islands-integrations/twig/server";`,
|
|
67
|
+
`export default createRenderer(${JSON.stringify(include)}, ${JSON.stringify(exclude)});`,
|
|
68
|
+
].join("\n");
|
|
69
|
+
},
|
|
70
|
+
name: "islands/twig/filter",
|
|
71
|
+
resolveId(id: string) {
|
|
72
|
+
if (id === VIRTUAL_SERVER_ID) return RESOLVED_VIRTUAL_SERVER_ID;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const INCLUDE_TAG = /\{%-?\s*include\s+(['"])([^'"]+)\1([^%]*?)-?%\}/g;
|
|
78
|
+
|
|
79
|
+
interface IncludeModifiers {
|
|
80
|
+
ignoreMissing: boolean;
|
|
81
|
+
only: boolean;
|
|
82
|
+
withExpr?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function applyContextScope(
|
|
86
|
+
body: string,
|
|
87
|
+
{ only, withExpr }: IncludeModifiers,
|
|
88
|
+
): string {
|
|
89
|
+
if (!withExpr && !only) return body;
|
|
90
|
+
const vars = withExpr ?? "{}";
|
|
91
|
+
const onlyFlag = only ? " only" : "";
|
|
92
|
+
return `{% with ${vars}${onlyFlag} %}${body}{% endwith %}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function inlineIncludes(
|
|
96
|
+
filepath: string,
|
|
97
|
+
ancestors: string[],
|
|
98
|
+
namespaces: Namespaces,
|
|
99
|
+
onInclude?: (target: string) => void,
|
|
100
|
+
): string {
|
|
101
|
+
const resolved = path.resolve(filepath);
|
|
102
|
+
if (ancestors.includes(resolved)) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Twig include cycle detected: ${[...ancestors, resolved].join(" -> ")}`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const source = fs.readFileSync(resolved, "utf-8");
|
|
109
|
+
const dir = path.dirname(resolved);
|
|
110
|
+
const trail = [...ancestors, resolved];
|
|
111
|
+
|
|
112
|
+
return source.replace(
|
|
113
|
+
INCLUDE_TAG,
|
|
114
|
+
(_match, _quote, includePath, modifiers) => {
|
|
115
|
+
const parsed = parseModifiers(modifiers);
|
|
116
|
+
const target = resolveIncludePath(includePath, dir, namespaces);
|
|
117
|
+
if (!fs.existsSync(target)) {
|
|
118
|
+
if (parsed.ignoreMissing) return "";
|
|
119
|
+
throw new Error(
|
|
120
|
+
`Twig include "${includePath}" not found (referenced from ${resolved}).`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
onInclude?.(target);
|
|
124
|
+
const body = inlineIncludes(target, trail, namespaces, onInclude);
|
|
125
|
+
return applyContextScope(body, parsed);
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function parseModifiers(modifiers: string): IncludeModifiers {
|
|
131
|
+
const ignoreMissing = /\bignore\s+missing\b/.test(modifiers);
|
|
132
|
+
let rest = modifiers.replace(/\bignore\s+missing\b/, " ");
|
|
133
|
+
|
|
134
|
+
const only = /\bonly\s*$/.test(rest);
|
|
135
|
+
rest = rest.replace(/\bonly\s*$/, " ");
|
|
136
|
+
|
|
137
|
+
const withMatch = /\bwith\b([\s\S]*)$/.exec(rest);
|
|
138
|
+
const withExpr = withMatch ? withMatch[1].trim() : undefined;
|
|
139
|
+
|
|
140
|
+
return { ignoreMissing, only, withExpr: withExpr || undefined };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function twigLoaderPlugin(namespaces: Namespaces) {
|
|
144
|
+
return {
|
|
145
|
+
enforce: "pre" as const,
|
|
146
|
+
load(this: { addWatchFile?: (id: string) => void }, id: string) {
|
|
147
|
+
const filepath = id.split("?")[0];
|
|
148
|
+
if (!filepath.endsWith(".twig")) return;
|
|
149
|
+
const source = inlineIncludes(filepath, [], namespaces, (target) =>
|
|
150
|
+
this.addWatchFile?.(target),
|
|
151
|
+
);
|
|
152
|
+
return {
|
|
153
|
+
code: `export default ${JSON.stringify(source)};`,
|
|
154
|
+
map: null,
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
name: "islands/twig/loader",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export default function (options: Options = {}): AstroIntegration {
|
|
162
|
+
const { exclude, include, namespaces } = options;
|
|
163
|
+
const filtered = !!(include?.length || exclude?.length);
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
hooks: {
|
|
167
|
+
"astro:config:setup": ({ addRenderer, config, updateConfig }) => {
|
|
168
|
+
addRenderer(getRenderer(filtered));
|
|
169
|
+
const resolvedNamespaces = normalizeNamespaces(
|
|
170
|
+
namespaces,
|
|
171
|
+
fileURLToPath(config.root),
|
|
172
|
+
);
|
|
173
|
+
const loader = twigLoaderPlugin(resolvedNamespaces);
|
|
174
|
+
updateConfig({
|
|
175
|
+
vite: {
|
|
176
|
+
plugins: filtered
|
|
177
|
+
? [loader, twigFilterPlugin(include, exclude)]
|
|
178
|
+
: [loader],
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
name: "islands/twig",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AstroComponentMetadata,
|
|
3
|
+
NamedSSRLoadedRendererValue,
|
|
4
|
+
} from "astro";
|
|
5
|
+
|
|
6
|
+
export function createRenderer(
|
|
7
|
+
include?: string[],
|
|
8
|
+
exclude?: string[],
|
|
9
|
+
): NamedSSRLoadedRendererValue {
|
|
10
|
+
return {
|
|
11
|
+
check: async (
|
|
12
|
+
Component: unknown,
|
|
13
|
+
_props: unknown,
|
|
14
|
+
_slots: unknown,
|
|
15
|
+
metadata?: AstroComponentMetadata,
|
|
16
|
+
) => {
|
|
17
|
+
const url = metadata?.componentUrl;
|
|
18
|
+
if (url) {
|
|
19
|
+
if (include && !matchesPatterns(url, include)) return false;
|
|
20
|
+
if (exclude && matchesPatterns(url, exclude)) return false;
|
|
21
|
+
}
|
|
22
|
+
return checkComponent(Component);
|
|
23
|
+
},
|
|
24
|
+
name: "islands/twig",
|
|
25
|
+
renderToStaticMarkup,
|
|
26
|
+
supportsAstroStaticSlot: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function checkComponent(Component: unknown): Promise<boolean> {
|
|
31
|
+
if (typeof Component === "string") return true;
|
|
32
|
+
if (typeof Component === "function") {
|
|
33
|
+
try {
|
|
34
|
+
const result = (Component as (p: Record<string, unknown>) => unknown)({});
|
|
35
|
+
return typeof result === "string";
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function matchesPatterns(url: string, patterns: string[]): boolean {
|
|
44
|
+
return patterns.some((pattern) => {
|
|
45
|
+
const prefix = pattern.replace(/\/?\*+$/, "");
|
|
46
|
+
return url.includes(prefix);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function renderToStaticMarkup(): Promise<{ html: string }> {
|
|
51
|
+
return { html: "" };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default createRenderer();
|
package/integrations/yarn.lock
CHANGED
|
@@ -104,6 +104,13 @@ __metadata:
|
|
|
104
104
|
languageName: node
|
|
105
105
|
linkType: hard
|
|
106
106
|
|
|
107
|
+
"@babel/runtime@npm:^7.8.4":
|
|
108
|
+
version: 7.29.2
|
|
109
|
+
resolution: "@babel/runtime@npm:7.29.2"
|
|
110
|
+
checksum: 10c0/30b80a0140d16467792e1bbeb06f655b0dab70407da38dfac7fedae9c859f9ae9d846ef14ad77bd3814c064295fe9b1bc551f1541ea14646ae9f22b71a8bc17a
|
|
111
|
+
languageName: node
|
|
112
|
+
linkType: hard
|
|
113
|
+
|
|
107
114
|
"@babel/types@npm:^7.29.0":
|
|
108
115
|
version: 7.29.0
|
|
109
116
|
resolution: "@babel/types@npm:7.29.0"
|
|
@@ -1121,6 +1128,22 @@ __metadata:
|
|
|
1121
1128
|
languageName: node
|
|
1122
1129
|
linkType: hard
|
|
1123
1130
|
|
|
1131
|
+
"@types/node@npm:^25.9.1":
|
|
1132
|
+
version: 25.9.1
|
|
1133
|
+
resolution: "@types/node@npm:25.9.1"
|
|
1134
|
+
dependencies:
|
|
1135
|
+
undici-types: "npm:>=7.24.0 <7.24.7"
|
|
1136
|
+
checksum: 10c0/9a04682842bebbcf21a1779dfeab9aa733d7bd7bbc0a0edb641ab3a9a3d43eac543225acf669c334f458f1956443ebc072bc3c72840c543b8b356cab5c82d456
|
|
1137
|
+
languageName: node
|
|
1138
|
+
linkType: hard
|
|
1139
|
+
|
|
1140
|
+
"@types/twig@npm:^1.12.17":
|
|
1141
|
+
version: 1.12.17
|
|
1142
|
+
resolution: "@types/twig@npm:1.12.17"
|
|
1143
|
+
checksum: 10c0/a54d62abb979ecc81707c7da9ffe641cdbb12c5e73d782c5fbed69c41123d7c2142c8c79fe7a92295bc13eea7abbafd68863e5f0eb3f54094a26b179e3a2d653
|
|
1144
|
+
languageName: node
|
|
1145
|
+
linkType: hard
|
|
1146
|
+
|
|
1124
1147
|
"@types/unist@npm:*, @types/unist@npm:^3.0.0":
|
|
1125
1148
|
version: 3.0.3
|
|
1126
1149
|
resolution: "@types/unist@npm:3.0.3"
|
|
@@ -2802,6 +2825,13 @@ __metadata:
|
|
|
2802
2825
|
languageName: node
|
|
2803
2826
|
linkType: hard
|
|
2804
2827
|
|
|
2828
|
+
"foreachasync@npm:^3.0.0":
|
|
2829
|
+
version: 3.0.0
|
|
2830
|
+
resolution: "foreachasync@npm:3.0.0"
|
|
2831
|
+
checksum: 10c0/8ad877008da351fa78939e850c6014e94b8b9c6de3d12751b2b906ef96f8c80945310d998b2a704854e126c508237dc9951f6900685ccc42c93db15b09a0c4b3
|
|
2832
|
+
languageName: node
|
|
2833
|
+
linkType: hard
|
|
2834
|
+
|
|
2805
2835
|
"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
|
|
2806
2836
|
version: 2.3.3
|
|
2807
2837
|
resolution: "fsevents@npm:2.3.3"
|
|
@@ -3570,6 +3600,8 @@ __metadata:
|
|
|
3570
3600
|
dependencies:
|
|
3571
3601
|
"@eslint/compat": "npm:^2.1.0"
|
|
3572
3602
|
"@eslint/js": "npm:^9.39.4"
|
|
3603
|
+
"@types/node": "npm:^25.9.1"
|
|
3604
|
+
"@types/twig": "npm:^1.12.17"
|
|
3573
3605
|
astro: "npm:^6.3.7"
|
|
3574
3606
|
better-npm-audit: "npm:^3.11.0"
|
|
3575
3607
|
eslint: "npm:^9.39.4"
|
|
@@ -3579,6 +3611,7 @@ __metadata:
|
|
|
3579
3611
|
eslint-plugin-perfectionist: "npm:^5.9.0"
|
|
3580
3612
|
globals: "npm:^17.6.0"
|
|
3581
3613
|
prettier: "npm:^3.8.3"
|
|
3614
|
+
twig: "npm:^3.0.0"
|
|
3582
3615
|
typescript: "npm:^5.9.3"
|
|
3583
3616
|
typescript-eslint: "npm:^8.59.4"
|
|
3584
3617
|
languageName: unknown
|
|
@@ -3669,6 +3702,13 @@ __metadata:
|
|
|
3669
3702
|
languageName: node
|
|
3670
3703
|
linkType: hard
|
|
3671
3704
|
|
|
3705
|
+
"locutus@npm:^3.0.9":
|
|
3706
|
+
version: 3.0.36
|
|
3707
|
+
resolution: "locutus@npm:3.0.36"
|
|
3708
|
+
checksum: 10c0/54a04ecddeaeadd924f2362c31d888e333bb717bd48dd9d40ac6ddccb352a924791223e09b782d03196808c1404a1f74210a388ce4475c3650dcb8d7b0a75730
|
|
3709
|
+
languageName: node
|
|
3710
|
+
linkType: hard
|
|
3711
|
+
|
|
3672
3712
|
"lodash.get@npm:^4.4.2":
|
|
3673
3713
|
version: 4.4.2
|
|
3674
3714
|
resolution: "lodash.get@npm:4.4.2"
|
|
@@ -4271,7 +4311,7 @@ __metadata:
|
|
|
4271
4311
|
languageName: node
|
|
4272
4312
|
linkType: hard
|
|
4273
4313
|
|
|
4274
|
-
"minimatch@npm:^10.2.2":
|
|
4314
|
+
"minimatch@npm:^10, minimatch@npm:^10.2.2":
|
|
4275
4315
|
version: 10.2.5
|
|
4276
4316
|
resolution: "minimatch@npm:10.2.5"
|
|
4277
4317
|
dependencies:
|
|
@@ -5713,6 +5753,20 @@ __metadata:
|
|
|
5713
5753
|
languageName: node
|
|
5714
5754
|
linkType: hard
|
|
5715
5755
|
|
|
5756
|
+
"twig@npm:^3.0.0":
|
|
5757
|
+
version: 3.0.0
|
|
5758
|
+
resolution: "twig@npm:3.0.0"
|
|
5759
|
+
dependencies:
|
|
5760
|
+
"@babel/runtime": "npm:^7.8.4"
|
|
5761
|
+
locutus: "npm:^3.0.9"
|
|
5762
|
+
minimatch: "npm:^10"
|
|
5763
|
+
walk: "npm:2.3.x"
|
|
5764
|
+
bin:
|
|
5765
|
+
twigjs: bin/twigjs
|
|
5766
|
+
checksum: 10c0/a727b665d34c9b7db9cf5fa99072472ef1dd9291d6f29a4b1de88ca95493d16c667f47d7e87f4aaea05275ea184f6550dc3c32cb42026b819d154690f48cff76
|
|
5767
|
+
languageName: node
|
|
5768
|
+
linkType: hard
|
|
5769
|
+
|
|
5716
5770
|
"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
|
|
5717
5771
|
version: 0.4.0
|
|
5718
5772
|
resolution: "type-check@npm:0.4.0"
|
|
@@ -5843,6 +5897,13 @@ __metadata:
|
|
|
5843
5897
|
languageName: node
|
|
5844
5898
|
linkType: hard
|
|
5845
5899
|
|
|
5900
|
+
"undici-types@npm:>=7.24.0 <7.24.7":
|
|
5901
|
+
version: 7.24.6
|
|
5902
|
+
resolution: "undici-types@npm:7.24.6"
|
|
5903
|
+
checksum: 10c0/d9cd8befb643ac904615c280a095ba4240531f6bb4a5e75a22a7483630ca8d3f1016d2ab6ace6ceda1f63b3a2db2fe037fafe121d6917a0187573aa548ff78ca
|
|
5904
|
+
languageName: node
|
|
5905
|
+
linkType: hard
|
|
5906
|
+
|
|
5846
5907
|
"undici@npm:^6.25.0":
|
|
5847
5908
|
version: 6.25.0
|
|
5848
5909
|
resolution: "undici@npm:6.25.0"
|
|
@@ -6151,6 +6212,15 @@ __metadata:
|
|
|
6151
6212
|
languageName: node
|
|
6152
6213
|
linkType: hard
|
|
6153
6214
|
|
|
6215
|
+
"walk@npm:2.3.x":
|
|
6216
|
+
version: 2.3.15
|
|
6217
|
+
resolution: "walk@npm:2.3.15"
|
|
6218
|
+
dependencies:
|
|
6219
|
+
foreachasync: "npm:^3.0.0"
|
|
6220
|
+
checksum: 10c0/c390221ff6fdb8e95f9b03d90fa9980edc2c01ce9efac44c0ade2036ee2823bf2bc9abfae388bdf64ab59e9262610e7cf6634ad54acac018e62621b85edad2cf
|
|
6221
|
+
languageName: node
|
|
6222
|
+
linkType: hard
|
|
6223
|
+
|
|
6154
6224
|
"web-namespaces@npm:^2.0.0":
|
|
6155
6225
|
version: 2.0.1
|
|
6156
6226
|
resolution: "web-namespaces@npm:2.0.1"
|
package/package.json
CHANGED
package/template/AGENTS.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- React - Documentation available at https://docs.astro.build/en/guides/integrations-guide/react/
|
|
12
12
|
- SolidJS - Documentation available at https://docs.astro.build/en/guides/integrations-guide/solid-js/
|
|
13
13
|
- Svelte - Documentation availabe at https://docs.astro.build/en/guides/integrations-guide/svelte/
|
|
14
|
+
- Twig - Documentation available at https://hs2323.github.io/create-outsystems-astro/guides/integrations/twig/
|
|
14
15
|
- Vue - Documentation available at https://docs.astro.build/en/guides/integrations-guide/vue/
|
|
15
16
|
- Prefer to use TypeScript when possible.
|
|
16
17
|
|
|
@@ -44,6 +45,7 @@ In OutSystems Developer Cloud, the Islands library is available at https://www.o
|
|
|
44
45
|
- React: `client:only="react"`
|
|
45
46
|
- SolidJS: `client:only="solid-js"`
|
|
46
47
|
- Svelte: `client:only="svelte"`
|
|
48
|
+
- Twig: `client:load`
|
|
47
49
|
- Vue: `client:only="vue"`
|
|
48
50
|
|
|
49
51
|
### Components
|
|
@@ -94,6 +96,10 @@ Angular does not support the use of slots. Any use of slots with Angular should
|
|
|
94
96
|
|
|
95
97
|
The HTML integration does not support the use of slots. Any use of slots with the HTML integration should be discouraged.
|
|
96
98
|
|
|
99
|
+
##### Twig
|
|
100
|
+
|
|
101
|
+
The Twig integration does not support the use of slots. Any use of slots with the Twig integration should be discouraged. Pass content in as props and render it with `{{ }}` instead.
|
|
102
|
+
|
|
97
103
|
##### Preact
|
|
98
104
|
|
|
99
105
|
- In Preact, slots are handled as props. The default slot is the `children` prop. A named slot will have the name of its slot as the parameter. For example, a slot with the following:
|
|
@@ -406,6 +412,47 @@ export default function Counter({}) {
|
|
|
406
412
|
<div>{$nanoStoreValue}</div>
|
|
407
413
|
```
|
|
408
414
|
|
|
415
|
+
#### Twig
|
|
416
|
+
|
|
417
|
+
Like the HTML integration, Twig does not use a Nano Stores binding library. Set up a compatible store on `window.Stores` inside the component's `<script>` tag and subscribe to it directly.
|
|
418
|
+
|
|
419
|
+
```html
|
|
420
|
+
<div class="nanostore-value"></div>
|
|
421
|
+
<script>
|
|
422
|
+
const nanostoreEl = container.querySelector(".nanostore-value");
|
|
423
|
+
|
|
424
|
+
if (!window.Stores) window.Stores = {};
|
|
425
|
+
if (!window.Stores["twigStore"]) {
|
|
426
|
+
let _value = "Test Value";
|
|
427
|
+
const _subs = [];
|
|
428
|
+
window.Stores["twigStore"] = {
|
|
429
|
+
get: function () {
|
|
430
|
+
return _value;
|
|
431
|
+
},
|
|
432
|
+
set: function (v) {
|
|
433
|
+
_value = v;
|
|
434
|
+
_subs.forEach(function (fn) {
|
|
435
|
+
fn(v);
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
subscribe: function (fn) {
|
|
439
|
+
fn(_value);
|
|
440
|
+
_subs.push(fn);
|
|
441
|
+
return function () {
|
|
442
|
+
_subs.splice(_subs.indexOf(fn), 1);
|
|
443
|
+
};
|
|
444
|
+
},
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const store = window.Stores["twigStore"];
|
|
449
|
+
nanostoreEl.textContent = store.get();
|
|
450
|
+
store.subscribe(function (value) {
|
|
451
|
+
nanostoreEl.textContent = value;
|
|
452
|
+
});
|
|
453
|
+
</script>
|
|
454
|
+
```
|
|
455
|
+
|
|
409
456
|
#### Vue
|
|
410
457
|
|
|
411
458
|
```vue
|
|
@@ -7,6 +7,7 @@ import svelte from "@astrojs/svelte";
|
|
|
7
7
|
import vue from "@astrojs/vue";
|
|
8
8
|
import { defineConfig } from "astro/config";
|
|
9
9
|
import html from "islands-integrations/html";
|
|
10
|
+
import twig from "islands-integrations/twig";
|
|
10
11
|
|
|
11
12
|
// https://astro.build/config
|
|
12
13
|
export default defineConfig({
|
|
@@ -39,6 +40,9 @@ export default defineConfig({
|
|
|
39
40
|
svelte({
|
|
40
41
|
include: ["src/framework/svelte/*"],
|
|
41
42
|
}),
|
|
43
|
+
twig({
|
|
44
|
+
include: ["src/framework/twig/*"],
|
|
45
|
+
}),
|
|
42
46
|
vue({
|
|
43
47
|
include: ["src/framework/vue/*"],
|
|
44
48
|
}),
|